📄 interface.c
字号:
/* this is for WinNT... */ else if (Method == IPAPI_METHOD) { /* Use of the IPHelper-API here. */ GetIfTable = (GetIfTableProc) GetProcAddress (WSockHandle, "GetIfTable"); if (!GetIfTable) { printf ("GetProcAddress (GetIfTable): %s\n", SYS_ERROR); FreeLibrary (WSockHandle); return; } GetIpAddrTable = (GetIpAddrTableProc) GetProcAddress (WSockHandle, "GetIpAddrTable"); if (!GetIpAddrTable) { printf ("GetProcAddress (GetIpAddrTable): %s\n", SYS_ERROR); FreeLibrary (WSockHandle); return; } ifTableSize = sizeof (MIB_IFTABLE); ifTable = (PMIB_IFTABLE) svz_malloc (ifTableSize); GetIfTable (ifTable, &ifTableSize, FALSE); ifTable = (PMIB_IFTABLE) svz_realloc (ifTable, ifTableSize); if (GetIfTable (ifTable, &ifTableSize, FALSE) != NO_ERROR) { printf ("GetIfTable: %s\n", SYS_ERROR); FreeLibrary (WSockHandle); svz_free (ifTable); return; } ipTableSize = sizeof (MIB_IPADDRTABLE); ipTable = (PMIB_IPADDRTABLE) svz_malloc (ipTableSize); GetIpAddrTable (ipTable, &ipTableSize, FALSE); ipTable = (PMIB_IPADDRTABLE) svz_realloc (ipTable, ipTableSize); if (GetIpAddrTable (ipTable, &ipTableSize, FALSE) != NO_ERROR) { printf ("GetIpAddrTable: %s\n", SYS_ERROR); FreeLibrary (WSockHandle); svz_free (ipTable); svz_free (ifTable); return; } for (n = 0; n < ipTable->dwNumEntries; n++) { for (i = 0; i < ifTable->dwNumEntries; i++) { if (ifTable->table[i].dwIndex == ipTable->table[n].dwIndex) { ifTable->table[i].bDescr[ifTable->table[i].dwDescrLen] = 0; svz_interface_add (ipTable->table[n].dwIndex, (char *) ifTable->table[i].bDescr, ipTable->table[n].dwAddr); break; } } if (i == ifTable->dwNumEntries) { svz_interface_add (ipTable->table[n].dwIndex, NULL, ipTable->table[n].dwAddr); } } svz_free (ipTable); svz_free (ifTable); FreeLibrary (WSockHandle); } else { printf ("Neither IPHlpApi.dll nor WSock32.WsControl found...\n"); }}#else /* not __MINGW32__ *//* * Collect all available network interfaces and put them into the list * @var{svz_interfaces}. This is useful in order to @code{bind()} server * sockets to specific network interfaces. Thus you can make certain * services accessible from "outside" or "inside" a network installation * only. */voidsvz_interface_collect (void){ int numreqs = 16; struct ifconf ifc; struct ifreq *ifr; struct ifreq ifr2; int n; int fd; /* Get a socket out of the Internet Address Family. */ if ((fd = socket (AF_INET, SOCK_STREAM, 0)) < 0) { perror ("socket"); return; } /* Collect information. */ ifc.ifc_buf = NULL; for (;;) { ifc.ifc_len = sizeof (struct ifreq) * numreqs; ifc.ifc_buf = svz_realloc (ifc.ifc_buf, ifc.ifc_len); /* * On newer AIXes we cannot use SIOCGICONF anymore, although it is * present. The data structure returned is bogus. Using OSIOCGIFCONF. */#if defined (OSIOCGIFCONF) if (ioctl (fd, OSIOCGIFCONF, &ifc) < 0) { perror ("OSIOCGIFCONF"); close (fd); svz_free (ifc.ifc_buf); return; }#else /* OSIOCGIFCONF */ if (ioctl (fd, SIOCGIFCONF, &ifc) < 0) { perror ("SIOCGIFCONF"); close (fd); svz_free (ifc.ifc_buf); return; }#endif /* OSIOCGIFCONF */ if ((unsigned) ifc.ifc_len == sizeof (struct ifreq) * numreqs) { /* Assume it overflowed and try again. */ numreqs += 10; continue; } break; } ifr = ifc.ifc_req; for (n = 0; n < ifc.ifc_len; n += sizeof (struct ifreq), ifr++) { /* * On AIX (and perhaps others) you get interfaces that are not AF_INET * from the first `ioctl ()', so filter here again. */#if defined (__FreeBSD__) if ((ifr->ifr_phys & 0xFFFF0000) == 0)#elif defined (__NetBSD__) if (((long) ifr->ifr_data & 0xFFFF0000) != 0)#else if (ifr->ifr_addr.sa_family != AF_INET)#endif continue; strcpy (ifr2.ifr_name, ifr->ifr_name); ifr2.ifr_addr.sa_family = AF_INET; if (ioctl (fd, SIOCGIFADDR, &ifr2) == 0) { static int index = 0; /* * The following cast looks bogus. ifr2.ifr_addr is a * (struct sockaddr), but we know that we deal with a * (struct sockaddr_in) here. Since you cannot cast structures * in C, I cast addresses just to get a (struct sockaddr_in) in * the end ... */#ifdef ifr_ifindex index = ifr->ifr_ifindex;#else index++;#endif svz_interface_add (index, ifr->ifr_name, (*(struct sockaddr_in *) (void *) &ifr2.ifr_addr).sin_addr.s_addr); } } close (fd); svz_free (ifc.ifc_buf);}#endif /* not __MINGW32__ */#else /* not ENABLE_IFLIST */voidsvz_interface_collect (void){ printf ("\n" "Sorry, the list of local interfaces is not available. If you\n" "know how to get such a list on your OS, please contact\n" "Raimund Jacob <raimi@lkcc.org>. Thanks.\n\n");}#endif /* not ENABLE_IFLIST *//* * Print the text representation of all the network interfaces. */voidsvz_interface_list (void){ unsigned long n; svz_interface_t *ifc; printf ("--- list of local interfaces you can start ip services on ---\n"); /* any interfaces at all ? */ if (!svz_interfaces) return; for (n = 0; n < svz_vector_length (svz_interfaces); n++) { ifc = svz_vector_get (svz_interfaces, n); /* interface with description */ if (ifc->description) { printf ("%40s: %s\n", ifc->description, svz_inet_ntoa (ifc->ipaddr)); } else { /* interface with interface # only */ printf ("%31s%09lu: %s\n", "interface # ", ifc->index, svz_inet_ntoa (ifc->ipaddr)); } }}/* * Add a network interface to the current list of known interfaces. Drop * duplicate entries. */intsvz_interface_add (int index, char *desc, unsigned long addr){ char *p; unsigned long n; svz_interface_t *ifc; /* Check if there is such an interface already. */ if (svz_interfaces == NULL) { svz_interfaces = svz_vector_create (sizeof (svz_interface_t)); } else { for (n = 0; n < svz_vector_length (svz_interfaces); n++) { ifc = svz_vector_get (svz_interfaces, n); if (ifc->ipaddr == addr) return -1; } } /* Actually add this interface. */ ifc = svz_malloc (sizeof (svz_interface_t)); ifc->index = index; ifc->ipaddr = addr; ifc->description = svz_strdup (desc); /* Delete trailing white space characters. */ p = ifc->description + strlen (ifc->description) - 1; while (p > ifc->description && (*p == '\n' || *p == '\r' || *p == '\t' || *p == ' ')) *p-- = '\0'; svz_vector_add (svz_interfaces, ifc); svz_free (ifc); return 0;}/* * This function returns the interface structure for the given IP address * @var{addr} if any. Returns @code{NULL} otherwise. */svz_interface_t *svz_interface_get (unsigned long addr){ svz_interface_t *ifc; int n; svz_vector_foreach (svz_interfaces, ifc, n) { if (ifc->ipaddr == addr) return ifc; } return NULL;}/* * The following function returns a network interface structure for a given * interface name (e.g. eth0). If no such interface exists it returns * @code{NULL}. */svz_interface_t *svz_interface_search (char *desc){ svz_interface_t *ifc; int n; svz_vector_foreach (svz_interfaces, ifc, n) if (!strcmp (ifc->description, desc)) return ifc; return NULL;}/* * Free the network interface list. */intsvz_interface_free (void){ unsigned long n; svz_interface_t *ifc; if (svz_interfaces) { svz_vector_foreach (svz_interfaces, ifc, n) { ifc = svz_vector_get (svz_interfaces, n); if (ifc->description) svz_free (ifc->description); } svz_vector_destroy (svz_interfaces); svz_interfaces = NULL; return 0; } return -1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -