00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include "NetworkInterfaces.h"
00042
00043
00044 #include <stddef.h>
00045 #include <syslog.h>
00046 #include <string.h>
00047 #include <errno.h>
00048 #include <unistd.h>
00049 #include <sys/ioctl.h>
00050 #include <fcntl.h>
00051 #include <assert.h>
00052 #include <net/if.h>
00053 #include <netinet/in.h>
00054 #include <linux/if_ether.h>
00055 #include <linux/if_packet.h>
00056 #include <linux/if_tun.h>
00057 #include <netinet/ip.h>
00058 #include <netinet/udp.h>
00059 #include <stdlib.h>
00060 #include <stdio.h>
00061
00062
00063 #include "olsr.h"
00064 #include "ipcalc.h"
00065 #include "defs.h"
00066 #include "link_set.h"
00067 #include "tc_set.h"
00068 #include "net_olsr.h"
00069 #include "lq_plugin.h"
00070 #include "olsr_ip_prefix_list.h"
00071 #include "olsr_logging.h"
00072
00073
00074 #include "Packet.h"
00075 #include "Bmf.h"
00076 #include "Address.h"
00077
00078
00079 struct TBmfInterface *BmfInterfaces = NULL;
00080 struct TBmfInterface *LastBmfInterface = NULL;
00081
00082
00083
00084 int HighestSkfd = -1;
00085
00086
00087 fd_set InputSet;
00088
00089
00090 int EtherTunTapFd = -1;
00091
00092
00093
00094 char EtherTunTapIfName[IFNAMSIZ] = "bmf0";
00095
00096
00097
00098
00099
00100 enum TBmfMechanism BmfMechanism = BM_BROADCAST;
00101
00102 #define ETHERTUNTAPIPNOTSET 0
00103
00104
00105
00106 u_int32_t EtherTunTapIp = ETHERTUNTAPIPNOTSET;
00107
00108
00109
00110 u_int32_t EtherTunTapIpMask = 0xFFFFFFFF;
00111
00112
00113
00114 u_int32_t EtherTunTapIpBroadcast = ETHERTUNTAPIPNOTSET;
00115
00116
00117
00118 int TunTapIpOverruled = 0;
00119
00120
00121
00122
00123 int CapturePacketsOnOlsrInterfaces = 0;
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136 int
00137 SetBmfInterfaceName(const char *ifname,
00138 void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused)))
00139 {
00140 strncpy(EtherTunTapIfName, ifname, IFNAMSIZ - 1);
00141 EtherTunTapIfName[IFNAMSIZ - 1] = '\0';
00142 return 0;
00143 }
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157 int
00158 SetBmfInterfaceIp(const char *ip, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused)))
00159 {
00160 #define IPV4_MAX_ADDRLEN 16
00161 #define IPV4_MAX_PREFIXLEN 32
00162 char *slashAt;
00163 char ipAddr[IPV4_MAX_ADDRLEN];
00164 struct in_addr sinaddr;
00165 int prefixLen;
00166 int i;
00167
00168
00169
00170
00171
00172 slashAt = strchr(ip, '/');
00173
00174
00175 if (slashAt == NULL || slashAt - ip >= IPV4_MAX_ADDRLEN) {
00176
00177 return 1;
00178 }
00179
00180 strncpy(ipAddr, ip, slashAt - ip);
00181 *(ipAddr + (slashAt - ip)) = '\0';
00182 if (inet_aton(ipAddr, &sinaddr) == 0) {
00183
00184 return 1;
00185 }
00186
00187 EtherTunTapIp = ntohl(sinaddr.s_addr);
00188
00189
00190 prefixLen = atoi(++slashAt);
00191 if (prefixLen <= 0 || prefixLen > IPV4_MAX_PREFIXLEN) {
00192 return 1;
00193 }
00194
00195
00196 EtherTunTapIpMask = 0;
00197 for (i = 0; i < prefixLen; i++) {
00198 EtherTunTapIpMask |= (1 << (IPV4_MAX_PREFIXLEN - 1 - i));
00199 }
00200
00201
00202 EtherTunTapIpBroadcast = EtherTunTapIp;
00203 for (i = prefixLen; i < IPV4_MAX_PREFIXLEN; i++) {
00204 EtherTunTapIpBroadcast |= (1 << (IPV4_MAX_PREFIXLEN - 1 - i));
00205 }
00206
00207 TunTapIpOverruled = 1;
00208
00209 return 0;
00210 }
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223 int
00224 SetCapturePacketsOnOlsrInterfaces(const char *enable,
00225 void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused)))
00226 {
00227 if (strcmp(enable, "yes") == 0) {
00228 CapturePacketsOnOlsrInterfaces = 1;
00229 return 0;
00230 } else if (strcmp(enable, "no") == 0) {
00231 CapturePacketsOnOlsrInterfaces = 0;
00232 return 0;
00233 }
00234
00235
00236 return 1;
00237 }
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250 int
00251 SetBmfMechanism(const char *mechanism,
00252 void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused)))
00253 {
00254 if (strcmp(mechanism, "Broadcast") == 0) {
00255 BmfMechanism = BM_BROADCAST;
00256 return 0;
00257 } else if (strcmp(mechanism, "UnicastPromiscuous") == 0) {
00258 BmfMechanism = BM_UNICAST_PROMISCUOUS;
00259 return 0;
00260 }
00261
00262
00263 return 1;
00264 }
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275 static void
00276 AddDescriptorToInputSet(int skfd)
00277 {
00278
00279 if (skfd > HighestSkfd) {
00280 HighestSkfd = skfd;
00281 }
00282
00283
00284 FD_SET(skfd, &InputSet);
00285 }
00286
00287
00288 static char EthTapSpoofState = '1';
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300 int
00301 DeactivateSpoofFilter(void)
00302 {
00303 FILE *procSpoof;
00304 char procFile[FILENAME_MAX];
00305
00306
00307 sprintf(procFile, "/proc/sys/net/ipv4/conf/%s/rp_filter", EtherTunTapIfName);
00308
00309
00310 procSpoof = fopen(procFile, "r");
00311 if (procSpoof == NULL) {
00312 OLSR_WARN(LOG_PLUGINS,
00313 "WARNING! Could not open the %s file to check/disable the IP spoof filter!\n"
00314 "Are you using the procfile filesystem?\n"
00315 "Does your system support IPv4?\n"
00316 "I will continue (in 3 sec) - but you should manually ensure that IP spoof\n" "filtering is disabled!\n\n", procFile);
00317
00318 sleep(3);
00319 return 0;
00320 }
00321
00322 EthTapSpoofState = fgetc(procSpoof);
00323 fclose(procSpoof);
00324
00325
00326 procSpoof = fopen(procFile, "w");
00327 if (procSpoof == NULL) {
00328 OLSR_WARN(LOG_PLUGINS, "Could not open %s for writing!\n"
00329 "I will continue (in 3 sec) - but you should manually ensure that IP" " spoof filtering is disabled!\n\n", procFile);
00330 sleep(3);
00331 return 0;
00332 }
00333
00334 fputs("0", procSpoof);
00335
00336 fclose(procSpoof);
00337
00338 return 1;
00339 }
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350 void
00351 RestoreSpoofFilter(void)
00352 {
00353 FILE *procSpoof;
00354 char procFile[FILENAME_MAX];
00355
00356
00357 sprintf(procFile, "/proc/sys/net/ipv4/conf/%s/rp_filter", EtherTunTapIfName);
00358
00359
00360 procSpoof = fopen(procFile, "w");
00361 if (procSpoof == NULL) {
00362 OLSR_WARN(LOG_PLUGINS, "Could not open %s for writing!\nSettings not restored!\n", procFile);
00363 } else {
00364 fputc(EthTapSpoofState, procSpoof);
00365 fclose(procSpoof);
00366 }
00367 }
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385 void
00386 FindNeighbors(struct TBestNeighbors *neighbors,
00387 struct link_entry **bestNeighbor,
00388 struct TBmfInterface *intf,
00389 union olsr_ip_addr *source, union olsr_ip_addr *forwardedBy, union olsr_ip_addr *forwardedTo, int *nPossibleNeighbors)
00390 {
00391 struct link_entry *walker, *iterator;
00392 olsr_linkcost previousLinkEtx = LINK_COST_BROKEN;
00393 olsr_linkcost bestEtx = LINK_COST_BROKEN;
00394
00395 int i;
00396
00397
00398 *bestNeighbor = NULL;
00399 for (i = 0; i < MAX_UNICAST_NEIGHBORS; i++) {
00400 neighbors->links[i] = NULL;
00401 }
00402 *nPossibleNeighbors = 0;
00403
00404 if (forwardedBy != NULL) {
00405
00406 struct link_entry *bestLinkFromForwarder = get_best_link_to_neighbor_ip(forwardedBy);
00407 if (bestLinkFromForwarder != NULL) {
00408 previousLinkEtx = bestLinkFromForwarder->linkcost;
00409 }
00410 }
00411
00412 OLSR_FOR_ALL_LINK_ENTRIES(walker, iterator) {
00413 #if !defined REMOVE_LOG_DEBUG
00414 struct ipaddr_str buf;
00415 #endif
00416 union olsr_ip_addr *neighborMainIp;
00417 struct link_entry *bestLinkToNeighbor;
00418 struct tc_entry *tcLastHop;
00419 float currEtx;
00420
00421
00422 if (olsr_ipcmp(&intf->intAddr, &walker->local_iface_addr) != 0) {
00423 continue;
00424 }
00425
00426 OLSR_DEBUG(LOG_PLUGINS,
00427 "Considering forwarding pkt on \"%s\" to %s\n", intf->ifName, olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
00428
00429 neighborMainIp = MainAddressOf(&walker->neighbor_iface_addr);
00430
00431
00432
00433 if (source != NULL && olsr_ipcmp(neighborMainIp, MainAddressOf(source)) == 0) {
00434 OLSR_DEBUG(LOG_PLUGINS, "Not forwarding to %s: is source of pkt\n", olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
00435
00436 continue;
00437 }
00438
00439
00440 if (forwardedBy != NULL && olsr_ipcmp(neighborMainIp, MainAddressOf(forwardedBy)) == 0) {
00441 OLSR_DEBUG(LOG_PLUGINS,
00442 "Not forwarding to %s: is the node that forwarded the pkt\n",
00443 olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
00444
00445 continue;
00446 }
00447
00448
00449 if (forwardedTo != NULL && olsr_ipcmp(neighborMainIp, MainAddressOf(forwardedTo)) == 0) {
00450 OLSR_DEBUG(LOG_PLUGINS,
00451 "Not forwarding to %s: is the node to which the pkt was forwarded\n",
00452 olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
00453
00454 continue;
00455 }
00456
00457
00458
00459
00460 currEtx = walker->linkcost;
00461
00462 if (currEtx >= LINK_COST_BROKEN) {
00463 OLSR_DEBUG(LOG_PLUGINS, "Not forwarding to %s: link is timing out\n", olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
00464
00465 continue;
00466 }
00467
00468
00469 OLSR_DEBUG(LOG_PLUGINS,
00470 "Forwarding pkt to %s will cost ETX %5.2f\n", olsr_ip_to_string(&buf, &walker->neighbor_iface_addr), currEtx);
00471
00472
00473
00474
00475
00476
00477 bestLinkToNeighbor = get_best_link_to_neighbor_ip(&walker->neighbor_iface_addr);
00478
00479 if (walker != bestLinkToNeighbor) {
00480 if (bestLinkToNeighbor == NULL) {
00481 OLSR_DEBUG(LOG_PLUGINS, "Not forwarding to %s: no link found\n", olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
00482 } else {
00483 #if !defined REMOVE_LOG_DEBUG
00484 struct interface *bestIntf = if_ifwithaddr(&bestLinkToNeighbor->local_iface_addr);
00485 char lqbuffer[LQTEXT_MAXLENGTH];
00486 #endif
00487 OLSR_DEBUG(LOG_PLUGINS,
00488 "Not forwarding to %s: \"%s\" gives a better link to this neighbor, costing %s\n",
00489 olsr_ip_to_string(&buf, &walker->neighbor_iface_addr),
00490 bestIntf->int_name,
00491 olsr_get_linkcost_text(bestLinkToNeighbor->linkcost, false, lqbuffer, sizeof(lqbuffer)));
00492 }
00493
00494 continue;
00495 }
00496
00497 if (forwardedBy != NULL) {
00498 #if !defined REMOVE_LOG_DEBUG
00499 struct ipaddr_str forwardedByBuf, niaBuf;
00500 char lqbuffer[LQTEXT_MAXLENGTH];
00501 #endif
00502 OLSR_DEBUG(LOG_PLUGINS,
00503 "2-hop path from %s via me to %s will cost ETX %s\n",
00504 olsr_ip_to_string(&forwardedByBuf, forwardedBy),
00505 olsr_ip_to_string(&niaBuf, &walker->neighbor_iface_addr),
00506 olsr_get_linkcost_text(previousLinkEtx + currEtx, true, lqbuffer, sizeof(lqbuffer)));
00507 }
00508
00509
00510
00511
00512
00513 if (forwardedBy != NULL) {
00514 tcLastHop = olsr_lookup_tc_entry(MainAddressOf(forwardedBy));
00515 if (tcLastHop != NULL) {
00516 struct tc_edge_entry *tc_edge;
00517
00518 tc_edge = olsr_lookup_tc_edge(tcLastHop, MainAddressOf(&walker->neighbor_iface_addr));
00519
00520
00521 if (tc_edge) {
00522 olsr_linkcost tcEtx = tc_edge->cost;
00523
00524 if (previousLinkEtx + currEtx > tcEtx) {
00525 #if !defined REMOVE_LOG_DEBUG
00526 struct ipaddr_str neighbor_iface_buf, forw_buf;
00527 char lqbuffer[LQTEXT_MAXLENGTH];
00528 olsr_ip_to_string(&neighbor_iface_buf, &walker->neighbor_iface_addr);
00529 #endif
00530 OLSR_DEBUG(LOG_PLUGINS,
00531 "Not forwarding to %s: I am not an MPR between %s and %s, direct link costs %s\n",
00532 neighbor_iface_buf.buf,
00533 olsr_ip_to_string(&forw_buf, forwardedBy),
00534 neighbor_iface_buf.buf,
00535 olsr_get_linkcost_text(tcEtx, false, lqbuffer, sizeof(lqbuffer)));
00536
00537 continue;
00538 }
00539 }
00540 }
00541 }
00542
00543
00544
00545 if (currEtx < bestEtx) {
00546 *bestNeighbor = walker;
00547 bestEtx = currEtx;
00548 }
00549
00550
00551
00552
00553 if (*nPossibleNeighbors < FanOutLimit) {
00554 neighbors->links[*nPossibleNeighbors] = walker;
00555 }
00556
00557 *nPossibleNeighbors += 1;
00558 }
00559
00560
00561 if (*nPossibleNeighbors == 0) {
00562 OLSR_DEBUG(LOG_PLUGINS, "No suitable neighbor found to forward to on \"%s\"\n", intf->ifName);
00563 } else {
00564 #if !defined REMOVE_LOG_DEBUG
00565 struct ipaddr_str buf;
00566 #endif
00567 OLSR_DEBUG(LOG_PLUGINS,
00568 "%d neighbors found on \"%s\"; best neighbor to forward to: %s\n",
00569 *nPossibleNeighbors, intf->ifName, olsr_ip_to_string(&buf, &(*bestNeighbor)->neighbor_iface_addr));
00570 }
00571
00572 }
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584 static int
00585 CreateCaptureSocket(const char *ifName)
00586 {
00587 int ifIndex = if_nametoindex(ifName);
00588 struct packet_mreq mreq;
00589 struct ifreq req;
00590 struct sockaddr_ll bindTo;
00591
00592
00593 int skfd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
00594 if (skfd < 0) {
00595 OLSR_WARN(LOG_PLUGINS, "socket(PF_PACKET) error");
00596 return -1;
00597 }
00598
00599
00600 memset(&mreq, 0, sizeof(struct packet_mreq));
00601 mreq.mr_ifindex = ifIndex;
00602 mreq.mr_type = PACKET_MR_PROMISC;
00603 if (setsockopt(skfd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) {
00604 OLSR_WARN(LOG_PLUGINS, "setsockopt(PACKET_MR_PROMISC) error");
00605 close(skfd);
00606 return -1;
00607 }
00608
00609
00610 memset(&req, 0, sizeof(struct ifreq));
00611 strncpy(req.ifr_name, ifName, IFNAMSIZ - 1);
00612 req.ifr_name[IFNAMSIZ - 1] = '\0';
00613 if (ioctl(skfd, SIOCGIFHWADDR, &req) < 0) {
00614 OLSR_WARN(LOG_PLUGINS, "error retrieving MAC address");
00615 close(skfd);
00616 return -1;
00617 }
00618
00619
00620 memset(&bindTo, 0, sizeof(bindTo));
00621 bindTo.sll_family = AF_PACKET;
00622 bindTo.sll_protocol = htons(ETH_P_IP);
00623 bindTo.sll_ifindex = ifIndex;
00624 memcpy(bindTo.sll_addr, req.ifr_hwaddr.sa_data, IFHWADDRLEN);
00625 bindTo.sll_halen = IFHWADDRLEN;
00626
00627 if (bind(skfd, (struct sockaddr *)&bindTo, sizeof(bindTo)) < 0) {
00628 OLSR_WARN(LOG_PLUGINS, "bind() error");
00629 close(skfd);
00630 return -1;
00631 }
00632
00633
00634 if (fcntl(skfd, F_SETFL, fcntl(skfd, F_GETFL, 0) & ~O_NONBLOCK) < 0) {
00635 OLSR_WARN(LOG_PLUGINS, "fcntl() error");
00636 close(skfd);
00637 return -1;
00638 }
00639
00640 AddDescriptorToInputSet(skfd);
00641
00642 return skfd;
00643 }
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656 static int
00657 CreateListeningSocket(const char *ifName)
00658 {
00659 int ifIndex = if_nametoindex(ifName);
00660 struct packet_mreq mreq;
00661 struct ifreq req;
00662 struct sockaddr_ll bindTo;
00663
00664
00665 int skfd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
00666 if (skfd < 0) {
00667 OLSR_WARN(LOG_PLUGINS, "socket(PF_PACKET) error");
00668 return -1;
00669 }
00670
00671
00672 memset(&mreq, 0, sizeof(struct packet_mreq));
00673 mreq.mr_ifindex = ifIndex;
00674 mreq.mr_type = PACKET_MR_PROMISC;
00675 if (setsockopt(skfd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) {
00676 OLSR_WARN(LOG_PLUGINS, "setsockopt(PACKET_MR_PROMISC) error");
00677 close(skfd);
00678 return -1;
00679 }
00680
00681
00682 memset(&req, 0, sizeof(struct ifreq));
00683 strncpy(req.ifr_name, ifName, IFNAMSIZ - 1);
00684 req.ifr_name[IFNAMSIZ - 1] = '\0';
00685 if (ioctl(skfd, SIOCGIFHWADDR, &req) < 0) {
00686 OLSR_WARN(LOG_PLUGINS, "error retrieving MAC address");
00687 close(skfd);
00688 return -1;
00689 }
00690
00691
00692 memset(&bindTo, 0, sizeof(bindTo));
00693 bindTo.sll_family = AF_PACKET;
00694 bindTo.sll_protocol = htons(ETH_P_IP);
00695 bindTo.sll_ifindex = ifIndex;
00696 memcpy(bindTo.sll_addr, req.ifr_hwaddr.sa_data, IFHWADDRLEN);
00697 bindTo.sll_halen = IFHWADDRLEN;
00698
00699 if (bind(skfd, (struct sockaddr *)&bindTo, sizeof(bindTo)) < 0) {
00700 OLSR_WARN(LOG_PLUGINS, "bind() error");
00701 close(skfd);
00702 return -1;
00703 }
00704
00705
00706 if (fcntl(skfd, F_SETFL, fcntl(skfd, F_GETFL, 0) & ~O_NONBLOCK) < 0) {
00707 OLSR_WARN(LOG_PLUGINS, "fcntl() error");
00708 close(skfd);
00709 return -1;
00710 }
00711
00712 AddDescriptorToInputSet(skfd);
00713
00714 return skfd;
00715 }
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728 static int
00729 CreateEncapsulateSocket(const char *ifName)
00730 {
00731 int on = 1;
00732 struct sockaddr_in bindTo;
00733
00734
00735 int skfd = socket(PF_INET, SOCK_DGRAM, 0);
00736 if (skfd < 0) {
00737 OLSR_WARN(LOG_PLUGINS, "socket(PF_INET) error");
00738 return -1;
00739 }
00740
00741
00742 if (setsockopt(skfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0) {
00743 OLSR_WARN(LOG_PLUGINS, "setsockopt(SO_BROADCAST) error");
00744 close(skfd);
00745 return -1;
00746 }
00747
00748
00749
00750 if (setsockopt(skfd, SOL_SOCKET, SO_BINDTODEVICE, ifName, strlen(ifName) + 1) < 0) {
00751 OLSR_WARN(LOG_PLUGINS, "setsockopt(SO_BINDTODEVICE) error");
00752 close(skfd);
00753 return -1;
00754 }
00755
00756
00757 memset(&bindTo, 0, sizeof(bindTo));
00758 bindTo.sin_family = AF_INET;
00759 bindTo.sin_port = htons(BMF_ENCAP_PORT);
00760 bindTo.sin_addr.s_addr = htonl(INADDR_ANY);
00761
00762 if (bind(skfd, (struct sockaddr *)&bindTo, sizeof(bindTo)) < 0) {
00763 OLSR_WARN(LOG_PLUGINS, "bind() error");
00764 close(skfd);
00765 return -1;
00766 }
00767
00768
00769 if (fcntl(skfd, F_SETFL, fcntl(skfd, F_GETFL, 0) & ~O_NONBLOCK) < 0) {
00770 OLSR_WARN(LOG_PLUGINS, "fcntl() error");
00771 close(skfd);
00772 return -1;
00773 }
00774
00775 AddDescriptorToInputSet(skfd);
00776
00777 return skfd;
00778 }
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795 static int
00796 CreateLocalEtherTunTap(void)
00797 {
00798 static const char deviceName[] = "/dev/net/tun";
00799 struct ifreq ifreq;
00800 int etfd;
00801 int ioctlSkfd;
00802 int ioctlres;
00803
00804 etfd = open(deviceName, O_RDWR | O_NONBLOCK);
00805 if (etfd < 0) {
00806 OLSR_WARN(LOG_PLUGINS, "error opening %s", deviceName);
00807 return -1;
00808 }
00809
00810 memset(&ifreq, 0, sizeof(ifreq));
00811 strncpy(ifreq.ifr_name, EtherTunTapIfName, IFNAMSIZ - 1);
00812 ifreq.ifr_name[IFNAMSIZ - 1] = '\0';
00813
00814
00815
00816 ifreq.ifr_flags = IFF_TUN;
00817 ifreq.ifr_flags |= IFF_NO_PI;
00818
00819 if (ioctl(etfd, TUNSETIFF, (void *)&ifreq) < 0) {
00820 OLSR_WARN(LOG_PLUGINS, "ioctl(TUNSETIFF) error on %s", deviceName);
00821 close(etfd);
00822 return -1;
00823 }
00824
00825 memset(&ifreq, 0, sizeof(ifreq));
00826 strncpy(ifreq.ifr_name, EtherTunTapIfName, IFNAMSIZ - 1);
00827 ifreq.ifr_name[IFNAMSIZ - 1] = '\0';
00828 ifreq.ifr_addr.sa_family = AF_INET;
00829
00830 ioctlSkfd = socket(PF_INET, SOCK_DGRAM, 0);
00831 if (ioctlSkfd < 0) {
00832 OLSR_WARN(LOG_PLUGINS, "socket(PF_INET) error on %s", deviceName);
00833 close(etfd);
00834 return -1;
00835 }
00836
00837
00838
00839
00840
00841 if (EtherTunTapIp == ETHERTUNTAPIPNOTSET) {
00842 struct TBmfInterface *nextBmfIf = BmfInterfaces;
00843 while (nextBmfIf != NULL) {
00844 struct TBmfInterface *bmfIf = nextBmfIf;
00845 nextBmfIf = bmfIf->next;
00846
00847 if (bmfIf->olsrIntf != NULL) {
00848 EtherTunTapIp = ntohl(bmfIf->intAddr.v4.s_addr);
00849 EtherTunTapIpBroadcast = EtherTunTapIp;
00850 }
00851 }
00852 }
00853
00854 if (EtherTunTapIp == ETHERTUNTAPIPNOTSET) {
00855
00856
00857 EtherTunTapIp = ETHERTUNTAPDEFAULTIP;
00858 }
00859
00860 ((struct sockaddr_in *)(ARM_NOWARN_ALIGN(&ifreq.ifr_addr)))->sin_addr.s_addr = htonl(EtherTunTapIp);
00861 ioctlres = ioctl(ioctlSkfd, SIOCSIFADDR, &ifreq);
00862 if (ioctlres >= 0) {
00863
00864 ((struct sockaddr_in *)(ARM_NOWARN_ALIGN(&ifreq.ifr_netmask)))->sin_addr.s_addr = htonl(EtherTunTapIpMask);
00865 ioctlres = ioctl(ioctlSkfd, SIOCSIFNETMASK, &ifreq);
00866 if (ioctlres >= 0) {
00867
00868 ((struct sockaddr_in *)(ARM_NOWARN_ALIGN(&ifreq.ifr_broadaddr)))->sin_addr.s_addr = htonl(EtherTunTapIpBroadcast);
00869 ioctlres = ioctl(ioctlSkfd, SIOCSIFBRDADDR, &ifreq);
00870 if (ioctlres >= 0) {
00871
00872 ioctlres = ioctl(ioctlSkfd, SIOCGIFFLAGS, &ifreq);
00873 if (ioctlres >= 0) {
00874 ifreq.ifr_flags |= (IFF_UP | IFF_RUNNING | IFF_BROADCAST);
00875 ioctlres = ioctl(ioctlSkfd, SIOCSIFFLAGS, &ifreq);
00876 }
00877 }
00878 }
00879 }
00880
00881 if (ioctlres < 0) {
00882
00883 OLSR_WARN(LOG_PLUGINS, "error bringing up EtherTunTap interface \"%s\"", EtherTunTapIfName);
00884
00885 close(etfd);
00886 close(ioctlSkfd);
00887 return -1;
00888 }
00889
00890
00891
00892 memset(&ifreq, 0, sizeof(ifreq));
00893 strncpy(ifreq.ifr_name, EtherTunTapIfName, IFNAMSIZ - 1);
00894 ifreq.ifr_name[IFNAMSIZ - 1] = '\0';
00895
00896 ioctlres = ioctl(ioctlSkfd, SIOCGIFFLAGS, &ifreq);
00897 if (ioctlres >= 0) {
00898 ifreq.ifr_flags |= IFF_MULTICAST;
00899 ioctlres = ioctl(ioctlSkfd, SIOCSIFFLAGS, &ifreq);
00900 }
00901 if (ioctlres < 0) {
00902
00903 OLSR_WARN(LOG_PLUGINS, "error setting multicast flag on EtherTunTap interface \"%s\"", EtherTunTapIfName);
00904
00905
00906 }
00907
00908
00909
00910
00911 if (ioctl(etfd, TUNSETPERSIST, (void *)&ifreq) < 0) {
00912 OLSR_WARN(LOG_PLUGINS, "error making EtherTunTap interface \"%s\" persistent", EtherTunTapIfName);
00913
00914
00915 }
00916
00917 OLSR_DEBUG(LOG_PLUGINS, "opened 1 socket on \"%s\"\n", EtherTunTapIfName);
00918
00919 AddDescriptorToInputSet(etfd);
00920
00921
00922
00923
00924 if (TunTapIpOverruled != 0) {
00925 union olsr_ip_addr temp_net;
00926
00927 temp_net.v4.s_addr = htonl(EtherTunTapIp);
00928 ip_prefix_list_add(&olsr_cnf->hna_entries, &temp_net, 32);
00929 }
00930
00931 close(ioctlSkfd);
00932
00933 return etfd;
00934 }
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947 static int
00948 CreateInterface(const char *ifName, struct interface *olsrIntf)
00949 {
00950 int capturingSkfd = -1;
00951 int encapsulatingSkfd = -1;
00952 int listeningSkfd = -1;
00953 int ioctlSkfd;
00954 struct ifreq ifr;
00955 int nOpened = 0;
00956 struct TBmfInterface *newIf = malloc(sizeof(struct TBmfInterface));
00957
00958 assert(ifName != NULL);
00959
00960 if (newIf == NULL) {
00961 return 0;
00962 }
00963
00964 if (olsrIntf != NULL) {
00965
00966
00967 encapsulatingSkfd = CreateEncapsulateSocket(ifName);
00968 if (encapsulatingSkfd < 0) {
00969 free(newIf);
00970 return 0;
00971 }
00972 nOpened++;
00973 }
00974
00975
00976
00977 if ((olsrIntf == NULL) || (CapturePacketsOnOlsrInterfaces != 0)) {
00978 capturingSkfd = CreateCaptureSocket(ifName);
00979 if (capturingSkfd < 0) {
00980 close(encapsulatingSkfd);
00981 free(newIf);
00982 return 0;
00983 }
00984
00985 nOpened++;
00986 }
00987
00988
00989
00990 if (BmfMechanism == BM_UNICAST_PROMISCUOUS) {
00991 listeningSkfd = CreateListeningSocket(ifName);
00992 if (listeningSkfd < 0) {
00993 close(listeningSkfd);
00994 close(encapsulatingSkfd);
00995 free(newIf);
00996 return 0;
00997 }
00998
00999 nOpened++;
01000 }
01001
01002
01003
01004 ioctlSkfd = (capturingSkfd >= 0) ? capturingSkfd : encapsulatingSkfd;
01005
01006
01007 memset(&ifr, 0, sizeof(struct ifreq));
01008 strncpy(ifr.ifr_name, ifName, IFNAMSIZ - 1);
01009 ifr.ifr_name[IFNAMSIZ - 1] = '\0';
01010 if (ioctl(ioctlSkfd, SIOCGIFHWADDR, &ifr) < 0) {
01011 OLSR_WARN(LOG_PLUGINS, "ioctl(SIOCGIFHWADDR) error for interface \"%s\"", ifName);
01012 close(capturingSkfd);
01013 close(encapsulatingSkfd);
01014 free(newIf);
01015 return 0;
01016 }
01017
01018
01019 newIf->capturingSkfd = capturingSkfd;
01020 newIf->encapsulatingSkfd = encapsulatingSkfd;
01021 newIf->listeningSkfd = listeningSkfd;
01022 memcpy(newIf->macAddr, ifr.ifr_hwaddr.sa_data, IFHWADDRLEN);
01023 memcpy(newIf->ifName, ifName, IFNAMSIZ);
01024 newIf->olsrIntf = olsrIntf;
01025 if (olsrIntf != NULL) {
01026
01027
01028
01029 newIf->intAddr.v4 = olsrIntf->int_src.v4.sin_addr;
01030 newIf->broadAddr.v4 = olsrIntf->int_multicast.v4.sin_addr;
01031 } else {
01032
01033 memset(&ifr, 0, sizeof(struct ifreq));
01034 strncpy(ifr.ifr_name, ifName, IFNAMSIZ - 1);
01035 ifr.ifr_name[IFNAMSIZ - 1] = '\0';
01036 if (ioctl(ioctlSkfd, SIOCGIFADDR, &ifr) < 0) {
01037 OLSR_WARN(LOG_PLUGINS, "ioctl(SIOCGIFADDR) error for interface \"%s\"", ifName);
01038
01039 newIf->intAddr.v4.s_addr = inet_addr("0.0.0.0");
01040 } else {
01041
01042 newIf->intAddr.v4 = ((struct sockaddr_in *)(ARM_NOWARN_ALIGN(&ifr.ifr_addr)))->sin_addr;
01043 }
01044
01045
01046 memset(&ifr, 0, sizeof(struct ifreq));
01047 strncpy(ifr.ifr_name, ifName, IFNAMSIZ - 1);
01048 ifr.ifr_name[IFNAMSIZ - 1] = '\0';
01049 if (ioctl(ioctlSkfd, SIOCGIFBRDADDR, &ifr) < 0) {
01050 OLSR_WARN(LOG_PLUGINS, "ioctl(SIOCGIFBRDADDR) error for interface \"%s\"", ifName);
01051
01052 newIf->broadAddr.v4.s_addr = inet_addr("0.0.0.0");
01053 } else {
01054
01055 newIf->broadAddr.v4 = ((struct sockaddr_in *)(ARM_NOWARN_ALIGN(&ifr.ifr_broadaddr)))->sin_addr;
01056 }
01057 }
01058
01059
01060 memset(&newIf->fragmentHistory, 0, sizeof(newIf->fragmentHistory));
01061 newIf->nextFragmentHistoryEntry = 0;
01062
01063
01064 newIf->nBmfPacketsRx = 0;
01065 newIf->nBmfPacketsRxDup = 0;
01066 newIf->nBmfPacketsTx = 0;
01067
01068
01069
01070 if (BmfInterfaces == NULL) {
01071
01072 BmfInterfaces = newIf;
01073 LastBmfInterface = newIf;
01074 } else if (olsrIntf != NULL) {
01075
01076 newIf->next = BmfInterfaces;
01077 BmfInterfaces = newIf;
01078 } else {
01079
01080 newIf->next = NULL;
01081 LastBmfInterface->next = newIf;
01082 LastBmfInterface = newIf;
01083 }
01084
01085 OLSR_DEBUG(LOG_PLUGINS,
01086 "opened %d socket%s on %s interface \"%s\"\n",
01087 nOpened, nOpened == 1 ? "" : "s", olsrIntf != NULL ? "OLSR" : "non-OLSR", ifName);
01088
01089 return nOpened;
01090 }
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101 int
01102 CreateBmfNetworkInterfaces(struct interface *skipThisIntf)
01103 {
01104 int skfd;
01105 struct ifconf ifc;
01106 int numreqs = 30;
01107 struct ifreq *ifr;
01108 int n;
01109 int nOpenedSockets = 0;
01110
01111
01112 FD_ZERO(&InputSet);
01113
01114 skfd = socket(PF_INET, SOCK_DGRAM, 0);
01115 if (skfd < 0) {
01116 OLSR_WARN(LOG_PLUGINS, "no inet socket available to retrieve interface list");
01117 return -1;
01118 }
01119
01120
01121 ifc.ifc_buf = NULL;
01122 for (;;) {
01123 ifc.ifc_len = sizeof(struct ifreq) * numreqs;
01124 ifc.ifc_buf = realloc(ifc.ifc_buf, ifc.ifc_len);
01125
01126 if (ioctl(skfd, SIOCGIFCONF, &ifc) < 0) {
01127 OLSR_WARN(LOG_PLUGINS, "ioctl(SIOCGIFCONF) error");
01128
01129 close(skfd);
01130 free(ifc.ifc_buf);
01131 return -1;
01132 }
01133 if ((unsigned)ifc.ifc_len == sizeof(struct ifreq) * numreqs) {
01134
01135 numreqs *= 2;
01136 assert(numreqs < 1024);
01137 continue;
01138 }
01139 break;
01140 }
01141
01142 close(skfd);
01143
01144
01145 ifr = ifc.ifc_req;
01146 for (n = ifc.ifc_len / sizeof(struct ifreq); --n >= 0; ifr++) {
01147 struct interface *olsrIntf;
01148 union olsr_ip_addr ipAddr;
01149
01150
01151 if (strncmp(ifr->ifr_name, EtherTunTapIfName, IFNAMSIZ) == 0) {
01152 continue;
01153 }
01154
01155
01156 ipAddr.v4 = ((struct sockaddr_in *)(ARM_NOWARN_ALIGN(&ifr->ifr_addr)))->sin_addr;
01157 olsrIntf = if_ifwithaddr(&ipAddr);
01158
01159 if (skipThisIntf != NULL && olsrIntf == skipThisIntf) {
01160 continue;
01161 }
01162
01163 if (olsrIntf == NULL && !IsNonOlsrBmfIf(ifr->ifr_name)) {
01164
01165
01166 continue;
01167 }
01168
01169 nOpenedSockets += CreateInterface(ifr->ifr_name, olsrIntf);
01170
01171 }
01172
01173 free(ifc.ifc_buf);
01174
01175
01176 EtherTunTapFd = CreateLocalEtherTunTap();
01177 if (EtherTunTapFd >= 0) {
01178 nOpenedSockets++;
01179 }
01180
01181 if (BmfInterfaces == NULL) {
01182 OLSR_WARN(LOG_PLUGINS, "could not initialize any network interface\n");
01183 } else {
01184 OLSR_WARN(LOG_PLUGINS, "opened %d sockets\n", nOpenedSockets);
01185 }
01186 return 0;
01187 }
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198 void
01199 AddInterface(struct interface *newIntf)
01200 {
01201 int nOpened;
01202
01203 assert(newIntf != NULL);
01204
01205 nOpened = CreateInterface(newIntf->int_name, newIntf);
01206
01207 OLSR_DEBUG(LOG_PLUGINS, "opened %d sockets\n", nOpened);
01208 }
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226 void
01227 CloseBmfNetworkInterfaces(void)
01228 {
01229 int nClosed = 0;
01230 u_int32_t totalOlsrBmfPacketsRx = 0;
01231 u_int32_t totalOlsrBmfPacketsRxDup = 0;
01232 u_int32_t totalOlsrBmfPacketsTx = 0;
01233 u_int32_t totalNonOlsrBmfPacketsRx = 0;
01234 u_int32_t totalNonOlsrBmfPacketsRxDup = 0;
01235 u_int32_t totalNonOlsrBmfPacketsTx = 0;
01236
01237
01238 struct TBmfInterface *nextBmfIf = BmfInterfaces;
01239 while (nextBmfIf != NULL) {
01240 struct TBmfInterface *bmfIf = nextBmfIf;
01241 nextBmfIf = bmfIf->next;
01242
01243 if (bmfIf->capturingSkfd >= 0) {
01244 close(bmfIf->capturingSkfd);
01245 nClosed++;
01246 }
01247 if (bmfIf->encapsulatingSkfd >= 0) {
01248 close(bmfIf->encapsulatingSkfd);
01249 nClosed++;
01250 }
01251
01252 OLSR_DEBUG(LOG_PLUGINS,
01253 "%s interface \"%s\": RX pkts %u (%u dups); TX pkts %u\n",
01254 bmfIf->olsrIntf != NULL ? "OLSR" : "non-OLSR",
01255 bmfIf->ifName, bmfIf->nBmfPacketsRx, bmfIf->nBmfPacketsRxDup, bmfIf->nBmfPacketsTx);
01256
01257 OLSR_DEBUG(LOG_PLUGINS, "closed %s interface \"%s\"\n", bmfIf->olsrIntf != NULL ? "OLSR" : "non-OLSR", bmfIf->ifName);
01258
01259
01260 if (bmfIf->olsrIntf != NULL) {
01261 totalOlsrBmfPacketsRx += bmfIf->nBmfPacketsRx;
01262 totalOlsrBmfPacketsRxDup += bmfIf->nBmfPacketsRxDup;
01263 totalOlsrBmfPacketsTx += bmfIf->nBmfPacketsTx;
01264 } else {
01265 totalNonOlsrBmfPacketsRx += bmfIf->nBmfPacketsRx;
01266 totalNonOlsrBmfPacketsRxDup += bmfIf->nBmfPacketsRxDup;
01267 totalNonOlsrBmfPacketsTx += bmfIf->nBmfPacketsTx;
01268 }
01269
01270 free(bmfIf);
01271 }
01272
01273 if (EtherTunTapFd >= 0) {
01274 close(EtherTunTapFd);
01275 nClosed++;
01276
01277 OLSR_DEBUG(LOG_PLUGINS, "closed \"%s\"\n", EtherTunTapIfName);
01278 }
01279
01280 BmfInterfaces = NULL;
01281
01282 OLSR_DEBUG(LOG_PLUGINS, "closed %d sockets\n", nClosed);
01283
01284 OLSR_DEBUG(LOG_PLUGINS,
01285 "Total all OLSR interfaces : RX pkts %u (%u dups); TX pkts %u\n",
01286 totalOlsrBmfPacketsRx, totalOlsrBmfPacketsRxDup, totalOlsrBmfPacketsTx);
01287 OLSR_DEBUG(LOG_PLUGINS,
01288 "Total all non-OLSR interfaces: RX pkts %u (%u dups); TX pkts %u\n",
01289 totalNonOlsrBmfPacketsRx, totalNonOlsrBmfPacketsRxDup, totalNonOlsrBmfPacketsTx);
01290 }
01291
01292 #define MAX_NON_OLSR_IFS 32
01293 static char NonOlsrIfNames[MAX_NON_OLSR_IFS][IFNAMSIZ];
01294 static int nNonOlsrIfs = 0;
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307 int
01308 AddNonOlsrBmfIf(const char *ifName, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused)))
01309 {
01310 assert(ifName != NULL);
01311
01312 if (nNonOlsrIfs >= MAX_NON_OLSR_IFS) {
01313 OLSR_WARN(LOG_PLUGINS, "too many non-OLSR interfaces specified, maximum is %d\n", MAX_NON_OLSR_IFS);
01314 return 1;
01315 }
01316
01317 strncpy(NonOlsrIfNames[nNonOlsrIfs], ifName, IFNAMSIZ - 1);
01318 NonOlsrIfNames[nNonOlsrIfs][IFNAMSIZ - 1] = '\0';
01319 nNonOlsrIfs++;
01320 return 0;
01321 }
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331 int
01332 IsNonOlsrBmfIf(const char *ifName)
01333 {
01334 int i;
01335
01336 assert(ifName != NULL);
01337
01338 for (i = 0; i < nNonOlsrIfs; i++) {
01339 if (strncmp(NonOlsrIfNames[i], ifName, IFNAMSIZ) == 0)
01340 return 1;
01341 }
01342 return 0;
01343 }
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358 void
01359 CheckAndUpdateLocalBroadcast(unsigned char *ipPacket, union olsr_ip_addr *broadAddr)
01360 {
01361 struct iphdr *iph;
01362 union olsr_ip_addr destIp;
01363
01364 assert(ipPacket != NULL && broadAddr != NULL);
01365
01366 iph = (struct iphdr *)(ARM_NOWARN_ALIGN(ipPacket));
01367 destIp.v4.s_addr = iph->daddr;
01368 if (!IsMulticast(&destIp)) {
01369 u_int32_t origDaddr, newDaddr;
01370 u_int32_t check;
01371
01372 origDaddr = ntohl(iph->daddr);
01373
01374 iph->daddr = broadAddr->v4.s_addr;
01375 newDaddr = ntohl(iph->daddr);
01376
01377
01378 check = ntohs(iph->check);
01379
01380 check = ~(~check - ((origDaddr >> 16) & 0xFFFF) + ((newDaddr >> 16) & 0xFFFF));
01381 check = ~(~check - (origDaddr & 0xFFFF) + (newDaddr & 0xFFFF));
01382
01383
01384 check = check + (check >> 16);
01385
01386 iph->check = htons(check);
01387
01388 if (iph->protocol == SOL_UDP) {
01389
01390
01391 int ipHeaderLen = GetIpHeaderLength(ipPacket);
01392 struct udphdr *udph = (struct udphdr *)(ARM_NOWARN_ALIGN(ipPacket + ipHeaderLen));
01393
01394
01395
01396 check = ntohs(udph->check);
01397
01398 check = ~(~check - ((origDaddr >> 16) & 0xFFFF) + ((newDaddr >> 16) & 0xFFFF));
01399 check = ~(~check - (origDaddr & 0xFFFF) + (newDaddr & 0xFFFF));
01400
01401
01402 check = check + (check >> 16);
01403
01404 udph->check = htons(check);
01405 }
01406 }
01407 }
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418 void
01419 AddMulticastRoute(void)
01420 {
01421 struct rtentry kernel_route;
01422 int ioctlSkfd = socket(PF_INET, SOCK_DGRAM, 0);
01423 if (ioctlSkfd < 0) {
01424 OLSR_WARN(LOG_PLUGINS, "socket(PF_INET) error");
01425 return;
01426 }
01427
01428 memset(&kernel_route, 0, sizeof(struct rtentry));
01429
01430 ((struct sockaddr_in *)(ARM_NOWARN_ALIGN(&kernel_route.rt_dst)))->sin_family = AF_INET;
01431 ((struct sockaddr_in *)(ARM_NOWARN_ALIGN(&kernel_route.rt_gateway)))->sin_family = AF_INET;
01432 ((struct sockaddr_in *)(ARM_NOWARN_ALIGN(&kernel_route.rt_genmask)))->sin_family = AF_INET;
01433
01434
01435 ((struct sockaddr_in *)(ARM_NOWARN_ALIGN(&kernel_route.rt_dst)))->sin_addr.s_addr = htonl(0xE0000000);
01436 ((struct sockaddr_in *)(ARM_NOWARN_ALIGN(&kernel_route.rt_genmask)))->sin_addr.s_addr = htonl(0xF0000000);
01437
01438 kernel_route.rt_metric = 0;
01439 kernel_route.rt_flags = RTF_UP;
01440
01441 kernel_route.rt_dev = EtherTunTapIfName;
01442
01443 if (ioctl(ioctlSkfd, SIOCADDRT, &kernel_route) < 0) {
01444 OLSR_WARN(LOG_PLUGINS, "error setting multicast route via EtherTunTap interface \"%s\"", EtherTunTapIfName);
01445
01446
01447 }
01448 close(ioctlSkfd);
01449 }
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460 void
01461 DeleteMulticastRoute(void)
01462 {
01463 if (EtherTunTapIp != ETHERTUNTAPDEFAULTIP) {
01464 struct rtentry kernel_route;
01465 int ioctlSkfd = socket(PF_INET, SOCK_DGRAM, 0);
01466 if (ioctlSkfd < 0) {
01467 OLSR_WARN(LOG_PLUGINS, "socket(PF_INET) error");
01468 return;
01469 }
01470
01471 memset(&kernel_route, 0, sizeof(struct rtentry));
01472
01473 ((struct sockaddr_in *)(ARM_NOWARN_ALIGN(&kernel_route.rt_dst)))->sin_family = AF_INET;
01474 ((struct sockaddr_in *)(ARM_NOWARN_ALIGN(&kernel_route.rt_gateway)))->sin_family = AF_INET;
01475 ((struct sockaddr_in *)(ARM_NOWARN_ALIGN(&kernel_route.rt_genmask)))->sin_family = AF_INET;
01476
01477
01478 ((struct sockaddr_in *)(ARM_NOWARN_ALIGN(&kernel_route.rt_dst)))->sin_addr.s_addr = htonl(0xE0000000);
01479 ((struct sockaddr_in *)(ARM_NOWARN_ALIGN(&kernel_route.rt_genmask)))->sin_addr.s_addr = htonl(0xF0000000);
01480
01481 kernel_route.rt_metric = 0;
01482 kernel_route.rt_flags = RTF_UP;
01483
01484 kernel_route.rt_dev = EtherTunTapIfName;
01485
01486 if (ioctl(ioctlSkfd, SIOCDELRT, &kernel_route) < 0) {
01487 OLSR_WARN(LOG_PLUGINS, "error deleting multicast route via EtherTunTap interface \"%s\"", EtherTunTapIfName);
01488
01489
01490 }
01491 close(ioctlSkfd);
01492 }
01493 }
01494
01495
01496
01497
01498
01499
01500