1
0

cherry-pick.1.4.0-11-g4ea2db6.ff.patch 65 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479
  1. Subject: Cherry-pick 1.4.0-11-g4ea2db6 ff. to fix sprintf usage
  2. Origin:
  3. commit 4ea2db6028cc1079aa84ac1b92e23ba8a7ce9d8e
  4. commit 2521c45c19106722f299c66d4e0ef86ff7486b54
  5. commit eee8ad1adece7cc5dfcadaa3cf838cfaf0b01b05
  6. Author: James Cameron <quozl@laptop.org>
  7. Date: Thu Oct 16 08:22:36 2014 +1100
  8. Bug-Debian: https://bugs.debian.org/765442
  9. Last-Update: 2015-08-24
  10. --- a/bcrelay.c
  11. +++ b/bcrelay.c
  12. @@ -1,6 +1,6 @@
  13. -// A broadcast packet repeater. This packet repeater (currently designed for
  14. -// udp packets) will listen for broadcast packets.
  15. -// When it receives the packets, it will then re-broadcast the packet.
  16. +// A broadcast packet repeater. This packet repeater (currently
  17. +// designed for udp packets) will listen for broadcast packets. When
  18. +// it receives the packets, it will then re-broadcast the packet.
  19. //
  20. // Written by TheyCallMeLuc(at)yahoo.com.au
  21. // I accept no responsiblity for the function of this program if you
  22. @@ -8,58 +8,70 @@
  23. // Modified for Poptop by Richard de Vroede <r.devroede@linvision.com>
  24. // Ditto on the no responsibility.
  25. //
  26. -// Rewritten by Norbert van Bolhuis <norbert@vanbolhuis.demon.nl> bcrelay (v1.0+)
  27. -// now supports/does:
  28. -// 1) Relaying from PPP (VPN tunnel) interfaces, hereby creating a virtual
  29. -// LAN (w.r.t. UDP broadcasts) for VPN clients and ethernet PCs
  30. -// belonging/matching the subnet portion of the VPN IP addresses.
  31. -// So now broadcasting to/from all systems of the VPN has been implemented.
  32. -// Note that bcrelay v0.5 only relayed from LAN to VPN clients.
  33. -// It doesn't matter whether the systems on the VPN are on the LAN of the
  34. -// VPN server or have a VPN/PPTP connection (over the internet) to the VPN
  35. -// server. Broadcasts will always be relayed to/from all given interfaces. And
  36. -// as long as the subnet portion of the IP addresses of the systems on the VPN
  37. -// matches, the VPN server will be able to route properly. This means all
  38. -// networking applications/games that rely on a UDP broadcast from one or
  39. -// more PPP (VPN tunnel) interfaces will now see eachother and work over
  40. -// the VPN.
  41. -// Note that it depends on the networking application/game and whoever
  42. -// acts as application/game server/host who is sending (UPD) broadcasts
  43. -// and who is listening.
  44. -// 2) UDP broadcasts received on a PPP interface (VPN tunnel) sometimes
  45. -// don't carry the VPN IP address which pptpd provisioned. I've seen
  46. -// this happening on a WinXP SP1 box, especially when the application
  47. -// responsible for the UDP broadcasts isn't aware of the PPP interface.
  48. -// In this case it just uses the LAN IP src address for the IP src
  49. -// address of the inner (GRE encapsulated) IP packet. This breaks
  50. -// the "virtual LAN" and therefore bcrelay, as of this version, changes
  51. -// the src IP address to the VPN IP address (which pptpd provisioned)
  52. +// Rewritten by Norbert van Bolhuis <norbert@vanbolhuis.demon.nl>
  53. +// bcrelay (v1.0+) now supports/does:
  54. +//
  55. +// 1) Relaying from PPP (VPN tunnel) interfaces, hereby creating a
  56. +// virtual LAN (w.r.t. UDP broadcasts) for VPN clients and ethernet
  57. +// PCs belonging/matching the subnet portion of the VPN IP
  58. +// addresses. So now broadcasting to/from all systems of the VPN
  59. +// has been implemented. Note that bcrelay v0.5 only relayed from
  60. +// LAN to VPN clients. It doesn't matter whether the systems on
  61. +// the VPN are on the LAN of the VPN server or have a VPN/PPTP
  62. +// connection (over the internet) to the VPN server. Broadcasts
  63. +// will always be relayed to/from all given interfaces. And as long
  64. +// as the subnet portion of the IP addresses of the systems on the
  65. +// VPN matches, the VPN server will be able to route properly. This
  66. +// means all networking applications/games that rely on a UDP
  67. +// broadcast from one or more PPP (VPN tunnel) interfaces will now
  68. +// see eachother and work over the VPN.
  69. +//
  70. +// Note that it depends on the networking application/game and
  71. +// whoever acts as application/game server/host who is sending
  72. +// (UDP) broadcasts and who is listening.
  73. +//
  74. +// 2) UDP broadcasts received on a PPP interface (VPN tunnel)
  75. +// sometimes don't carry the VPN IP address which pptpd
  76. +// provisioned. I've seen this happening on a WinXP SP1 box,
  77. +// especially when the application responsible for the UDP
  78. +// broadcasts isn't aware of the PPP interface. In this case it
  79. +// just uses the LAN IP src address for the IP src address of the
  80. +// inner (GRE encapsulated) IP packet. This breaks the "virtual
  81. +// LAN" and therefore bcrelay, as of this version, changes the src
  82. +// IP address to the VPN IP address (which pptpd provisioned)
  83. // before relaying.
  84. -// 3) To avoid a UDP broadcast loop, bcrelay changes the IP TTL and the
  85. -// UDP checksum (to 1 and 0 respectively) of the UDP broadcasts it relays.
  86. -// No relaying will be done for UDP broadcasts with IP TTL=1 and UDP
  87. -// checksum=0. Could also (mis)use IP identification for this, but IP TTL
  88. -// and UDP chksum combination is expected to work fine.
  89. -// 4) bcrelay v0.5 forgot to update IP/UDP checksum when it changed the
  90. -// dest. IP address (e.g. from 192.168.1.255 to 255.255.255.255).
  91. -// Of course as of this version bcrelay always updates the IP/UDP
  92. -// checksum since the IP TTL and src IP address will change also.
  93. -// 5) Enhanced the (syslog) debugging capabilities. By default bcrelay will
  94. -// show what it is doing. Bcrelay will syslog the IP interfaces it tries
  95. -// to read/relay UDP broadcasts from/to. These interfaces are called
  96. -// the 'active interfaces', bcrelay will syslog the initial set of active
  97. -// interfaces and whenever the set changes. Currently there is no difference
  98. -// between an incoming interface (given with -i) and an outgoing interface
  99. -// (given with -o), so bcrelay won't show this attribute. Also, bcrelay will
  100. -// syslog a successfully relayed UDP broadcast, including the UDP port numbers,
  101. -// the incoming interface and the interface(s) to which it was successfully
  102. -// relayed. The (new) -n option allows to suppress syslog tracing.
  103. -// If -n is given, bcrelay shows/syslogs nothing, except fatal error
  104. -// messages.
  105. +//
  106. +// 3) To avoid a UDP broadcast loop, bcrelay changes the IP TTL and
  107. +// the UDP checksum (to 1 and 0 respectively) of the UDP broadcasts
  108. +// it relays. No relaying will be done for UDP broadcasts with IP
  109. +// TTL=1 and UDP checksum=0. Could also (mis)use IP identification
  110. +// for this, but IP TTL and UDP chksum combination is expected to
  111. +// work fine.
  112. +//
  113. +// 4) bcrelay v0.5 forgot to update IP/UDP checksum when it changed
  114. +// the dest. IP address (e.g. from 192.168.1.255 to
  115. +// 255.255.255.255). Of course as of this version bcrelay always
  116. +// updates the IP/UDP checksum since the IP TTL and src IP address
  117. +// will change also.
  118. +//
  119. +// 5) Enhanced the (syslog) debugging capabilities. By default bcrelay
  120. +// will show what it is doing. Bcrelay will syslog the IP
  121. +// interfaces it tries to read/relay UDP broadcasts from/to. These
  122. +// interfaces are called the 'active interfaces', bcrelay will
  123. +// syslog the initial set of active interfaces and whenever the set
  124. +// changes. Currently there is no difference between an incoming
  125. +// interface (given with -i) and an outgoing interface (given with
  126. +// -o), so bcrelay won't show this attribute. Also, bcrelay will
  127. +// syslog a successfully relayed UDP broadcast, including the UDP
  128. +// port numbers, the incoming interface and the interface(s) to
  129. +// which it was successfully relayed. The (new) -n option allows to
  130. +// suppress syslog tracing. If -n is given, bcrelay shows/syslogs
  131. +// nothing, except fatal error messages.
  132. //
  133. // This software is completely free. You can use and/or modify this
  134. -// software to your hearts content. You are free to redistribute it as
  135. -// long as it is accompanied with the source and my credit is included.
  136. +// software to your hearts content. You are free to redistribute it
  137. +// as long as it is accompanied with the source and my credit is
  138. +// included.
  139. #ifdef HAVE_CONFIG_H
  140. #include "config.h"
  141. @@ -126,14 +138,16 @@
  142. #define IP_UDPPDU_CHECKSUM_MSB_PTR(udppdu) ((unsigned char *)(udppdu) + 6 )
  143. #define IP_UDPPDU_CHECKSUM_LSB_PTR(udppdu) ((unsigned char *)(udppdu) + 7 )
  144. -#define MAXIF 255 // Maximum interfaces to use
  145. -#define MAX_SELECT_WAIT 3 // Maximum time (in secs) to wait for input on the socket/interfaces
  146. - // A time-out triggers the discovery of new interfaces.
  147. -#define MAX_NODISCOVER_IFS 12 // Maximum time (in secs) to elaps before a discovery of new
  148. - // interfaces is triggered. Only when a packet keeps coming in
  149. - // (this prevents a select time-out) a variable initialized with
  150. - // this #define becomes 0 and a rediscovery of the interfaces is
  151. - // triggered.
  152. +// Maximum interfaces to use
  153. +#define MAXIF 255
  154. +// Maximum time (in secs) to wait for input on the socket/interfaces A
  155. +// time-out triggers the discovery of new interfaces.
  156. +#define MAX_SELECT_WAIT 3
  157. +// Maximum time (in secs) to elapse before a discovery of new
  158. +// interfaces is triggered. Only when a packet keeps coming in (this
  159. +// prevents a select time-out) a variable initialized with this
  160. +// #define becomes 0 and a rediscovery of the interfaces is triggered.
  161. +#define MAX_NODISCOVER_IFS 12
  162. #define MAX_IFLOGTOSTR 16
  163. /* Local function prototypes */
  164. @@ -152,15 +166,13 @@
  165. /*
  166. - * struct that keeps track of the interfaces of the system
  167. - * selected upon usage by bcrelay (with -i and -o option).
  168. - * An array of this struct is returned by discoverActiveInterfaces.
  169. - * This array is reset (filled from scratch) each time
  170. - * discoverActiveInterfaces is called.
  171. + * struct that keeps track of the interfaces of the system selected
  172. + * upon usage by bcrelay (with -i and -o option). An array of this
  173. + * struct is returned by discoverActiveInterfaces. This array is
  174. + * reset (filled from scratch) each time discoverActiveInterfaces is
  175. + * called.
  176. */
  177. struct iflist {
  178. -//Fix 3mar2003
  179. - //char index;
  180. int index;
  181. u_int32_t bcast;
  182. char ifname[16+1];
  183. @@ -176,10 +188,10 @@
  184. /*
  185. - * struct that keeps track of the socket fd's for every interface
  186. - * that is in use (and thus present in iflist).
  187. - * Two permanent arrays of this struct are used, one for the
  188. - * previous/old list and one for the current list.
  189. + * struct that keeps track of the socket fd's for every interface that
  190. + * is in use (and thus present in iflist). Two permanent arrays of
  191. + * this struct are used, one for the previous/old list and one for the
  192. + * current list.
  193. */
  194. struct ifsnr {
  195. int sock_nr;
  196. @@ -198,7 +210,7 @@
  197. /*
  198. * This global variable determines whether NVBCR_PRINTF actually
  199. - * displays something. While developping v1.0, NVBCR_PRINTF were
  200. + * displays something. While developing v1.0, NVBCR_PRINTF were
  201. * printf and a lot of tracing/logging/debugging was done with these.
  202. * Of course, by default these 'info' messages have been turned off
  203. * now. Enable by setting variable to 1. Note that output will only
  204. @@ -209,100 +221,100 @@
  205. static int vnologging = 0;
  206. static int vdaemon = 0;
  207. -#define NVBCR_PRINTF( args ) \
  208. - if ((vdaemon == 0) && (do_org_info_printfs == 1)) printf args
  209. +#define NVBCR_PRINTF( args ) \
  210. + if ((vdaemon == 0) && (do_org_info_printfs == 1)) printf args
  211. static char empty[1] = "";
  212. -static char interfaces[32];
  213. +static char reg_interfaces[MAX_IFLOGTOSTR*2+2];
  214. static char log_interfaces[MAX_IFLOGTOSTR*MAXIF];
  215. -static char log_relayed[(MAX_IFLOGTOSTR-1)*MAXIF+81];
  216. +static char log_relayed[MAX_IFLOGTOSTR*MAXIF+81];
  217. static char *ipsec = empty;
  218. static void showusage(char *prog)
  219. {
  220. - printf("\nBCrelay v%s\n\n", VERSION);
  221. - printf("A broadcast packet repeater. This packet repeater (currently designed for udp packets) will listen\n");
  222. - printf(" for broadcast packets. When it receives the packets, it will then re-broadcast the packet.\n\n");
  223. - printf("Usage: %s [options], where options are:\n\n", prog);
  224. - printf(" [-d] [--daemon] Run as daemon.\n");
  225. - printf(" [-h] [--help] Displays this help message.\n");
  226. - printf(" [-i] [--incoming <ifin>] Defines from which interface broadcasts will be relayed.\n");
  227. - printf(" [-n] [--nolog] No logging/tracing to /var/log/messages.\n");
  228. - printf(" [-o] [--outgoing <ifout>] Defines to which interface broadcasts will be relayed.\n");
  229. - printf(" [-s] [--ipsec <arg>] Defines an ipsec tunnel to be relayed to.\n");
  230. - printf(" Since ipsec tunnels terminate on the same interface, we need to define the broadcast\n");
  231. - printf(" address of the other end-point of the tunnel. This is done as ipsec0:x.x.x.255\n");
  232. - printf(" [-v] [--version] Displays the BCrelay version number.\n");
  233. - printf("\nLog messages and debugging go to syslog as DAEMON.\n\n");
  234. - printf("\nInterfaces can be specified as regexpressions, ie. ppp[0-9]+\n\n");
  235. + printf("\nBCrelay v%s\n\n", VERSION);
  236. + printf("A broadcast packet repeater. This packet repeater (currently designed for udp packets) will listen\n");
  237. + printf(" for broadcast packets. When it receives the packets, it will then re-broadcast the packet.\n\n");
  238. + printf("Usage: %s [options], where options are:\n\n", prog);
  239. + printf(" [-d] [--daemon] Run as daemon.\n");
  240. + printf(" [-h] [--help] Displays this help message.\n");
  241. + printf(" [-i] [--incoming <ifin>] Defines from which interface broadcasts will be relayed.\n");
  242. + printf(" [-n] [--nolog] No logging/tracing to /var/log/messages.\n");
  243. + printf(" [-o] [--outgoing <ifout>] Defines to which interface broadcasts will be relayed.\n");
  244. + printf(" [-s] [--ipsec <arg>] Defines an ipsec tunnel to be relayed to.\n");
  245. + printf(" Since ipsec tunnels terminate on the same interface, we need to define the broadcast\n");
  246. + printf(" address of the other end-point of the tunnel. This is done as ipsec0:x.x.x.255\n");
  247. + printf(" [-v] [--version] Displays the BCrelay version number.\n");
  248. + printf("\nLog messages and debugging go to syslog as DAEMON.\n\n");
  249. + printf("\nInterfaces can be specified as regexpressions, ie. ppp[0-9]+\n\n");
  250. }
  251. static void showversion()
  252. {
  253. - printf("BCrelay v%s\n", VERSION);
  254. + printf("BCrelay v%s\n", VERSION);
  255. }
  256. #ifndef HAVE_DAEMON
  257. static void my_daemon(int argc, char **argv)
  258. {
  259. - pid_t pid;
  260. + pid_t pid;
  261. #ifndef BCRELAY_BIN
  262. -/* Need a smart way to locate the binary -rdv */
  263. + /* Need a smart way to locate the binary -rdv */
  264. #define BCRELAY_BIN argv[0]
  265. #endif
  266. #ifndef HAVE_FORK
  267. - /* need to use vfork - eg, uClinux */
  268. - char **new_argv;
  269. - extern char **environ;
  270. - int minusd=0;
  271. - int i;
  272. - int fdr;
  273. -
  274. - /* Strip -d option */
  275. - new_argv = malloc((argc) * sizeof(char **));
  276. - fdr = open("/dev/null", O_RDONLY);
  277. - new_argv[0] = BCRELAY_BIN;
  278. - for (i = 1; argv[i] != NULL; i++) {
  279. - if (fdr != 0) { dup2(fdr, 0); close(fdr); }
  280. - if ( (strcmp(argv[i],"-d")) == 0 ) {
  281. - minusd=1;
  282. - }
  283. - if (minusd) {
  284. - new_argv[i] = argv[i+1];
  285. - } else {
  286. - new_argv[i] = argv[i];
  287. - }
  288. - }
  289. - syslog(LOG_DEBUG, "Option parse OK, re-execing as daemon");
  290. - fflush(stderr);
  291. - if ((pid = vfork()) == 0) {
  292. - if (setsid() < 0) { /* shouldn't fail */
  293. - syslog(LOG_ERR, "Setsid failed!");
  294. - _exit(1);
  295. - }
  296. - chdir("/");
  297. - umask(0);
  298. - /* execve only returns on an error */
  299. - execve(BCRELAY_BIN, new_argv, environ);
  300. - exit(1);
  301. - } else if (pid > 0) {
  302. - syslog(LOG_DEBUG, "Success re-execing as daemon!");
  303. - exit(0);
  304. - } else {
  305. - syslog(LOG_ERR, "Error vforking");
  306. - exit(1);
  307. - }
  308. -#else
  309. - pid=fork();
  310. - if (pid<0) { syslog(LOG_ERR, "Error forking"); _exit(1); }
  311. - if (pid>0) { syslog(LOG_DEBUG, "Parent exits"); _exit(0); }
  312. - if (pid==0) { syslog(LOG_DEBUG, "Running as child"); }
  313. - /* child (daemon) continues */
  314. + /* need to use vfork - eg, uClinux */
  315. + char **new_argv;
  316. + extern char **environ;
  317. + int minusd=0;
  318. + int i;
  319. + int fdr;
  320. +
  321. + /* Strip -d option */
  322. + new_argv = malloc((argc) * sizeof(char **));
  323. + fdr = open("/dev/null", O_RDONLY);
  324. + new_argv[0] = BCRELAY_BIN;
  325. + for (i = 1; argv[i] != NULL; i++) {
  326. + if (fdr != 0) { dup2(fdr, 0); close(fdr); }
  327. + if ( (strcmp(argv[i],"-d")) == 0 ) {
  328. + minusd=1;
  329. + }
  330. + if (minusd) {
  331. + new_argv[i] = argv[i+1];
  332. + } else {
  333. + new_argv[i] = argv[i];
  334. + }
  335. + }
  336. + syslog(LOG_DEBUG, "Option parse OK, re-execing as daemon");
  337. + fflush(stderr);
  338. + if ((pid = vfork()) == 0) {
  339. if (setsid() < 0) { /* shouldn't fail */
  340. syslog(LOG_ERR, "Setsid failed!");
  341. _exit(1);
  342. }
  343. chdir("/");
  344. + umask(0);
  345. + /* execve only returns on an error */
  346. + execve(BCRELAY_BIN, new_argv, environ);
  347. + exit(1);
  348. + } else if (pid > 0) {
  349. + syslog(LOG_DEBUG, "Success re-execing as daemon!");
  350. + exit(0);
  351. + } else {
  352. + syslog(LOG_ERR, "Error vforking");
  353. + exit(1);
  354. + }
  355. +#else
  356. + pid=fork();
  357. + if (pid<0) { syslog(LOG_ERR, "Error forking"); _exit(1); }
  358. + if (pid>0) { syslog(LOG_DEBUG, "Parent exits"); _exit(0); }
  359. + if (pid==0) { syslog(LOG_DEBUG, "Running as child"); }
  360. + /* child (daemon) continues */
  361. + if (setsid() < 0) { /* shouldn't fail */
  362. + syslog(LOG_ERR, "Setsid failed!");
  363. + _exit(1);
  364. + }
  365. + chdir("/");
  366. #endif
  367. }
  368. #endif
  369. @@ -321,78 +333,81 @@
  370. exit(1);
  371. #endif
  372. - /* open a connection to the syslog daemon */
  373. - openlog("bcrelay", LOG_PID, PPTP_FACILITY);
  374. + /* open a connection to the syslog daemon */
  375. + openlog("bcrelay", LOG_PID, PPTP_FACILITY);
  376. while (1) {
  377. - int option_index = 0;
  378. + int option_index = 0;
  379. - static struct option long_options[] =
  380. - {
  381. - {"nolog", 0, 0, 0},
  382. - {"daemon", 0, 0, 0},
  383. - {"help", 0, 0, 0},
  384. - {"incoming", 1, 0, 0},
  385. - {"outgoing", 1, 0, 0},
  386. - {"ipsec", 1, 0, 0},
  387. - {"version", 0, 0, 0},
  388. - {0, 0, 0, 0}
  389. - };
  390. -
  391. - c = getopt_long(argc, argv, "ndhi:o:s:v", long_options, &option_index);
  392. - if (c == -1)
  393. - break;
  394. - /* convert long options to short form */
  395. - if (c == 0)
  396. - c = "ndhiosv"[option_index];
  397. - switch (c) {
  398. - case 'n':
  399. - vnologging = 1;
  400. - break;
  401. - case 'd':
  402. - vdaemon = 1;
  403. - break;
  404. - case 'h':
  405. - showusage(argv[0]);
  406. - return 0;
  407. - case 'i':
  408. - ifin = strdup(optarg);
  409. - break;
  410. - case 'o':
  411. - ifout = strdup(optarg);
  412. - break;
  413. - case 's':
  414. - ipsec = strdup(optarg);
  415. - // Validate the ipsec parameters
  416. - regcomp(&preg, "ipsec[0-9]+:[0-9]+.[0-9]+.[0-9]+.255", REG_EXTENDED);
  417. - if (regexec(&preg, ipsec, 0, NULL, 0)) {
  418. - syslog(LOG_INFO,"Bad syntax: %s", ipsec);
  419. - fprintf(stderr, "\nBad syntax: %s\n", ipsec);
  420. - showusage(argv[0]);
  421. - return 0;
  422. - } else {
  423. - regfree(&preg);
  424. - break;
  425. - }
  426. - case 'v':
  427. - showversion();
  428. - return 0;
  429. - default:
  430. - showusage(argv[0]);
  431. - return 1;
  432. - }
  433. + static struct option long_options[] =
  434. + {
  435. + {"nolog", 0, 0, 0},
  436. + {"daemon", 0, 0, 0},
  437. + {"help", 0, 0, 0},
  438. + {"incoming", 1, 0, 0},
  439. + {"outgoing", 1, 0, 0},
  440. + {"ipsec", 1, 0, 0},
  441. + {"version", 0, 0, 0},
  442. + {0, 0, 0, 0}
  443. + };
  444. +
  445. + c = getopt_long(argc, argv, "ndhi:o:s:v", long_options, &option_index);
  446. + if (c == -1)
  447. + break;
  448. + /* convert long options to short form */
  449. + if (c == 0)
  450. + c = "ndhiosv"[option_index];
  451. + switch (c) {
  452. + case 'n':
  453. + vnologging = 1;
  454. + break;
  455. + case 'd':
  456. + vdaemon = 1;
  457. + break;
  458. + case 'h':
  459. + showusage(argv[0]);
  460. + return 0;
  461. + case 'i':
  462. + ifin = strdup(optarg);
  463. + break;
  464. + case 'o':
  465. + ifout = strdup(optarg);
  466. + break;
  467. + case 's':
  468. + ipsec = strdup(optarg);
  469. + // Validate the ipsec parameters
  470. + regcomp(&preg, "ipsec[0-9]+:[0-9]+.[0-9]+.[0-9]+.255", REG_EXTENDED);
  471. + if (regexec(&preg, ipsec, 0, NULL, 0)) {
  472. + syslog(LOG_INFO,"Bad syntax: %s", ipsec);
  473. + fprintf(stderr, "\nBad syntax: %s\n", ipsec);
  474. + showusage(argv[0]);
  475. + return 0;
  476. + } else {
  477. + regfree(&preg);
  478. + break;
  479. + }
  480. + case 'v':
  481. + showversion();
  482. + return 0;
  483. + default:
  484. + showusage(argv[0]);
  485. + return 1;
  486. + }
  487. }
  488. if (ifin == empty) {
  489. - syslog(LOG_INFO,"Incoming interface required!");
  490. - showusage(argv[0]);
  491. - _exit(1);
  492. + syslog(LOG_INFO,"Incoming interface required!");
  493. + showusage(argv[0]);
  494. + _exit(1);
  495. }
  496. if (ifout == empty && ipsec == empty) {
  497. - syslog(LOG_INFO,"Listen-mode or outgoing or IPsec interface required!");
  498. - showusage(argv[0]);
  499. - _exit(1);
  500. - } else {
  501. - sprintf(interfaces,"%s|%s", ifin, ifout);
  502. + syslog(LOG_INFO,"Listen-mode or outgoing or IPsec interface required!");
  503. + showusage(argv[0]);
  504. + _exit(1);
  505. + }
  506. + if (snprintf(reg_interfaces, sizeof(reg_interfaces),
  507. + "%s|%s", ifin, ifout) >= sizeof(reg_interfaces)) {
  508. + syslog(LOG_ERR, "interface names exceed size");
  509. + _exit(1);
  510. }
  511. // If specified, become Daemon.
  512. @@ -426,7 +441,6 @@
  513. {
  514. socklen_t salen = sizeof(struct sockaddr_ll);
  515. int i, s, rcg, j, no_discifs_cntr, ifs_change;
  516. - int logstr_cntr;
  517. struct iflist *iflist = NULL; // Initialised after the 1st packet
  518. struct sockaddr_ll sa;
  519. struct packet *ipp_p;
  520. @@ -436,7 +450,10 @@
  521. static struct ifsnr old_ifsnr[MAXIF+1]; // Old iflist to socket fd's mapping list
  522. static struct ifsnr cur_ifsnr[MAXIF+1]; // Current iflist to socket fd's mapping list
  523. unsigned char buf[1518];
  524. - char *logstr = empty;
  525. +
  526. + char *lptr; /* log buffer pointer for next chunk append */
  527. + int lsize = 0; /* count of remaining unused bytes in log buffer */
  528. + int chunk; /* bytes to be added to log buffer by chunk */
  529. no_discifs_cntr = MAX_NODISCOVER_IFS;
  530. ifs_change = 0;
  531. @@ -449,7 +466,8 @@
  532. /*
  533. - * Discover interfaces (initial set) and create a dedicated socket bound to the interface
  534. + * Discover interfaces (initial set) and create a dedicated socket
  535. + * bound to the interface
  536. */
  537. memset(old_ifsnr, -1, sizeof(old_ifsnr));
  538. memset(cur_ifsnr, -1, sizeof(cur_ifsnr));
  539. @@ -464,313 +482,367 @@
  540. }
  541. NVBCR_PRINTF(("Displaying INITIAL active interfaces..\n"));
  542. if (vnologging == 0) {
  543. - logstr = log_interfaces;
  544. - logstr_cntr = sprintf(logstr, "Initial active interfaces: ");
  545. - logstr += logstr_cntr;
  546. + lptr = log_interfaces;
  547. + lsize = sizeof(log_interfaces);
  548. + chunk = snprintf(lptr, lsize, "%s ", "Initial active interfaces:");
  549. + if (chunk < lsize) {
  550. + lptr += chunk;
  551. + lsize -= chunk;
  552. + }
  553. }
  554. for (i = 0; iflist[i].index; i++)
  555. - {
  556. - NVBCR_PRINTF(("\t\tactive interface number: %d, if=(%s), sock_nr=%d\n", i, iflistToString(&(iflist[i])), cur_ifsnr[i].sock_nr));
  557. - if (vnologging == 0) {
  558. - logstr_cntr = sprintf(logstr, "%s ", iflistLogIToString(&(iflist[i]), i, &(cur_ifsnr[i])));
  559. - logstr += logstr_cntr;
  560. + {
  561. + NVBCR_PRINTF(("\t\tactive interface number: %d, if=(%s), sock_nr=%d\n", i, iflistToString(&(iflist[i])), cur_ifsnr[i].sock_nr));
  562. + if (vnologging == 0) {
  563. + chunk = snprintf(lptr, lsize, "%s ",
  564. + iflistLogIToString(&(iflist[i]), i, &(cur_ifsnr[i])));
  565. + if (chunk < lsize) {
  566. + lptr += chunk;
  567. + lsize -= chunk;
  568. + }
  569. + }
  570. }
  571. - }
  572. if (vnologging == 0) syslog(LOG_INFO, "%s", log_interfaces);
  573. // Main loop
  574. while (1)
  575. - {
  576. -
  577. - /*
  578. - * Check all (interface) sockets for incoming packets
  579. - */
  580. - FD_ZERO(&sock_set);
  581. - for (i=0; iflist[i].index; ++i)
  582. - {
  583. - if (cur_ifsnr[i].sock_nr >= 0) {
  584. - FD_SET(cur_ifsnr[i].sock_nr, &sock_set);
  585. - }
  586. - }
  587. -
  588. - /*
  589. - * Don't wait more than MAX_SELECT_WAIT seconds
  590. - */
  591. - time_2_wait.tv_sec = MAX_SELECT_WAIT;
  592. - time_2_wait.tv_usec = 0L;
  593. -
  594. - /* select on sockets */
  595. - rcg = select(MAXIF, &sock_set, (fd_set *) NULL,(fd_set *) NULL, &time_2_wait);
  596. -
  597. - if (rcg < 0)
  598. {
  599. - syslog(LOG_ERR, "Error, select error! (rv=%d, errno=%d)", rcg, errno);
  600. - exit(1);
  601. - }
  602. - if (rcg == 0)
  603. - {
  604. - /* TimeOut, rediscover interfaces */
  605. - NVBCR_PRINTF(("Select timeout, rediscover interfaces\n"));
  606. - copy_ifsnr(cur_ifsnr, old_ifsnr);
  607. - memset(cur_ifsnr, -1, sizeof(cur_ifsnr));
  608. - iflist = discoverActiveInterfaces(s);
  609. /*
  610. - * Build new cur_ifsnr list.
  611. - * Make iflist[i] correspond with cur_ifsnr[i], so iflist[i].index == cur_ifsnr[i].ifindex
  612. - * The old list (old_ifsnr) is used to compare.
  613. + * Check all (interface) sockets for incoming packets
  614. */
  615. - for (i=0; iflist[i].index; ++i) {
  616. - /* check to see if it is a NEW interface */
  617. - int fsnr = find_sock_nr(old_ifsnr, iflist[i].index);
  618. - if (fsnr == -1) {
  619. - /* found new interface, open dedicated socket and bind it to the interface */
  620. - if ((cur_ifsnr[i].sock_nr = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL))) < 0) {
  621. - syslog(LOG_ERR, "mainloop: Error, socket error! (rv=%d, errno=%d)", cur_ifsnr[i].sock_nr, errno);
  622. - exit(1);
  623. - }
  624. - bind_to_iface(cur_ifsnr[i].sock_nr, iflist[i].index);
  625. - ifs_change = 1;
  626. - }
  627. - else
  628. + FD_ZERO(&sock_set);
  629. + for (i=0; iflist[i].index; ++i)
  630. {
  631. - /*
  632. - * not a new interface, socket already openen, interface already
  633. - * bound. Update cur_ifsnr.
  634. - */
  635. - cur_ifsnr[i].sock_nr = fsnr;
  636. - }
  637. - cur_ifsnr[i].ifindex = iflist[i].index;
  638. - }
  639. - /* Close disappeared interfaces */
  640. - for (i=0; i<MAXIF; ++i)
  641. - {
  642. - if ((old_ifsnr[i].sock_nr != -1) && (old_ifsnr[i].ifindex != -1) &&
  643. - (find_sock_nr(cur_ifsnr, old_ifsnr[i].ifindex) == -1)) {
  644. - NVBCR_PRINTF(("Closing an interface (it disappeared), namely: (s_nr=%d, ifidx=%d)\n", old_ifsnr[i].sock_nr, old_ifsnr[i].ifindex));
  645. - close(old_ifsnr[i].sock_nr);
  646. - old_ifsnr[i].sock_nr = -1;
  647. - old_ifsnr[i].ifindex = -1;
  648. - ifs_change = 1;
  649. - }
  650. - }
  651. - if (ifs_change == 1)
  652. - {
  653. - NVBCR_PRINTF(("Active interface set changed --> displaying current active interfaces..\n"));
  654. - if (vnologging == 0) {
  655. - logstr = log_interfaces;
  656. - logstr_cntr = sprintf(logstr, "Active interface set changed to: ");
  657. - logstr += logstr_cntr;
  658. - }
  659. - for (i = 0; iflist[i].index; i++)
  660. - {
  661. - NVBCR_PRINTF(("\t\tactive interface number: %d, if=(%s), sock_nr=%d\n", i, iflistToString(&(iflist[i])), cur_ifsnr[i].sock_nr));
  662. - if (vnologging == 0) {
  663. - logstr_cntr = sprintf(logstr, "%s ", iflistLogIToString(&(iflist[i]), i, &(cur_ifsnr[i])));
  664. - logstr += logstr_cntr;
  665. + if (cur_ifsnr[i].sock_nr >= 0) {
  666. + FD_SET(cur_ifsnr[i].sock_nr, &sock_set);
  667. }
  668. }
  669. - if (vnologging == 0) syslog(LOG_INFO, "%s", log_interfaces);
  670. - ifs_change = 0;
  671. - }
  672. - continue;
  673. - }
  674. - if (rcg > 0)
  675. - {
  676. - /* rcg interfaces have pending input */
  677. - for (i=0; ((iflist[i].index != 0) && (rcg > 0)); ++i)
  678. - {
  679. - if ((cur_ifsnr[i].sock_nr != -1) && (FD_ISSET(cur_ifsnr[i].sock_nr,&sock_set)))
  680. - {
  681. - /* Valid socket number and pending input, let's read */
  682. - int rlen = read(cur_ifsnr[i].sock_nr, buf, sizeof(buf));
  683. - ipp_p = (struct packet *)&(buf[0]);
  684. - NVBCR_PRINTF(("IP_Packet=(tot_len=%d, id=%02x%02x, ttl=%d, prot=%s, src_ip=%d.%d.%d.%d, dst_ip=%d.%d.%d.%d) (on if: %d/%d) ", ntohs(ipp_p->ip.tot_len), (ntohs(ipp_p->ip.id))>>8, (ntohs(ipp_p->ip.id))&0x00ff, ipp_p->ip.ttl, IpProtToString(ipp_p->ip.protocol), (ntohl(ipp_p->ip.saddr))>>24, ((ntohl(ipp_p->ip.saddr))&0x00ff0000)>>16, ((ntohl(ipp_p->ip.saddr))&0x0000ff00)>>8, (ntohl(ipp_p->ip.saddr))&0x000000ff, (ntohl(ipp_p->ip.daddr))>>24, ((ntohl(ipp_p->ip.daddr))&0x00ff0000)>>16, ((ntohl(ipp_p->ip.daddr))&0x0000ff00)>>8, (ntohl(ipp_p->ip.daddr))&0x000000ff, i, iflist[i].index));
  685. - rcg -= 1;
  686. -
  687. - if ( (ipp_p->ip.protocol == IPPROTO_UDP) &&
  688. - (((ntohl(ipp_p->ip.daddr)) & 0x000000ff) == 0x000000ff) &&
  689. - (ipp_p->ip.ttl != 1) &&
  690. - (!((*IP_UDPPDU_CHECKSUM_MSB_PTR((unsigned char *)ipp_p+(4*ipp_p->ip.ihl)) == 0) &&
  691. - (*IP_UDPPDU_CHECKSUM_LSB_PTR((unsigned char *)ipp_p+(4*ipp_p->ip.ihl)) == 0))) )
  692. - {
  693. - int nrsent;
  694. - int ifindex_to_exclude = iflist[i].index;
  695. + /*
  696. + * Don't wait more than MAX_SELECT_WAIT seconds
  697. + */
  698. + time_2_wait.tv_sec = MAX_SELECT_WAIT;
  699. + time_2_wait.tv_usec = 0L;
  700. - NVBCR_PRINTF(("is an UDP BROADCAST (dstPort=%d, srcPort=%d) (with TTL!=1 and UDP_CHKSUM!=0)\n\n",
  701. - ntohs(ipp_p->udp.dest), ntohs(ipp_p->udp.source)));
  702. - if (vnologging == 0) {
  703. - logstr = log_relayed;
  704. - logstr_cntr = sprintf(logstr, "UDP_BroadCast(sp=%d,dp=%d) from: %s relayed to: ", ntohs(ipp_p->udp.source),
  705. - ntohs(ipp_p->udp.dest), iflistLogRToString(&(iflist[i]), i, &(cur_ifsnr[i])));
  706. - logstr += logstr_cntr;
  707. - }
  708. + /* select on sockets */
  709. + rcg = select(MAXIF, &sock_set, (fd_set *) NULL,(fd_set *) NULL, &time_2_wait);
  710. - /* going to relay a broadcast packet on all the other interfaces */
  711. - for (j=0; iflist[j].index; ++j)
  712. - {
  713. - int prepare_ipp = 0; // Changing the incoming UDP broadcast needs to be done once
  714. + if (rcg < 0)
  715. + {
  716. + syslog(LOG_ERR, "Error, select error! (rv=%d, errno=%d)", rcg, errno);
  717. + exit(1);
  718. + }
  719. - if (iflist[j].index != ifindex_to_exclude)
  720. + if (rcg == 0)
  721. + {
  722. + /* TimeOut, rediscover interfaces */
  723. + NVBCR_PRINTF(("Select timeout, rediscover interfaces\n"));
  724. + copy_ifsnr(cur_ifsnr, old_ifsnr);
  725. + memset(cur_ifsnr, -1, sizeof(cur_ifsnr));
  726. + iflist = discoverActiveInterfaces(s);
  727. + /*
  728. + * Build new cur_ifsnr list. Make iflist[i] correspond with
  729. + * cur_ifsnr[i], so iflist[i].index == cur_ifsnr[i].ifindex
  730. + * The old list (old_ifsnr) is used to compare.
  731. + */
  732. + for (i=0; iflist[i].index; ++i) {
  733. + /* check to see if it is a NEW interface */
  734. + int fsnr = find_sock_nr(old_ifsnr, iflist[i].index);
  735. + if (fsnr == -1) {
  736. + /* found new interface, open dedicated socket and bind
  737. + it to the interface */
  738. + if ((cur_ifsnr[i].sock_nr = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL))) < 0) {
  739. + syslog(LOG_ERR, "mainloop: Error, socket error! (rv=%d, errno=%d)", cur_ifsnr[i].sock_nr, errno);
  740. + exit(1);
  741. + }
  742. + bind_to_iface(cur_ifsnr[i].sock_nr, iflist[i].index);
  743. + ifs_change = 1;
  744. + }
  745. + else
  746. {
  747. - NVBCR_PRINTF(("Going to sent UDP Broadcast on interface: %s, sock_nr=%d\n", iflistToString(&(iflist[j])), cur_ifsnr[j].sock_nr));
  748. -
  749. - memset(&sa, 0, salen);
  750. -
  751. - sa.sll_family = AF_PACKET;
  752. - sa.sll_ifindex = iflist[j].index; /* Must be the SIOCGIFINDEX number */
  753. - // Set the outgoing hardware address to 1's. True Broadcast
  754. - sa.sll_addr[0] = sa.sll_addr[1] = sa.sll_addr[2] = sa.sll_addr[3] = 0xff;
  755. - sa.sll_addr[4] = sa.sll_addr[5] = sa.sll_addr[6] = sa.sll_addr[7] = 0xff;
  756. - sa.sll_halen = 6;
  757. -
  758. /*
  759. - * htons(ETH_P_IP) is necessary otherwise sendto will
  760. - * succeed but no packet is actually sent on the wire (this
  761. - * was the case for PPP interfaces, for ETH interfaces an unknown
  762. - * LAN frame is sent if htons(ETH_P_IP) is not set as protocol).
  763. + * not a new interface, socket already openen,
  764. + * interface already bound. Update cur_ifsnr.
  765. */
  766. - sa.sll_protocol = htons(ETH_P_IP); /* ETH_P_PPP_MP */
  767. + cur_ifsnr[i].sock_nr = fsnr;
  768. + }
  769. + cur_ifsnr[i].ifindex = iflist[i].index;
  770. + }
  771. + /* Close disappeared interfaces */
  772. + for (i=0; i<MAXIF; ++i)
  773. + {
  774. + if ((old_ifsnr[i].sock_nr != -1) && (old_ifsnr[i].ifindex != -1) &&
  775. + (find_sock_nr(cur_ifsnr, old_ifsnr[i].ifindex) == -1)) {
  776. + NVBCR_PRINTF(("Closing an interface (it disappeared), namely: (s_nr=%d, ifidx=%d)\n", old_ifsnr[i].sock_nr, old_ifsnr[i].ifindex));
  777. + close(old_ifsnr[i].sock_nr);
  778. + old_ifsnr[i].sock_nr = -1;
  779. + old_ifsnr[i].ifindex = -1;
  780. + ifs_change = 1;
  781. + }
  782. + }
  783. + if (ifs_change == 1)
  784. + {
  785. + NVBCR_PRINTF(("Active interface set changed --> displaying current active interfaces..\n"));
  786. + if (vnologging == 0) {
  787. + lptr = log_interfaces;
  788. + lsize = sizeof(log_interfaces);
  789. + chunk = snprintf(lptr, lsize, "%s ",
  790. + "Active interface set changed to:");
  791. + if (chunk < lsize) {
  792. + lptr += chunk;
  793. + lsize -= chunk;
  794. + }
  795. + }
  796. + for (i = 0; iflist[i].index; i++)
  797. + {
  798. + NVBCR_PRINTF(("\t\tactive interface number: %d, if=(%s), sock_nr=%d\n", i, iflistToString(&(iflist[i])), cur_ifsnr[i].sock_nr));
  799. + if (vnologging == 0) {
  800. + chunk = snprintf(lptr, lsize, "%s ",
  801. + iflistLogIToString(&(iflist[i]), i, &(cur_ifsnr[i])));
  802. + if (chunk < lsize) {
  803. + lptr += chunk;
  804. + lsize -= chunk;
  805. + }
  806. + }
  807. + }
  808. + if (vnologging == 0) syslog(LOG_INFO, "%s", log_interfaces);
  809. + ifs_change = 0;
  810. + }
  811. + continue;
  812. + }
  813. +
  814. + if (rcg > 0)
  815. + {
  816. + /* rcg interfaces have pending input */
  817. + for (i=0; ((iflist[i].index != 0) && (rcg > 0)); ++i)
  818. + {
  819. + if ((cur_ifsnr[i].sock_nr != -1) && (FD_ISSET(cur_ifsnr[i].sock_nr,&sock_set)))
  820. + {
  821. + /* Valid socket number and pending input, let's read */
  822. + int rlen = read(cur_ifsnr[i].sock_nr, buf, sizeof(buf));
  823. + ipp_p = (struct packet *)&(buf[0]);
  824. + NVBCR_PRINTF(("IP_Packet=(tot_len=%d, id=%02x%02x, ttl=%d, prot=%s, src_ip=%d.%d.%d.%d, dst_ip=%d.%d.%d.%d) (on if: %d/%d) ", ntohs(ipp_p->ip.tot_len), (ntohs(ipp_p->ip.id))>>8, (ntohs(ipp_p->ip.id))&0x00ff, ipp_p->ip.ttl, IpProtToString(ipp_p->ip.protocol), (ntohl(ipp_p->ip.saddr))>>24, ((ntohl(ipp_p->ip.saddr))&0x00ff0000)>>16, ((ntohl(ipp_p->ip.saddr))&0x0000ff00)>>8, (ntohl(ipp_p->ip.saddr))&0x000000ff, (ntohl(ipp_p->ip.daddr))>>24, ((ntohl(ipp_p->ip.daddr))&0x00ff0000)>>16, ((ntohl(ipp_p->ip.daddr))&0x0000ff00)>>8, (ntohl(ipp_p->ip.daddr))&0x000000ff, i, iflist[i].index));
  825. + rcg -= 1;
  826. +
  827. + if ( (ipp_p->ip.protocol == IPPROTO_UDP) &&
  828. + (((ntohl(ipp_p->ip.daddr)) & 0x000000ff) == 0x000000ff) &&
  829. + (ipp_p->ip.ttl != 1) &&
  830. + (!((*IP_UDPPDU_CHECKSUM_MSB_PTR((unsigned char *)ipp_p+(4*ipp_p->ip.ihl)) == 0) &&
  831. + (*IP_UDPPDU_CHECKSUM_LSB_PTR((unsigned char *)ipp_p+(4*ipp_p->ip.ihl)) == 0))) )
  832. + {
  833. + int nrsent;
  834. + int ifindex_to_exclude = iflist[i].index;
  835. +
  836. + NVBCR_PRINTF(("is an UDP BROADCAST (dstPort=%d, srcPort=%d) (with TTL!=1 and UDP_CHKSUM!=0)\n\n",
  837. + ntohs(ipp_p->udp.dest), ntohs(ipp_p->udp.source)));
  838. + if (vnologging == 0) {
  839. + lptr = log_relayed;
  840. + lsize = sizeof(log_relayed);
  841. + chunk = snprintf(lptr, lsize,
  842. + "UDP_BroadCast(sp=%d,dp=%d) from: %s relayed to: ",
  843. + ntohs(ipp_p->udp.source),
  844. + ntohs(ipp_p->udp.dest),
  845. + iflistLogRToString(&(iflist[i]), i, &(cur_ifsnr[i])));
  846. + if (chunk < lsize) {
  847. + lptr += chunk;
  848. + lsize -= chunk;
  849. + }
  850. + }
  851. - if (prepare_ipp == 0) {
  852. - // change TimeToLive to 1, This is to avoid loops, bcrelay will *NOT* relay
  853. - // anything with TTL==1.
  854. - ipp_p->ip.ttl = 1;
  855. + /* going to relay a broadcast packet on all the
  856. + other interfaces */
  857. + for (j=0; iflist[j].index; ++j)
  858. + {
  859. + int prepare_ipp = 0; // Changing the incoming UDP broadcast needs to be done once
  860. +
  861. + if (iflist[j].index != ifindex_to_exclude)
  862. + {
  863. + NVBCR_PRINTF(("Going to sent UDP Broadcast on interface: %s, sock_nr=%d\n", iflistToString(&(iflist[j])), cur_ifsnr[j].sock_nr));
  864. +
  865. + memset(&sa, 0, salen);
  866. +
  867. + sa.sll_family = AF_PACKET;
  868. + sa.sll_ifindex = iflist[j].index; /* Must be the SIOCGIFINDEX number */
  869. + // Set the outgoing hardware address to 1's. True Broadcast
  870. + sa.sll_addr[0] = sa.sll_addr[1] = sa.sll_addr[2] = sa.sll_addr[3] = 0xff;
  871. + sa.sll_addr[4] = sa.sll_addr[5] = sa.sll_addr[6] = sa.sll_addr[7] = 0xff;
  872. + sa.sll_halen = 6;
  873. +
  874. + /*
  875. + * htons(ETH_P_IP) is necessary
  876. + * otherwise sendto will succeed but no
  877. + * packet is actually sent on the wire
  878. + * (this was the case for PPP
  879. + * interfaces, for ETH interfaces an
  880. + * unknown LAN frame is sent if
  881. + * htons(ETH_P_IP) is not set as
  882. + * protocol).
  883. + */
  884. + sa.sll_protocol = htons(ETH_P_IP); /* ETH_P_PPP_MP */
  885. +
  886. + if (prepare_ipp == 0) {
  887. + // change TimeToLive to 1, This is to
  888. + // avoid loops, bcrelay will *NOT*
  889. + // relay anything with TTL==1.
  890. + ipp_p->ip.ttl = 1;
  891. - // The CRC gets broken here when sending over ipsec tunnels but that
  892. - // should not matter as we reassemble the packet at the other end.
  893. - ipp_p->ip.daddr = iflist[j].bcast;
  894. + // The CRC gets broken here when
  895. + // sending over ipsec tunnels but that
  896. + // should not matter as we reassemble
  897. + // the packet at the other end.
  898. + ipp_p->ip.daddr = iflist[j].bcast;
  899. - // check IP srcAddr (on some winXP boxes it is found to be
  900. - // different from the configured ppp address).
  901. - // Only do this for PPP interfaces.
  902. - if ((iflist[i].flags1 & IFLIST_FLAGS1_IF_IS_PPP) &&
  903. - (ntohl(ipp_p->ip.saddr) != iflist[i].ifdstaddr))
  904. - {
  905. - ipp_p->ip.saddr = htonl(iflist[i].ifdstaddr);
  906. - iflist[i].flags1 |= IFLIST_FLAGS1_CHANGED_INNER_SADDR;
  907. - }
  908. + // check IP srcAddr (on some winXP
  909. + // boxes it is found to be different
  910. + // from the configured ppp address).
  911. + // Only do this for PPP interfaces.
  912. + if ((iflist[i].flags1 & IFLIST_FLAGS1_IF_IS_PPP) &&
  913. + (ntohl(ipp_p->ip.saddr) != iflist[i].ifdstaddr))
  914. + {
  915. + ipp_p->ip.saddr = htonl(iflist[i].ifdstaddr);
  916. + iflist[i].flags1 |= IFLIST_FLAGS1_CHANGED_INNER_SADDR;
  917. + }
  918. - // Update IP checkSum (TTL and src/dest IP Address might have changed)
  919. - ip_update_checksum((unsigned char *)ipp_p);
  920. - /* Disable upper layer checksum */
  921. - udppdu = (unsigned char *)ipp_p + (4 * ipp_p->ip.ihl);
  922. - *IP_UDPPDU_CHECKSUM_MSB_PTR(udppdu) = (unsigned char)0;
  923. - *IP_UDPPDU_CHECKSUM_LSB_PTR(udppdu) = (unsigned char)0;
  924. -
  925. - prepare_ipp = 1;
  926. + // Update IP checkSum (TTL and
  927. + // src/dest IP Address might have
  928. + // changed)
  929. + ip_update_checksum((unsigned char *)ipp_p);
  930. + /* Disable upper layer checksum */
  931. + udppdu = (unsigned char *)ipp_p + (4 * ipp_p->ip.ihl);
  932. + *IP_UDPPDU_CHECKSUM_MSB_PTR(udppdu) = (unsigned char)0;
  933. + *IP_UDPPDU_CHECKSUM_LSB_PTR(udppdu) = (unsigned char)0;
  934. +
  935. + prepare_ipp = 1;
  936. + }
  937. +
  938. + /*
  939. + * The beauty of sending IP packets on a
  940. + * PACKET socket of type SOCK_DGRAM is
  941. + * that there is no need to concern
  942. + * about the physical/link layer header
  943. + * because it is filled in automatically
  944. + * (based on the contents of sa).
  945. + */
  946. + if ((nrsent = sendto(cur_ifsnr[j].sock_nr, ipp_p, rlen, MSG_DONTWAIT|MSG_TRYHARD, (struct sockaddr *)&sa, salen)) < 0)
  947. + {
  948. + if (errno == ENETDOWN) {
  949. + syslog(LOG_NOTICE, "ignored ENETDOWN from sendto(), a network interface was going down?");
  950. + } else if (errno == ENXIO) {
  951. + syslog(LOG_NOTICE, "ignored ENXIO from sendto(), a network interface went down?");
  952. + } else if (errno == ENOBUFS) {
  953. + syslog(LOG_NOTICE, "ignored ENOBUFS from sendto(), temporary shortage of buffer memory");
  954. + } else {
  955. + syslog(LOG_ERR, "mainloop: Error, sendto failed! (rv=%d, errno=%d)", nrsent, errno);
  956. + exit(1);
  957. + }
  958. + }
  959. + NVBCR_PRINTF(("Successfully relayed %d bytes \n", nrsent));
  960. + if (vnologging == 0) {
  961. + chunk = snprintf(lptr, lsize, "%s ",
  962. + iflistLogRToString(&(iflist[j]), j, &(cur_ifsnr[j])));
  963. + if (chunk < lsize) {
  964. + lptr += chunk;
  965. + lsize -= chunk;
  966. + }
  967. + }
  968. + }
  969. + }
  970. + if (vnologging == 0) syslog(LOG_INFO, "%s", log_relayed);
  971. + } else {
  972. + NVBCR_PRINTF(("is NOT an UDP BROADCAST (with TTL!=1 and UDP_CHKSUM!=0)\n\n"));
  973. + }
  974. }
  975. + }
  976. + /*
  977. + * Don't forget to discover new interfaces if we keep
  978. + * getting incoming packets (on an already discovered
  979. + * interface).
  980. + */
  981. + if (no_discifs_cntr == 0)
  982. + {
  983. + no_discifs_cntr = MAX_NODISCOVER_IFS;
  984. - /*
  985. - * The beauty of sending IP packets on a PACKET socket of type SOCK_DGRAM is that
  986. - * there is no need to concern about the physical/link layer header because it is
  987. - * filled in automatically (based on the contents of sa).
  988. - */
  989. - if ((nrsent = sendto(cur_ifsnr[j].sock_nr, ipp_p, rlen, MSG_DONTWAIT|MSG_TRYHARD, (struct sockaddr *)&sa, salen)) < 0)
  990. - {
  991. - if (errno == ENETDOWN) {
  992. - syslog(LOG_NOTICE, "ignored ENETDOWN from sendto(), a network interface was going down?");
  993. - } else if (errno == ENXIO) {
  994. - syslog(LOG_NOTICE, "ignored ENXIO from sendto(), a network interface went down?");
  995. - } else if (errno == ENOBUFS) {
  996. - syslog(LOG_NOTICE, "ignored ENOBUFS from sendto(), temporary shortage of buffer memory");
  997. - } else {
  998. - syslog(LOG_ERR, "mainloop: Error, sendto failed! (rv=%d, errno=%d)", nrsent, errno);
  999. + /* no_discifs_cntr became 0, rediscover interfaces */
  1000. + NVBCR_PRINTF(("no_discifs_cntr became 0, rediscover interfaces\n"));
  1001. + copy_ifsnr(cur_ifsnr, old_ifsnr);
  1002. + memset(cur_ifsnr, -1, sizeof(cur_ifsnr));
  1003. + iflist = discoverActiveInterfaces(s);
  1004. + /*
  1005. + * Build new cur_ifsnr list.
  1006. + * Make iflist[i] correspond with cur_ifsnr[i], so iflist[i].index == cur_ifsnr[i].ifindex
  1007. + * The old list (old_ifsnr) is used to compare.
  1008. + */
  1009. + for (i=0; iflist[i].index; ++i) {
  1010. + /* check to see if it is a NEW interface */
  1011. + int fsnr = find_sock_nr(old_ifsnr, iflist[i].index);
  1012. + if (fsnr == -1) {
  1013. + /* found new interface, open dedicated socket and
  1014. + bind it to the interface */
  1015. + if ((cur_ifsnr[i].sock_nr = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL))) < 0) {
  1016. + syslog(LOG_ERR, "mainloop: Error, socket error! (rv=%d, errno=%d)", cur_ifsnr[i].sock_nr, errno);
  1017. exit(1);
  1018. }
  1019. + bind_to_iface(cur_ifsnr[i].sock_nr, iflist[i].index);
  1020. + ifs_change = 1;
  1021. }
  1022. - NVBCR_PRINTF(("Successfully relayed %d bytes \n", nrsent));
  1023. - if (vnologging == 0) {
  1024. - logstr_cntr = sprintf(logstr, "%s ", iflistLogRToString(&(iflist[j]), j, &(cur_ifsnr[j])));
  1025. - logstr += logstr_cntr;
  1026. - }
  1027. + else
  1028. + {
  1029. + /*
  1030. + * not a new interface, socket already opened,
  1031. + * interface already bound. Update cur_ifsnr.
  1032. + */
  1033. + cur_ifsnr[i].sock_nr = fsnr;
  1034. + }
  1035. + cur_ifsnr[i].ifindex = iflist[i].index;
  1036. }
  1037. + /* Close disappeared interfaces */
  1038. + for (i=0; i<MAXIF; ++i)
  1039. + {
  1040. + if ((old_ifsnr[i].sock_nr != -1) && (old_ifsnr[i].ifindex != -1) &&
  1041. + (find_sock_nr(cur_ifsnr, old_ifsnr[i].ifindex) == -1)) {
  1042. + NVBCR_PRINTF(("Closing an interface (it disappeared), namely: (s_nr=%d, ifidx=%d)\n", old_ifsnr[i].sock_nr, old_ifsnr[i].ifindex));
  1043. + close(old_ifsnr[i].sock_nr);
  1044. + old_ifsnr[i].sock_nr = -1;
  1045. + old_ifsnr[i].ifindex = -1;
  1046. + ifs_change = 1;
  1047. + }
  1048. + }
  1049. + if (ifs_change == 1)
  1050. + {
  1051. + NVBCR_PRINTF(("Active interface set changed --> displaying current active interfaces..\n"));
  1052. + if (vnologging == 0) {
  1053. + lptr = log_interfaces;
  1054. + lsize = sizeof(log_interfaces);
  1055. + chunk = snprintf(lptr, lsize, "%s ",
  1056. + "Active interface set changed to:");
  1057. + if (chunk < lsize) {
  1058. + lptr += chunk;
  1059. + lsize -= chunk;
  1060. + }
  1061. + }
  1062. + for (i = 0; iflist[i].index; i++)
  1063. + {
  1064. + NVBCR_PRINTF(("\t\tactive interface number: %d, if=(%s), sock_nr=%d\n", i, iflistToString(&(iflist[i])), cur_ifsnr[i].sock_nr));
  1065. + if (vnologging == 0) {
  1066. + chunk = snprintf(lptr, lsize, "%s ",
  1067. + iflistLogIToString(&(iflist[i]), i, &(cur_ifsnr[i])));
  1068. + if (chunk < lsize) {
  1069. + lptr += chunk;
  1070. + lsize -= chunk;
  1071. + }
  1072. + }
  1073. + }
  1074. + if (vnologging == 0) syslog(LOG_INFO, "%s", log_interfaces);
  1075. + ifs_change = 0;
  1076. + }
  1077. }
  1078. - if (vnologging == 0) syslog(LOG_INFO, "%s", log_relayed);
  1079. - } else {
  1080. - NVBCR_PRINTF(("is NOT an UDP BROADCAST (with TTL!=1 and UDP_CHKSUM!=0)\n\n"));
  1081. - }
  1082. - }
  1083. - }
  1084. - /*
  1085. - * Don't forget to discover new interfaces if we keep getting
  1086. - * incoming packets (on an already discovered interface).
  1087. - */
  1088. - if (no_discifs_cntr == 0)
  1089. - {
  1090. - no_discifs_cntr = MAX_NODISCOVER_IFS;
  1091. -
  1092. - /* no_discifs_cntr became 0, rediscover interfaces */
  1093. - NVBCR_PRINTF(("no_discifs_cntr became 0, rediscover interfaces\n"));
  1094. - copy_ifsnr(cur_ifsnr, old_ifsnr);
  1095. - memset(cur_ifsnr, -1, sizeof(cur_ifsnr));
  1096. - iflist = discoverActiveInterfaces(s);
  1097. - /*
  1098. - * Build new cur_ifsnr list.
  1099. - * Make iflist[i] correspond with cur_ifsnr[i], so iflist[i].index == cur_ifsnr[i].ifindex
  1100. - * The old list (old_ifsnr) is used to compare.
  1101. - */
  1102. - for (i=0; iflist[i].index; ++i) {
  1103. - /* check to see if it is a NEW interface */
  1104. - int fsnr = find_sock_nr(old_ifsnr, iflist[i].index);
  1105. - if (fsnr == -1) {
  1106. - /* found new interface, open dedicated socket and bind it to the interface */
  1107. - if ((cur_ifsnr[i].sock_nr = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL))) < 0) {
  1108. - syslog(LOG_ERR, "mainloop: Error, socket error! (rv=%d, errno=%d)", cur_ifsnr[i].sock_nr, errno);
  1109. - exit(1);
  1110. - }
  1111. - bind_to_iface(cur_ifsnr[i].sock_nr, iflist[i].index);
  1112. - ifs_change = 1;
  1113. - }
  1114. else
  1115. - {
  1116. - /*
  1117. - * not a new interface, socket already openen, interface already
  1118. - * bound. Update cur_ifsnr.
  1119. - */
  1120. - cur_ifsnr[i].sock_nr = fsnr;
  1121. - }
  1122. - cur_ifsnr[i].ifindex = iflist[i].index;
  1123. - }
  1124. - /* Close disappeared interfaces */
  1125. - for (i=0; i<MAXIF; ++i)
  1126. - {
  1127. - if ((old_ifsnr[i].sock_nr != -1) && (old_ifsnr[i].ifindex != -1) &&
  1128. - (find_sock_nr(cur_ifsnr, old_ifsnr[i].ifindex) == -1)) {
  1129. - NVBCR_PRINTF(("Closing an interface (it disappeared), namely: (s_nr=%d, ifidx=%d)\n", old_ifsnr[i].sock_nr, old_ifsnr[i].ifindex));
  1130. - close(old_ifsnr[i].sock_nr);
  1131. - old_ifsnr[i].sock_nr = -1;
  1132. - old_ifsnr[i].ifindex = -1;
  1133. - ifs_change = 1;
  1134. - }
  1135. - }
  1136. - if (ifs_change == 1)
  1137. - {
  1138. - NVBCR_PRINTF(("Active interface set changed --> displaying current active interfaces..\n"));
  1139. - if (vnologging == 0) {
  1140. - logstr = log_interfaces;
  1141. - logstr_cntr = sprintf(logstr, "Active interface set changed to: ");
  1142. - logstr += logstr_cntr;
  1143. - }
  1144. - for (i = 0; iflist[i].index; i++)
  1145. - {
  1146. - NVBCR_PRINTF(("\t\tactive interface number: %d, if=(%s), sock_nr=%d\n", i, iflistToString(&(iflist[i])), cur_ifsnr[i].sock_nr));
  1147. - if (vnologging == 0) {
  1148. - logstr_cntr = sprintf(logstr, "%s ", iflistLogIToString(&(iflist[i]), i, &(cur_ifsnr[i])));
  1149. - logstr += logstr_cntr;
  1150. + {
  1151. + no_discifs_cntr -= MAX_SELECT_WAIT;
  1152. }
  1153. - }
  1154. - if (vnologging == 0) syslog(LOG_INFO, "%s", log_interfaces);
  1155. - ifs_change = 0;
  1156. }
  1157. - }
  1158. - else
  1159. - {
  1160. - no_discifs_cntr -= MAX_SELECT_WAIT;
  1161. - }
  1162. }
  1163. - }
  1164. }
  1165. // Discover active interfaces
  1166. @@ -788,102 +860,102 @@
  1167. /* Reset ifs */
  1168. memset(&ifs, 0, sizeof(ifs));
  1169. - //regcomp(&preg, argv[1], REG_ICASE|REG_EXTENDED);
  1170. - regcomp(&preg, interfaces, REG_ICASE|REG_EXTENDED);
  1171. + regcomp(&preg, reg_interfaces, REG_ICASE|REG_EXTENDED);
  1172. ifs.ifc_len = MAXIF*sizeof(struct ifreq);
  1173. ifs.ifc_req = malloc(ifs.ifc_len);
  1174. ioctl(s, SIOCGIFCONF, &ifs); // Discover active interfaces
  1175. for (i = 0; i * sizeof(struct ifreq) < ifs.ifc_len && cntr < MAXIF; i++)
  1176. - {
  1177. - if (regexec(&preg, ifs.ifc_req[i].ifr_name, 0, NULL, 0) == 0) {
  1178. -
  1179. - /*
  1180. - * Get interface flags and check status and type.
  1181. - * Only if interface is up it will be used.
  1182. - */
  1183. - memset(&ifrflags, 0, sizeof(ifrflags));
  1184. - strncpy(ifrflags.ifr_name, ifs.ifc_req[i].ifr_name, strlen(ifs.ifc_req[i].ifr_name));
  1185. - if (ioctl(s, SIOCGIFFLAGS, &ifrflags) < 0) {
  1186. - syslog(LOG_ERR, "discoverActiveInterfaces: Error, SIOCGIFFLAGS Failed! (errno=%d)", errno);
  1187. - exit(1);
  1188. - }
  1189. -
  1190. - if (ifrflags.ifr_flags & IFF_UP)
  1191. - {
  1192. - /*
  1193. - * Get interface index
  1194. - */
  1195. - ioctl(s, SIOCGIFINDEX, &ifs.ifc_req[i]);
  1196. -//Fix 3mar2003
  1197. - //iflist[cntr].index = (char)ifs.ifc_req[i].ifr_ifindex;
  1198. - iflist[cntr].index = ifs.ifc_req[i].ifr_ifindex;
  1199. -
  1200. - /*
  1201. - * Get interface name
  1202. - */
  1203. - strncpy(iflist[cntr].ifname, ifs.ifc_req[i].ifr_ifrn.ifrn_name,
  1204. - sizeof(iflist[cntr].ifname));
  1205. - iflist[cntr].ifname[sizeof(iflist[cntr].ifname)-1] = 0;
  1206. + {
  1207. + if (regexec(&preg, ifs.ifc_req[i].ifr_name, 0, NULL, 0) == 0) {
  1208. /*
  1209. - * Get local IP address
  1210. + * Get interface flags and check status and type.
  1211. + * Only if interface is up it will be used.
  1212. */
  1213. - memset(&ifr, 0, sizeof(ifr));
  1214. - ifr.ifr_addr.sa_family = AF_INET;
  1215. - (void)strncpy(ifr.ifr_name, iflist[cntr].ifname, strlen(iflist[cntr].ifname)+1);
  1216. - if (ioctl(s, SIOCGIFADDR, (char *)&ifr) < 0) {
  1217. - syslog(LOG_ERR, "discoverActiveInterfaces: Error, SIOCGIFADDR Failed! (errno=%d)", errno);
  1218. + memset(&ifrflags, 0, sizeof(ifrflags));
  1219. + strncpy(ifrflags.ifr_name, ifs.ifc_req[i].ifr_name, strlen(ifs.ifc_req[i].ifr_name));
  1220. + if (ioctl(s, SIOCGIFFLAGS, &ifrflags) < 0) {
  1221. + syslog(LOG_ERR, "discoverActiveInterfaces: Error, SIOCGIFFLAGS Failed! (errno=%d)", errno);
  1222. exit(1);
  1223. }
  1224. - sin = (struct sockaddr_in *)&ifr.ifr_addr;
  1225. - iflist[cntr].ifaddr = ntohl(sin->sin_addr.s_addr);
  1226. - iflist[cntr].flags1 = 0;
  1227. + if (ifrflags.ifr_flags & IFF_UP)
  1228. + {
  1229. + /*
  1230. + * Get interface index
  1231. + */
  1232. + ioctl(s, SIOCGIFINDEX, &ifs.ifc_req[i]);
  1233. + //Fix 3mar2003
  1234. + //iflist[cntr].index = (char)ifs.ifc_req[i].ifr_ifindex;
  1235. + iflist[cntr].index = ifs.ifc_req[i].ifr_ifindex;
  1236. - if (ifrflags.ifr_flags & IFF_POINTOPOINT) {
  1237. - /*
  1238. - * Get remote IP address (only for PPP interfaces)
  1239. - */
  1240. - memset(&ifr, 0, sizeof(ifr));
  1241. - ifr.ifr_addr.sa_family = AF_INET;
  1242. - (void)strncpy(ifr.ifr_name, iflist[cntr].ifname, strlen(iflist[cntr].ifname)+1);
  1243. - if (ioctl(s, SIOCGIFDSTADDR, (char *)&ifr) < 0) {
  1244. - syslog(LOG_ERR, "discoverActiveInterfaces: Error, SIOCGIFDSTADDR Failed! (errno=%d)", errno);
  1245. - exit(1);
  1246. - }
  1247. - sin = (struct sockaddr_in *)&ifr.ifr_addr;
  1248. - iflist[cntr].ifdstaddr = ntohl(sin->sin_addr.s_addr);
  1249. + /*
  1250. + * Get interface name
  1251. + */
  1252. + strncpy(iflist[cntr].ifname, ifs.ifc_req[i].ifr_ifrn.ifrn_name,
  1253. + sizeof(iflist[cntr].ifname));
  1254. + iflist[cntr].ifname[sizeof(iflist[cntr].ifname)-1] = 0;
  1255. - iflist[cntr].flags1 |= IFLIST_FLAGS1_IF_IS_PPP;
  1256. - iflist[cntr].bcast = INADDR_BROADCAST;
  1257. - }
  1258. - else if (ifrflags.ifr_flags & IFF_BROADCAST)
  1259. - {
  1260. - iflist[cntr].ifdstaddr = 0;
  1261. - iflist[cntr].flags1 |= IFLIST_FLAGS1_IF_IS_ETH;
  1262. - iflist[cntr].bcast = INADDR_BROADCAST;
  1263. - }
  1264. - else
  1265. - {
  1266. - iflist[cntr].ifdstaddr = 0;
  1267. - iflist[cntr].flags1 |= IFLIST_FLAGS1_IF_IS_UNKNOWN;
  1268. - iflist[cntr].bcast = INADDR_BROADCAST;
  1269. - }
  1270. + /*
  1271. + * Get local IP address
  1272. + */
  1273. + memset(&ifr, 0, sizeof(ifr));
  1274. + ifr.ifr_addr.sa_family = AF_INET;
  1275. + (void)strncpy(ifr.ifr_name, iflist[cntr].ifname, strlen(iflist[cntr].ifname)+1);
  1276. + if (ioctl(s, SIOCGIFADDR, (char *)&ifr) < 0) {
  1277. + syslog(LOG_ERR, "discoverActiveInterfaces: Error, SIOCGIFADDR Failed! (errno=%d)", errno);
  1278. + exit(1);
  1279. + }
  1280. + sin = (struct sockaddr_in *)&ifr.ifr_addr;
  1281. + iflist[cntr].ifaddr = ntohl(sin->sin_addr.s_addr);
  1282. - cntr++;
  1283. - }
  1284. - // IPSEC tunnels are a fun one. We must change the destination address
  1285. - // so that it will be routed to the correct tunnel end point.
  1286. - // We can define several tunnel end points for the same ipsec interface.
  1287. - } else if (ipsec != empty && strncmp(ifs.ifc_req[i].ifr_name, "ipsec", 5) == 0) {
  1288. - if (strncmp(ifs.ifc_req[i].ifr_name, ipsec, 6) == 0) {
  1289. - struct hostent *hp = gethostbyname(ipsec+7);
  1290. - ioctl(s, SIOCGIFINDEX, &ifs.ifc_req[i]);
  1291. - iflist[cntr].index = ifs.ifc_req[i].ifr_ifindex; /* Store the SIOCGIFINDEX number */
  1292. - memcpy(&(iflist[cntr++].bcast), hp->h_addr, sizeof(u_int32_t));
  1293. + iflist[cntr].flags1 = 0;
  1294. +
  1295. + if (ifrflags.ifr_flags & IFF_POINTOPOINT) {
  1296. + /*
  1297. + * Get remote IP address (only for PPP interfaces)
  1298. + */
  1299. + memset(&ifr, 0, sizeof(ifr));
  1300. + ifr.ifr_addr.sa_family = AF_INET;
  1301. + (void)strncpy(ifr.ifr_name, iflist[cntr].ifname, strlen(iflist[cntr].ifname)+1);
  1302. + if (ioctl(s, SIOCGIFDSTADDR, (char *)&ifr) < 0) {
  1303. + syslog(LOG_ERR, "discoverActiveInterfaces: Error, SIOCGIFDSTADDR Failed! (errno=%d)", errno);
  1304. + exit(1);
  1305. + }
  1306. + sin = (struct sockaddr_in *)&ifr.ifr_addr;
  1307. + iflist[cntr].ifdstaddr = ntohl(sin->sin_addr.s_addr);
  1308. +
  1309. + iflist[cntr].flags1 |= IFLIST_FLAGS1_IF_IS_PPP;
  1310. + iflist[cntr].bcast = INADDR_BROADCAST;
  1311. + }
  1312. + else if (ifrflags.ifr_flags & IFF_BROADCAST)
  1313. + {
  1314. + iflist[cntr].ifdstaddr = 0;
  1315. + iflist[cntr].flags1 |= IFLIST_FLAGS1_IF_IS_ETH;
  1316. + iflist[cntr].bcast = INADDR_BROADCAST;
  1317. + }
  1318. + else
  1319. + {
  1320. + iflist[cntr].ifdstaddr = 0;
  1321. + iflist[cntr].flags1 |= IFLIST_FLAGS1_IF_IS_UNKNOWN;
  1322. + iflist[cntr].bcast = INADDR_BROADCAST;
  1323. + }
  1324. +
  1325. + cntr++;
  1326. + }
  1327. + // IPSEC tunnels are a fun one. We must change the
  1328. + // destination address so that it will be routed to the
  1329. + // correct tunnel end point. We can define several tunnel end
  1330. + // points for the same ipsec interface.
  1331. + } else if (ipsec != empty && strncmp(ifs.ifc_req[i].ifr_name, "ipsec", 5) == 0) {
  1332. + if (strncmp(ifs.ifc_req[i].ifr_name, ipsec, 6) == 0) {
  1333. + struct hostent *hp = gethostbyname(ipsec+7);
  1334. + ioctl(s, SIOCGIFINDEX, &ifs.ifc_req[i]);
  1335. + iflist[cntr].index = ifs.ifc_req[i].ifr_ifindex; /* Store the SIOCGIFINDEX number */
  1336. + memcpy(&(iflist[cntr++].bcast), hp->h_addr, sizeof(u_int32_t));
  1337. + }
  1338. }
  1339. }
  1340. - }
  1341. iflist[cntr].index = 0; // Terminate list
  1342. free(ifs.ifc_req); // Stop that leak.
  1343. @@ -934,28 +1006,33 @@
  1344. static char *IpProtToString( unsigned char prot )
  1345. {
  1346. switch( prot )
  1347. - {
  1348. - case 0x11:
  1349. - return "UDP";
  1350. - case 0x6:
  1351. - return "TCP";
  1352. - case 0x2f:
  1353. - return "GRE";
  1354. - case 0x1:
  1355. - return "ICMP";
  1356. - default:
  1357. - return "???";
  1358. - }
  1359. + {
  1360. + case 0x11:
  1361. + return "UDP";
  1362. + case 0x6:
  1363. + return "TCP";
  1364. + case 0x2f:
  1365. + return "GRE";
  1366. + case 0x1:
  1367. + return "ICMP";
  1368. + default:
  1369. + return "???";
  1370. + }
  1371. }
  1372. static char *iflistToString( struct iflist *ifp )
  1373. {
  1374. - static char str_tr[80+1];
  1375. + static char str_tr[MAX_IFLOGTOSTR+90];
  1376. - sprintf(str_tr, "index=%d, ifname=%s, ifaddr=%ld.%ld.%ld.%ld, ifdstaddr=%ld.%ld.%ld.%ld, flags1=0x%04lx",
  1377. + snprintf(str_tr, sizeof(str_tr), "index=%d, ifname=%s, ifaddr=%ld.%ld.%ld.%ld, ifdstaddr=%ld.%ld.%ld.%ld, flags1=0x%04lx",
  1378. ifp->index, ifp->ifname,
  1379. - (ifp->ifaddr)>>24, ((ifp->ifaddr)&0x00ff0000)>>16, ((ifp->ifaddr)&0x0000ff00)>>8, (ifp->ifaddr)&0x000000ff,
  1380. - (ifp->ifdstaddr)>>24, ((ifp->ifdstaddr)&0x00ff0000)>>16, ((ifp->ifdstaddr)&0x0000ff00)>>8,
  1381. + (ifp->ifaddr)>>24,
  1382. + ((ifp->ifaddr)&0x00ff0000)>>16,
  1383. + ((ifp->ifaddr)&0x0000ff00)>>8,
  1384. + (ifp->ifaddr)&0x000000ff,
  1385. + (ifp->ifdstaddr)>>24,
  1386. + ((ifp->ifdstaddr)&0x00ff0000)>>16,
  1387. + ((ifp->ifdstaddr)&0x0000ff00)>>8,
  1388. (ifp->ifdstaddr)&0x000000ff, ifp->flags1);
  1389. return str_tr;
  1390. @@ -963,21 +1040,16 @@
  1391. static char *iflistLogRToString( struct iflist *ifp, int idx, struct ifsnr *ifnr )
  1392. {
  1393. - static char str_tr[MAX_IFLOGTOSTR]; /*
  1394. - * This makes function: 1) non-reentrant (doesn't matter).
  1395. - * 2) not useable multiple times by (s)printf.
  1396. - */
  1397. - sprintf(str_tr, "%s", ifp->ifname);
  1398. + static char str_tr[MAX_IFLOGTOSTR];
  1399. + snprintf(str_tr, sizeof(str_tr), "%s", ifp->ifname);
  1400. return str_tr;
  1401. }
  1402. static char *iflistLogIToString( struct iflist *ifp, int idx, struct ifsnr *ifnr )
  1403. {
  1404. - static char str_tr[MAX_IFLOGTOSTR]; /*
  1405. - * This makes function: 1) non-reentrant (doesn't matter).
  1406. - * 2) not useable multiple times by (s)printf.
  1407. - */
  1408. - sprintf(str_tr, "%s(%d/%d/%d)", ifp->ifname, idx, ifp->index, ifnr->sock_nr);
  1409. + static char str_tr[MAX_IFLOGTOSTR+64];
  1410. + snprintf(str_tr, sizeof(str_tr), "%s(%d/%d/%d)", ifp->ifname,
  1411. + idx, ifp->index, ifnr->sock_nr);
  1412. return str_tr;
  1413. }
  1414. @@ -1001,10 +1073,10 @@
  1415. int i;
  1416. for (i=0; i<MAXIF; ++i)
  1417. - {
  1418. - to[i].sock_nr = from[i].sock_nr;
  1419. - to[i].ifindex = from[i].ifindex;
  1420. - }
  1421. + {
  1422. + to[i].sock_nr = from[i].sock_nr;
  1423. + to[i].ifindex = from[i].ifindex;
  1424. + }
  1425. }
  1426. static int find_sock_nr(struct ifsnr *l, int ifidx)
  1427. @@ -1016,4 +1088,3 @@
  1428. /* not found */
  1429. return -1;
  1430. }
  1431. -