michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: michael@0: #include michael@0: #include michael@0: #include michael@0: michael@0: #define IN_ADDR_PLEN 16 /* including trailing '\0' */ michael@0: #define IN6_ADDR_PLEN 128 /* including trailing '\0' */ michael@0: #define MAC_ADDR_PLEN 18 michael@0: michael@0: michael@0: //static char netif_ip_addr[IN6_ADDR_PLEN]; michael@0: //static char netif_mac_addr[MAC_ADDR_PLEN]; michael@0: michael@0: //static int michael@0: //eth_macaddr_ntop(const struct sockaddr_dl *sdl, char *dst, size_t dstsize) michael@0: //{ michael@0: // const unsigned char *lladdr = LLADDR(sdl); michael@0: // int r; michael@0: // michael@0: // r = snprintf(dst, dstsize, "%02x:%02x:%02x:%02x:%02x:%02x", michael@0: // (int) lladdr[0], (int) lladdr[1], (int) lladdr[2], michael@0: // (int) lladdr[3], (int) lladdr[4], (int) lladdr[5]); michael@0: // michael@0: // if (r >= dstsize) michael@0: // /* The destination buffer is too small */ michael@0: // return -1; michael@0: // else michael@0: // return 0; michael@0: //} michael@0: michael@0: michael@0: /* michael@0: * Find the local IP (v4 or v6) address used by the system to reach a given IP michael@0: * address. michael@0: */ michael@0: //static int michael@0: //findlocaladdr(int af, struct sockaddr *dest, socklen_t destsize, michael@0: // struct sockaddr *local, socklen_t *localsize) michael@0: //{ michael@0: // int fd; michael@0: // michael@0: // if ((fd = socket(af, SOCK_DGRAM, 0)) == -1) { michael@0: // perror("socket"); michael@0: // return -1; michael@0: // } michael@0: // michael@0: // if (connect(fd, dest, destsize) != 0) { michael@0: // perror("connect"); michael@0: // close(fd); michael@0: // return -1; michael@0: // } michael@0: // michael@0: // /* michael@0: // * Retrieve the local address associated with the socket. michael@0: // */ michael@0: // if (getsockname(fd, (struct sockaddr *) local, localsize) != 0) { michael@0: // perror("getsockname"); michael@0: // close(fd); michael@0: // return -1; michael@0: // } michael@0: // michael@0: // close(fd); michael@0: // michael@0: // /* Check that the retrieved address is of the same family */ michael@0: // if (local->sa_family == af) michael@0: // return 0; michael@0: // else michael@0: // return -1; michael@0: //} michael@0: // michael@0: //static int michael@0: //inaddrcmp(struct sockaddr *s1, struct sockaddr *s2) michael@0: //{ michael@0: // if (s1->sa_family == s2->sa_family && s1->sa_family == AF_INET) { michael@0: // return bcmp(&((struct sockaddr_in *) s1)->sin_addr, michael@0: // &((struct sockaddr_in *) s2)->sin_addr, michael@0: // sizeof(struct in_addr)); michael@0: // } else if (s1->sa_family == s2->sa_family && s1->sa_family == AF_INET6) { michael@0: // return bcmp(&((struct sockaddr_in6 *) s1)->sin6_addr, michael@0: // &((struct sockaddr_in6 *) s2)->sin6_addr, michael@0: // sizeof(struct in6_addr)); michael@0: // } else { michael@0: // return -1; michael@0: // } michael@0: //} michael@0: michael@0: /* michael@0: * Retrieve the IP address (and associated link-layer address) that will be michael@0: * used by the operating system as the source IP address when sending packets michael@0: * to the given destination address. michael@0: */ michael@0: //static int michael@0: //getifaddr(int dstaf, struct sockaddr *dst, socklen_t dstsize, michael@0: // struct sockaddr *ipaddr, size_t ipaddrsize, struct sockaddr_dl *lladdr) michael@0: //{ michael@0: // struct sockaddr_storage ss; michael@0: // socklen_t sslen; michael@0: // struct ifaddrs *ifap, *ifp; michael@0: // char *ifname = NULL; michael@0: // int found_lladdr = 0; michael@0: // michael@0: // /* michael@0: // * First, determine the local IP address that will be used to reach the michael@0: // * given destination IP address. From that we will retrieve the interface michael@0: // * and then the MAC address. michael@0: // * `dstaf' can only be AF_INET or AF_INET6. michael@0: // */ michael@0: // bzero(&ss, sizeof(struct sockaddr_storage)); michael@0: // sslen = sizeof(struct sockaddr_storage); michael@0: // if (findlocaladdr(dstaf, dst, dstsize, (struct sockaddr *) &ss, &sslen) michael@0: // != 0) { michael@0: // return -1; michael@0: // } michael@0: // michael@0: // /* michael@0: // * Find the name of the network interface matching the address discovered michael@0: // * using findlocaladdr(). Note that this is not garanteed to yield the michael@0: // * correct result (or a result at all) because the network configuration michael@0: // * may change between the call to findlocaladdr() and getifaddrs(). michael@0: // * But this should work in most cases. michael@0: // */ michael@0: // if (getifaddrs(&ifap) == -1) michael@0: // return -1; michael@0: // michael@0: // for (ifp = ifap; ifp->ifa_next != NULL; ifp = ifp->ifa_next) { michael@0: // if (inaddrcmp(ifp->ifa_addr, (struct sockaddr *) &ss) == 0) { michael@0: // ifname = ifp->ifa_name; michael@0: // break; michael@0: // } michael@0: // } michael@0: // michael@0: // /* michael@0: // * Get the link-layer address matching the interface name. michael@0: // */ michael@0: // if (ifname != NULL) { michael@0: // for (ifp = ifap; ifp->ifa_next != NULL; ifp = ifp->ifa_next) { michael@0: // if (ifp->ifa_addr->sa_family == AF_LINK michael@0: // && strcmp(ifname, ifp->ifa_name) == 0) { michael@0: // bcopy(ifp->ifa_addr, lladdr, sizeof(struct sockaddr_dl)); michael@0: // found_lladdr = 1; michael@0: // break; michael@0: // } michael@0: // } michael@0: // } michael@0: // michael@0: // freeifaddrs(ifap); michael@0: // michael@0: // if (!found_lladdr) { michael@0: // /* The link-layer address was not found! */ michael@0: // return -1; michael@0: // } else { michael@0: // /* Copy the IP address to the buffer provided by the caller */ michael@0: // bcopy(&ss, ipaddr, ipaddrsize); michael@0: // return 0; michael@0: // } michael@0: //} michael@0: // michael@0: //static int michael@0: //getifaddr2(int af, struct sockaddr *ipaddr, size_t ipaddrsize, michael@0: // struct sockaddr_dl *lladdr) michael@0: //{ michael@0: // struct ifaddrs *ifap, *ifp; michael@0: // char *ifname; michael@0: // int found_lladdr = 0; michael@0: // michael@0: // if (getifaddrs(&ifap) == -1) michael@0: // return -1; michael@0: // michael@0: // /* Walk the list to find an active interface with an IPv4 or IPv6 address */ michael@0: // for (ifp = ifap; ifp->ifa_next != NULL; ifp = ifp->ifa_next) { michael@0: // if (ifp->ifa_flags & (IFF_UP|IFF_RUNNING) michael@0: // && !(ifp->ifa_flags & IFF_LOOPBACK) michael@0: // && ifp->ifa_addr->sa_family == af) { michael@0: // ifname = ifp->ifa_name; michael@0: // bcopy(ifp->ifa_addr, ipaddr, ipaddrsize); michael@0: // break; michael@0: // } michael@0: // } michael@0: // michael@0: // /* Get the matching link-layer address */ michael@0: // for (ifp = ifap; ifp->ifa_next != NULL; ifp = ifp->ifa_next) { michael@0: // if (ifp->ifa_addr->sa_family == AF_LINK michael@0: // && strcmp(ifname, ifp->ifa_name) == 0) { michael@0: // bcopy(ifp->ifa_addr, lladdr, sizeof(struct sockaddr_dl)); michael@0: // found_lladdr = 1; michael@0: // } michael@0: // } michael@0: // michael@0: // freeifaddrs(ifap); michael@0: // michael@0: // if (found_lladdr) michael@0: // return 0; michael@0: // else michael@0: // return -1; michael@0: //} michael@0: michael@0: //char * michael@0: //platGetIPAddr(void) michael@0: //{ michael@0: // struct sockaddr_in inaddr; michael@0: // struct sockaddr_dl lladdr; /* Unused */ michael@0: // michael@0: // /* michael@0: // * XXX We should use getifaddr() but need to figure out how this can be done michael@0: // * (we would need the IP address of the CUCM at this stage). Using michael@0: // * getifaddr2() ATM. michael@0: // */ michael@0: // michael@0: // /* michael@0: // * XXX This will return an IPv4 address. getifaddr() and getifaddr2() can michael@0: // * handle IPv6 addresses properly though. michael@0: // */ michael@0: // michael@0: // if (getifaddr2(AF_INET, (struct sockaddr *) &inaddr, sizeof(inaddr), michael@0: // &lladdr) != 0) michael@0: // return NULL; michael@0: // michael@0: // inet_ntop(AF_INET, &inaddr.sin_addr, netif_ip_addr, IN_ADDR_PLEN); michael@0: // return netif_ip_addr; michael@0: //} michael@0: michael@0: //void michael@0: //platGetMacAddr(char *maddr) michael@0: //{ michael@0: // struct sockaddr_in inaddr; /* Unused */ michael@0: // struct sockaddr_dl lladdr; michael@0: // michael@0: /* michael@0: * XXX Same comment applies (see platGetIPAddr). Additionally, it is just michael@0: * not possible to properly implement platGetIpAddr() and platGetMacAddr() michael@0: * so that the caller has a guarantee that both address come from the same michael@0: * network address. michael@0: */ michael@0: michael@0: // if (getifaddr2(AF_INET, (struct sockaddr *) &inaddr, sizeof(inaddr), michael@0: // &lladdr) != 0) michael@0: // /* XXX */ michael@0: // bzero(maddr, MAC_ADDR_PLEN); michael@0: // michael@0: // eth_macaddr_ntop(&lladdr, maddr, MAC_ADDR_PLEN); michael@0: //} michael@0: