📄 networkinterfaces.c
字号:
walker->neigh_link_quality); if (currEtx >= INFINITE_ETX) { OLSR_PRINTF( 9, "%s: ----> Not forwarding to %s: link is timing out\n", PLUGIN_NAME_SHORT, olsr_ip_to_string(&walker->neighbor_iface_addr)); continue; /* for */ } /* Compare costs to check if the candidate neighbor is best reached via 'intf' */ OLSR_PRINTF( 9, "%s: ----> Forwarding pkt to %s will cost ETX %5.2f\n", PLUGIN_NAME_SHORT, olsr_ip_to_string(&walker->neighbor_iface_addr), currEtx); /* If the candidate neighbor is best reached via another interface, then skip * the candidate neighbor; the candidate neighbor has been / will be selected via that * other interface. * TODO: get_best_link_to_neighbor() is not thread-safe. */ bestLinkToNeighbor = get_best_link_to_neighbor(&walker->neighbor_iface_addr); if (walker != bestLinkToNeighbor) { if (bestLinkToNeighbor == NULL) { OLSR_PRINTF( 9, "%s: ----> Not forwarding to %s: no link found\n", PLUGIN_NAME_SHORT, olsr_ip_to_string(&walker->neighbor_iface_addr)); } else { struct interface* bestIntf = if_ifwithaddr(&bestLinkToNeighbor->local_iface_addr); OLSR_PRINTF( 9, "%s: ----> Not forwarding to %s: \"%s\" gives a better link to this neighbor, costing %5.2f\n", PLUGIN_NAME_SHORT, olsr_ip_to_string(&walker->neighbor_iface_addr), bestIntf->int_name, CalcEtx( bestLinkToNeighbor->loss_link_quality, bestLinkToNeighbor->neigh_link_quality)); } continue; /* for */ } if (forwardedBy != NULL) { OLSR_PRINTF( 9, "%s: ----> 2-hop path from %s via me to %s will cost ETX %5.2f\n", PLUGIN_NAME_SHORT, olsr_ip_to_string(forwardedBy), olsr_ip_to_string(&walker->neighbor_iface_addr), previousLinkEtx + currEtx); } /* Check the topology table whether the 'forwardedBy' node is itself a direct * neighbor of the candidate neighbor, at a lower cost than the 2-hop route * via myself. If so, we do not need to forward the BMF packet to the candidate * neighbor, because the 'forwardedBy' node will forward the packet. */ if (forwardedBy != NULL) { /* TODO: olsr_lookup_tc_entry() is not thread-safe. */ tcLastHop = olsr_lookup_tc_entry(MainAddressOf(forwardedBy)); if (tcLastHop != NULL) { struct tc_edge_entry* tc_edge; /* TODO: olsr_lookup_tc_edge() is not thread-safe. */ tc_edge = olsr_lookup_tc_edge(tcLastHop, MainAddressOf(&walker->neighbor_iface_addr)); if (tc_edge != NULL) { float tcEtx = CalcEtx( tc_edge->link_quality, tc_edge->inverse_link_quality); if (previousLinkEtx + currEtx > tcEtx) { OLSR_PRINTF( 9, "%s: ----> Not forwarding to %s: I am not an MPR between %s and %s, direct link costs %5.2f\n", PLUGIN_NAME_SHORT, olsr_ip_to_string(&walker->neighbor_iface_addr), olsr_ip_to_string(forwardedBy), olsr_ip_to_string(&walker->neighbor_iface_addr), tcEtx); continue; /* for */ } /* if */ } /* if */ } /* if */ } /* if */ *nPossibleNeighbors += 1; /* Remember the best two links. If all are very bad, remember none. */ if (currEtx < bestEtx) { result->links[1] = result->links[0]; result->links[0] = walker; bestEtx = currEtx; } else if (currEtx < oneButBestEtx) { result->links[1] = walker; oneButBestEtx = currEtx; } /* if */ } /* for */#endif /* USING_THALES_LINK_COST_ROUTING */ } /* if */ /* Display the result of the neighbor search */ if (result->links[0] == NULL) { OLSR_PRINTF( 9, "%s: ----> No suitable neighbor found to forward to on \"%s\"\n", PLUGIN_NAME_SHORT, intf->ifName); } else { OLSR_PRINTF( 9, "%s: ----> Best neighbor%s to forward to on \"%s\": ", PLUGIN_NAME_SHORT, *nPossibleNeighbors == 1 ? "" : "s", intf->ifName); OLSR_PRINTF( 9, "%s", olsr_ip_to_string(&result->links[0]->neighbor_iface_addr)); if (result->links[1] != NULL) { OLSR_PRINTF( 9, ", %s", olsr_ip_to_string(&result->links[1]->neighbor_iface_addr)); } /* if */ OLSR_PRINTF(9, "\n"); } /* if */} /* GetBestTwoNeighbors *//* ------------------------------------------------------------------------- * Function : CreateCaptureSocket * Description: Create socket for promiscuously capturing multicast IP traffic * Input : ifname - network interface (e.g. "eth0") * Output : none * Return : the socket descriptor ( >= 0), or -1 if an error occurred * Data Used : none * Notes : The socket is a cooked IP packet socket, bound to the specified * network interface * ------------------------------------------------------------------------- */static int CreateCaptureSocket(const char* ifName){ int ifIndex = if_nametoindex(ifName); struct packet_mreq mreq; struct ifreq req; struct sockaddr_ll bindTo; /* Open cooked IP packet socket */ int skfd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP)); if (skfd < 0) { BmfPError("socket(PF_PACKET) error"); return -1; } /* Set interface to promiscuous mode */ memset(&mreq, 0, sizeof(struct packet_mreq)); mreq.mr_ifindex = ifIndex; mreq.mr_type = PACKET_MR_PROMISC; if (setsockopt(skfd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) { BmfPError("setsockopt(PACKET_MR_PROMISC) error"); close(skfd); return -1; } /* Get hardware (MAC) address */ memset(&req, 0, sizeof(struct ifreq)); strncpy(req.ifr_name, ifName, IFNAMSIZ - 1); req.ifr_name[IFNAMSIZ-1] = '\0'; /* Ensures null termination */ if (ioctl(skfd, SIOCGIFHWADDR, &req) < 0) { BmfPError("error retrieving MAC address"); close(skfd); return -1; } /* Bind the socket to the specified interface */ memset(&bindTo, 0, sizeof(bindTo)); bindTo.sll_family = AF_PACKET; bindTo.sll_protocol = htons(ETH_P_IP); bindTo.sll_ifindex = ifIndex; memcpy(bindTo.sll_addr, req.ifr_hwaddr.sa_data, IFHWADDRLEN); bindTo.sll_halen = IFHWADDRLEN; if (bind(skfd, (struct sockaddr*)&bindTo, sizeof(bindTo)) < 0) { BmfPError("bind() error"); close(skfd); return -1; } /* Set socket to blocking operation */ if (fcntl(skfd, F_SETFL, fcntl(skfd, F_GETFL, 0) & ~O_NONBLOCK) < 0) { BmfPError("fcntl() error"); close(skfd); return -1; } AddDescriptorToInputSet(skfd); return skfd;} /* CreateCaptureSocket *//* ------------------------------------------------------------------------- * Function : CreateListeningSocket * Description: Create socket for promiscuously listening to BMF packets. * Used only when 'BmfMechanism' is BM_UNICAST_PROMISCUOUS * Input : ifname - network interface (e.g. "eth0") * Output : none * Return : the socket descriptor ( >= 0), or -1 if an error occurred * Data Used : none * Notes : The socket is a cooked IP packet socket, bound to the specified * network interface * ------------------------------------------------------------------------- */static int CreateListeningSocket(const char* ifName){ int ifIndex = if_nametoindex(ifName); struct packet_mreq mreq; struct ifreq req; struct sockaddr_ll bindTo; /* Open cooked IP packet socket */ int skfd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP)); if (skfd < 0) { BmfPError("socket(PF_PACKET) error"); return -1; } /* Set interface to promiscuous mode */ memset(&mreq, 0, sizeof(struct packet_mreq)); mreq.mr_ifindex = ifIndex; mreq.mr_type = PACKET_MR_PROMISC; if (setsockopt(skfd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) { BmfPError("setsockopt(PACKET_MR_PROMISC) error"); close(skfd); return -1; } /* Get hardware (MAC) address */ memset(&req, 0, sizeof(struct ifreq)); strncpy(req.ifr_name, ifName, IFNAMSIZ - 1); req.ifr_name[IFNAMSIZ-1] = '\0'; /* Ensures null termination */ if (ioctl(skfd, SIOCGIFHWADDR, &req) < 0) { BmfPError("error retrieving MAC address"); close(skfd); return -1; } /* Bind the socket to the specified interface */ memset(&bindTo, 0, sizeof(bindTo)); bindTo.sll_family = AF_PACKET; bindTo.sll_protocol = htons(ETH_P_IP); bindTo.sll_ifindex = ifIndex; memcpy(bindTo.sll_addr, req.ifr_hwaddr.sa_data, IFHWADDRLEN); bindTo.sll_halen = IFHWADDRLEN; if (bind(skfd, (struct sockaddr*)&bindTo, sizeof(bindTo)) < 0) { BmfPError("bind() error"); close(skfd); return -1; } /* Set socket to blocking operation */ if (fcntl(skfd, F_SETFL, fcntl(skfd, F_GETFL, 0) & ~O_NONBLOCK) < 0) { BmfPError("fcntl() error"); close(skfd); return -1; } AddDescriptorToInputSet(skfd); return skfd;} /* CreateListeningSocket *//* ------------------------------------------------------------------------- * Function : CreateEncapsulateSocket * Description: Create a socket for sending and receiving encapsulated * multicast packets * Input : ifname - network interface (e.g. "eth0") * Output : none * Return : the socket descriptor ( >= 0), or -1 if an error occurred * Data Used : none * Notes : The socket is an UDP (datagram) over IP socket, bound to the * specified network interface * ------------------------------------------------------------------------- */static int CreateEncapsulateSocket(const char* ifName){ int on = 1; struct sockaddr_in bindTo; /* Open UDP-IP socket */ int skfd = socket(PF_INET, SOCK_DGRAM, 0); if (skfd < 0) { BmfPError("socket(PF_INET) error"); return -1; } /* Enable sending to broadcast addresses */ if (setsockopt(skfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0) { BmfPError("setsockopt(SO_BROADCAST) error"); close(skfd); return -1; } /* Bind to the specific network interfaces indicated by ifName. */ /* When using Kernel 2.6 this must happer prior to the port binding! */ if (setsockopt(skfd, SOL_SOCKET, SO_BINDTODEVICE, ifName, strlen(ifName) + 1) < 0) { BmfPError("setsockopt(SO_BINDTODEVICE) error"); close(skfd); return -1; } /* Bind to BMF port */ memset(&bindTo, 0, sizeof(bindTo)); bindTo.sin_family = AF_INET; bindTo.sin_port = htons(BMF_ENCAP_PORT); bindTo.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(skfd, (struct sockaddr*)&bindTo, sizeof(bindTo)) < 0) { BmfPError("bind() error"); close(skfd); return -1; } /* Set socket to blocking operation */ if (fcntl(skfd, F_SETFL, fcntl(skfd, F_GETFL, 0) & ~O_NONBLOCK) < 0) { BmfPError("fcntl() error"); close(skfd); return -1; } AddDescriptorToInputSet(skfd); return skfd;} /* CreateEncapsulateSocket *//* ------------------------------------------------------------------------- * Function : CreateLocalEtherTunTap * Description: Creates and brings up an EtherTunTap interface * Input : none * Output : none * Return : the socket file descriptor (>= 0), or -1 in case of failure * Data Used : EtherTunTapIfName - name used for the tuntap interface (e.g. * "bmf0") * EtherTunTapIp * EtherTunTapIpMask * EtherTunTapIpBroadcast * BmfInterfaces * Note : Order dependency: call this function only if BmfInterfaces * is filled with a list of network interfaces. * ------------------------------------------------------------------------- */static int CreateLocalEtherTunTap(void)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -