summaryrefslogtreecommitdiff
path: root/mcast/common/.svn/text-base/interfaces.c.svn-base
diff options
context:
space:
mode:
Diffstat (limited to 'mcast/common/.svn/text-base/interfaces.c.svn-base')
-rw-r--r--mcast/common/.svn/text-base/interfaces.c.svn-base347
1 files changed, 347 insertions, 0 deletions
diff --git a/mcast/common/.svn/text-base/interfaces.c.svn-base b/mcast/common/.svn/text-base/interfaces.c.svn-base
new file mode 100644
index 0000000..bd19c8d
--- /dev/null
+++ b/mcast/common/.svn/text-base/interfaces.c.svn-base
@@ -0,0 +1,347 @@
+/*
+ * (c) BayCom GmbH, http://www.baycom.de, info@baycom.de
+ *
+ * See the COPYING file for copyright information and
+ * how to reach the author.
+ *
+ */
+
+#include "headers.h"
+
+void int_destroy (struct intnode *intn)
+{
+ dbg ("Destroying interface %s\n", intn->name);
+
+ /* Resetting the MTU to zero disabled the interface */
+ intn->mtu = 0;
+}
+
+struct intnode *int_find (unsigned int ifindex)
+{
+ unsigned int i;
+ for (i = 0; i < g_conf->maxinterfaces; i++) {
+ if(g_conf->ints[i].ifindex == ifindex) {
+ return g_conf->ints+i;
+ }
+ }
+ return NULL;
+}
+
+struct intnode *int_find_name (char *ifname)
+{
+ unsigned int i;
+ for (i = 0; i < g_conf->maxinterfaces; i++) {
+ if (!strcmp (ifname, g_conf->ints[i].name) && g_conf->ints[i].mtu != 0) {
+ return g_conf->ints+i;
+ }
+ }
+ return NULL;
+}
+
+
+struct intnode *int_find_first (void)
+{
+ unsigned int i;
+ for (i = 0; i < g_conf->maxinterfaces; i++) {
+ dbg("int: %d %s\n",i, g_conf->ints[i].name);
+ if (g_conf->ints[i].mtu != 0) {
+ return g_conf->ints+i;
+ }
+ }
+ return NULL;
+}
+
+//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+#if ! (defined WIN32 || defined APPLE) || defined __CYGWIN__
+
+/* Initiliaze interfaces */
+void update_interfaces (struct intnode *intn)
+{
+ struct in6_addr addr;
+
+ FILE *file;
+ unsigned int prefixlen, scope, flags, ifindex;
+ char devname[IFNAMSIZ];
+
+ /* Only update every 5 seconds to avoid rerunning it every packet */
+ if (g_conf->maxinterfaces)
+ return;
+
+ dbg ("Updating Interfaces\n");
+
+ /* Get link local addresses from /proc/net/if_inet6 */
+ file = fopen ("/proc/net/if_inet6", "r");
+
+ /* We can live without it though */
+ if (!file) {
+ err ("Cannot open /proc/net/if_inet6\n");
+ return;
+ }
+
+ char buf[255];
+ /* Format "fe80000000000000029027fffe24bbab 02 0a 20 80 eth0" */
+ while (fgets (buf, sizeof (buf), file)) {
+ if (21 != sscanf (buf, "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx %x %x %x %x %8s", &addr.s6_addr[0], &addr.s6_addr[1], &addr.s6_addr[2], &addr.s6_addr[3], &addr.s6_addr[4], &addr.s6_addr[5], &addr.s6_addr[6], &addr.s6_addr[7], &addr.s6_addr[8], &addr.s6_addr[9], &addr.s6_addr[10], &addr.s6_addr[11], &addr.s6_addr[12], &addr.s6_addr[13], &addr.s6_addr[14], &addr.s6_addr[15], &ifindex, &prefixlen, &scope, &flags, devname)) {
+
+ warn ("/proc/net/if_inet6 in wrong format!\n");
+ continue;
+ }
+ if (!IN6_IS_ADDR_LINKLOCAL (&addr) && (IN6_IS_ADDR_UNSPECIFIED (&addr) || IN6_IS_ADDR_LOOPBACK (&addr) || IN6_IS_ADDR_MULTICAST (&addr))) {
+ continue;
+ }
+
+ if((intn=int_find(ifindex))==NULL) {
+ g_conf->ints=(struct intnode*)realloc(g_conf->ints, sizeof(struct intnode)*(++g_conf->maxinterfaces));
+ if (!g_conf->ints) {
+ err ("Cannot get memory for interface structures.\n");
+ }
+ intn=g_conf->ints+g_conf->maxinterfaces-1;
+ memset(intn, 0, sizeof(struct intnode));
+ }
+#ifdef WIN32
+ // Ugly WINXP workaround
+ if(scope==0x20 && flags==0x80) {
+ intn->mtu=1480;
+ } else {
+ intn->mtu=0;
+ }
+#else
+ intn->ifindex = ifindex;
+ strcpy(intn->name, devname);
+
+ struct ifreq ifreq;
+ int sock;
+ sock = socket (AF_INET6, SOCK_DGRAM, 0);
+ if (sock < 0) {
+ err ("Cannot get socket for setup\n");
+ }
+
+ memcpy (&ifreq.ifr_name, &intn->name, sizeof (ifreq.ifr_name));
+ /* Get the MTU size of this interface */
+ /* We will use that for fragmentation */
+ if (ioctl (sock, SIOCGIFMTU, &ifreq) != 0) {
+ warn ("Cannot get MTU size for %s index %d: %s\n", intn->name, intn->ifindex, strerror (errno));
+ }
+ intn->mtu = ifreq.ifr_mtu;
+
+ /* Get hardware address + type */
+ if (ioctl (sock, SIOCGIFHWADDR, &ifreq) != 0) {
+ warn ("Cannot get hardware address for %s, interface index %d : %s\n", intn->name, intn->ifindex, strerror (errno));
+ }
+ intn->hwaddr = ifreq.ifr_hwaddr;
+ close (sock);
+#endif
+ /* Link Local IPv6 address ? */
+ if (IN6_IS_ADDR_LINKLOCAL (&addr)) {
+ /* Update the linklocal address */
+ intn->linklocal = addr;
+ } else {
+ intn->global = addr;
+ }
+
+ dbg ("Available interface %s index %u hardware %s/%u MTU %d\n", intn->name, intn->ifindex, (intn->hwaddr.sa_family == ARPHRD_ETHER ? "Ethernet" : (intn->hwaddr.sa_family == ARPHRD_SIT ? "sit" : "Unknown")), intn->hwaddr.sa_family, intn->mtu);
+ }
+
+ fclose (file);
+}
+#endif
+#if defined WIN32 && ! defined __CYGWIN__
+
+unsigned int if_nametoindex (const char *ifname)
+{
+ unsigned int ifindex;
+ for (ifindex = 0; ifindex < g_conf->maxinterfaces; ifindex++) {
+ if (!strcmp (ifname, g_conf->ints[ifindex].name) && g_conf->ints[ifindex].mtu != 0) {
+ return g_conf->ints[ifindex].ifindex;
+ }
+ }
+ return 0;
+}
+
+void update_interfaces (struct intnode *intn)
+{
+
+ /* Declare and initialize variables */
+
+ DWORD dwRetVal = 0;
+
+ int i = 0;
+
+ // Set the flags to pass to GetAdaptersAddresses
+ ULONG flags = GAA_FLAG_INCLUDE_PREFIX;
+
+ // default to unspecified address family (both)
+ ULONG family = AF_INET6;
+
+ PIP_ADAPTER_ADDRESSES pAddresses = NULL;
+ ULONG outBufLen = 0;
+
+ PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL;
+ PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL;
+
+ outBufLen = sizeof (IP_ADAPTER_ADDRESSES);
+ pAddresses = (IP_ADAPTER_ADDRESSES *) malloc (outBufLen);
+ if (pAddresses == NULL) {
+ printf ("Memory allocation failed for IP_ADAPTER_ADDRESSES struct\n");
+ exit (1);
+ }
+ // Make an initial call to GetAdaptersAddresses to get the
+ // size needed into the outBufLen variable
+ if (GetAdaptersAddresses (family, flags, NULL, pAddresses, &outBufLen) == ERROR_BUFFER_OVERFLOW) {
+ free (pAddresses);
+ pAddresses = (IP_ADAPTER_ADDRESSES *) malloc (outBufLen);
+ }
+
+ if (pAddresses == NULL) {
+ printf ("Memory allocation failed for IP_ADAPTER_ADDRESSES struct\n");
+ exit (1);
+ }
+
+ dwRetVal = GetAdaptersAddresses (family, flags, NULL, pAddresses, &outBufLen);
+
+ if (dwRetVal == NO_ERROR) {
+ // If successful, output some information from the data we received
+ pCurrAddresses = pAddresses;
+ g_conf->maxinterfaces=0;
+
+ while (pCurrAddresses) {
+
+ if( /* pCurrAddresses->Flags & IP_ADAPTER_IPV6_ENABLED && */ (pCurrAddresses->IfType == IF_TYPE_ETHERNET_CSMACD || pCurrAddresses->IfType == IF_TYPE_IEEE80211) && pCurrAddresses->OperStatus == IfOperStatusUp ) {
+ g_conf->ints=(struct intnode*)realloc(g_conf->ints, sizeof(struct intnode)*(g_conf->maxinterfaces+1));
+ if (!g_conf->ints) {
+ err ("update_interfaces: out of memory\n");
+ }
+ intn=g_conf->ints+g_conf->maxinterfaces;
+ memset(intn, 0, sizeof(struct intnode));
+
+#ifndef __MINGW32__
+ printf ("Interface: %s (%wS)\n", pCurrAddresses->AdapterName, pCurrAddresses->Description);
+ dbg ("\tFriendly name: %wS\n", pCurrAddresses->FriendlyName);
+#else
+ printf ("Interface: %s (%ls)\n", pCurrAddresses->AdapterName, pCurrAddresses->Description);
+ dbg ("\tFriendly name: %ls\n", pCurrAddresses->FriendlyName);
+#endif
+ dbg ("\tFlags: %x\n", pCurrAddresses->Flags);
+ dbg ("\tIfType: %ld\n", pCurrAddresses->IfType);
+ dbg ("\tOperStatus: %ld\n", pCurrAddresses->OperStatus);
+ dbg ("\tMtu: %lu\n", pCurrAddresses->Mtu);
+ dbg ("\tIpv6IfIndex (IPv6 interface): %u\n", pCurrAddresses->Ipv6IfIndex);
+
+ strncpy(intn->name, pCurrAddresses->AdapterName, IFNAMSIZ-1);
+
+ intn->mtu = pCurrAddresses->Mtu;
+ intn->ifindex= pCurrAddresses->Ipv6IfIndex;
+
+ pUnicast = pCurrAddresses->FirstUnicastAddress;
+ if (pUnicast != NULL) {
+ for (i = 0; pUnicast != NULL; i++) {
+ char host[80];
+ inet_ntop (AF_INET6, ((struct sockaddr_in6 *)(pUnicast->Address.lpSockaddr))->sin6_addr.s6_addr, host, sizeof(host));
+ dbg("\tIP:%s LL:%d\n",host, IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6 *)(pUnicast->Address.lpSockaddr))->sin6_addr));
+ if(IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6 *)(pUnicast->Address.lpSockaddr))->sin6_addr)) {
+ intn->linklocal=((struct sockaddr_in6 *)(pUnicast->Address.lpSockaddr))->sin6_addr;
+ } else {
+ intn->global=((struct sockaddr_in6 *)(pUnicast->Address.lpSockaddr))->sin6_addr;
+ }
+ pUnicast = pUnicast->Next;
+ }
+ dbg ("\tNumber of Unicast Addresses: %d\n", i);
+ }
+#ifdef DEBUG
+ if (pCurrAddresses->PhysicalAddressLength != 0) {
+ dbg ("\tPhysical address: ");
+ for (i = 0; i < (int) pCurrAddresses->PhysicalAddressLength; i++) {
+ if (i == (pCurrAddresses->PhysicalAddressLength - 1))
+ printf ("%.2X\n", (int) pCurrAddresses->PhysicalAddress[i]);
+ else
+ printf ("%.2X:", (int) pCurrAddresses->PhysicalAddress[i]);
+ }
+ }
+#endif
+ g_conf->maxinterfaces++;
+ }
+ pCurrAddresses = pCurrAddresses->Next;
+ }
+ }
+
+ free (pAddresses);
+}
+
+#endif
+#ifdef APPLE
+void update_interfaces (struct intnode *intn)
+{
+ struct ifaddrs *myaddrs, *ifa;
+ struct sockaddr_in *s4;
+ struct sockaddr_in6 *s6;
+ int if_index;
+ /*
+ * buf must be big enough for an IPv6 address (e.g.
+ * 3ffe:2fa0:1010:ca22:020a:95ff:fe8a:1cf8)
+ */
+ char buf[64];
+
+ if (getifaddrs(&myaddrs)) {
+ err ("getifaddrs");
+ }
+
+ for (ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next) {
+ if (ifa->ifa_addr == NULL)
+ continue;
+ if ((ifa->ifa_flags & IFF_UP) == 0)
+ continue;
+
+ if_index=if_nametoindex(ifa->ifa_name);
+ dbg("%s(%d): ", ifa->ifa_name,if_index);
+
+ if(!if_index) {
+ warn("cannot get interface index for %s\n",ifa->ifa_name);
+ continue;
+ }
+
+ if((intn=int_find(if_index))==NULL) {
+ g_conf->ints=(struct intnode*)realloc(g_conf->ints, sizeof(struct intnode)*(++g_conf->maxinterfaces));
+ if (!g_conf->ints) {
+ err ("Cannot get memory for interface structures.\n");
+ }
+ intn=g_conf->ints+g_conf->maxinterfaces-1;
+ memset(intn, 0, sizeof(struct intnode));
+ }
+
+ intn->ifindex=if_index;
+ strcpy(intn->name,ifa->ifa_name);
+
+ if(ifa->ifa_addr->sa_family == AF_LINK && ((struct if_data *)ifa->ifa_data)->ifi_type != IFT_LOOP && ifa->ifa_data) {
+ dbg("MTU: %d\n", ((struct if_data *)ifa->ifa_data)->ifi_mtu);
+ intn->mtu=((struct if_data *)ifa->ifa_data)->ifi_mtu;
+ memcpy(&intn->hwaddr, ifa->ifa_addr, sizeof(struct sockaddr_in));
+ }
+
+ if (ifa->ifa_addr->sa_family == AF_INET) {
+ s4 = (struct sockaddr_in *) (ifa->ifa_addr);
+ if (inet_ntop(ifa->ifa_addr->sa_family, (void *) &(s4->sin_addr), buf, sizeof(buf)) == NULL) {
+ warn("%s: inet_ntop failed!\n", ifa->ifa_name);
+ } else {
+ dbg("%s\n", buf);
+ }
+ } else if (ifa->ifa_addr->sa_family == AF_INET6) {
+ s6 = (struct sockaddr_in6 *) (ifa->ifa_addr);
+ /* Link Local IPv6 address ? */
+ if (IN6_IS_ADDR_LINKLOCAL (&s6->sin6_addr)) {
+ /* Update the linklocal address */
+ intn->linklocal = s6->sin6_addr;
+ } else {
+ intn->global = s6->sin6_addr;
+ }
+ if (inet_ntop(ifa->ifa_addr->sa_family, (void *) &(s6->sin6_addr), buf, sizeof(buf)) == NULL) {
+ warn("%s: inet_ntop failed!\n", ifa->ifa_name);
+ } else {
+ dbg("%s\n", buf);
+ }
+ }
+ }
+
+ freeifaddrs(myaddrs);
+}
+
+#endif