⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fad-gifc.c

📁 Windows XP下的抓包程序实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (fd < 0) {		(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,		    "socket: %s", pcap_strerror(errno));		return (-1);	}	/*	 * Start with an 8K buffer, and keep growing the buffer until	 * we have more than "sizeof(ifrp->ifr_name) + MAX_SA_LEN"	 * bytes left over in the buffer or we fail to get the	 * interface list for some reason other than EINVAL (which is	 * presumed here to mean "buffer is too small").	 */	buf_size = 8192;	for (;;) {		buf = malloc(buf_size);		if (buf == NULL) {			(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,			    "malloc: %s", pcap_strerror(errno));			(void)close(fd);			return (-1);		}		ifc.ifc_len = buf_size;		ifc.ifc_buf = buf;		memset(buf, 0, buf_size);		if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0		    && errno != EINVAL) {			(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,			    "SIOCGIFCONF: %s", pcap_strerror(errno));			(void)close(fd);			free(buf);			return (-1);		}		if (ifc.ifc_len < buf_size &&		    (buf_size - ifc.ifc_len) > sizeof(ifrp->ifr_name) + MAX_SA_LEN)			break;		free(buf);		buf_size *= 2;	}	ifrp = (struct ifreq *)buf;	ifend = (struct ifreq *)(buf + ifc.ifc_len);	for (; ifrp < ifend; ifrp = ifnext) {		/*		 * XXX - what if this isn't an IPv4 address?  Can		 * we still get the netmask, etc. with ioctls on		 * an IPv4 socket?		 *		 * The answer is probably platform-dependent, and		 * if the answer is "no" on more than one platform,		 * the way you work around it is probably platform-		 * dependent as well.		 */		n = SA_LEN(&ifrp->ifr_addr) + sizeof(ifrp->ifr_name);		if (n < sizeof(*ifrp))			ifnext = ifrp + 1;		else			ifnext = (struct ifreq *)((char *)ifrp + n);		/*		 * XXX - The 32-bit compatibility layer for Linux on IA-64		 * is slightly broken. It correctly converts the structures		 * to and from kernel land from 64 bit to 32 bit but 		 * doesn't update ifc.ifc_len, leaving it larger than the 		 * amount really used. This means we read off the end 		 * of the buffer and encounter an interface with an 		 * "empty" name. Since this is highly unlikely to ever 		 * occur in a valid case we can just finish looking for 		 * interfaces if we see an empty name.		 */		if (!(*ifrp->ifr_name))			break;		/*		 * Skip entries that begin with "dummy".		 * XXX - what are these?  Is this Linux-specific?		 * Are there platforms on which we shouldn't do this?		 */		if (strncmp(ifrp->ifr_name, "dummy", 5) == 0)			continue;		/*		 * Get the flags for this interface, and skip it if it's		 * not up.		 */		strncpy(ifrflags.ifr_name, ifrp->ifr_name,		    sizeof(ifrflags.ifr_name));		if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifrflags) < 0) {			if (errno == ENXIO)				continue;			(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,			    "SIOCGIFFLAGS: %.*s: %s",			    (int)sizeof(ifrflags.ifr_name),			    ifrflags.ifr_name,			    pcap_strerror(errno));			ret = -1;			break;		}		if (!(ifrflags.ifr_flags & IFF_UP))			continue;		/*		 * Get the netmask for this address on this interface.		 */		strncpy(ifrnetmask.ifr_name, ifrp->ifr_name,		    sizeof(ifrnetmask.ifr_name));		memcpy(&ifrnetmask.ifr_addr, &ifrp->ifr_addr,		    sizeof(ifrnetmask.ifr_addr));		if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifrnetmask) < 0) {			if (errno == EADDRNOTAVAIL) {				/*				 * Not available.				 */				netmask = NULL;				netmask_size = 0;			} else {				(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,				    "SIOCGIFNETMASK: %.*s: %s",				    (int)sizeof(ifrnetmask.ifr_name),				    ifrnetmask.ifr_name,				    pcap_strerror(errno));				ret = -1;				break;			}		} else {			netmask = &ifrnetmask.ifr_addr;			netmask_size = SA_LEN(netmask);		}		/*		 * Get the broadcast address for this address on this		 * interface (if any).		 */		if (ifrflags.ifr_flags & IFF_BROADCAST) {			strncpy(ifrbroadaddr.ifr_name, ifrp->ifr_name,			    sizeof(ifrbroadaddr.ifr_name));			memcpy(&ifrbroadaddr.ifr_addr, &ifrp->ifr_addr,			    sizeof(ifrbroadaddr.ifr_addr));			if (ioctl(fd, SIOCGIFBRDADDR,			    (char *)&ifrbroadaddr) < 0) {				if (errno == EADDRNOTAVAIL) {					/*					 * Not available.					 */					broadaddr = NULL;					broadaddr_size = 0;				} else {					(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,					    "SIOCGIFBRDADDR: %.*s: %s",					    (int)sizeof(ifrbroadaddr.ifr_name),					    ifrbroadaddr.ifr_name,					    pcap_strerror(errno));					ret = -1;					break;				}			} else {				broadaddr = &ifrbroadaddr.ifr_broadaddr;				broadaddr_size = SA_LEN(broadaddr);			}		} else {			/*			 * Not a broadcast interface, so no broadcast			 * address.			 */			broadaddr = NULL;			broadaddr_size = 0;		}		/*		 * Get the destination address for this address on this		 * interface (if any).		 */		if (ifrflags.ifr_flags & IFF_POINTOPOINT) {			strncpy(ifrdstaddr.ifr_name, ifrp->ifr_name,			    sizeof(ifrdstaddr.ifr_name));			memcpy(&ifrdstaddr.ifr_addr, &ifrp->ifr_addr,			    sizeof(ifrdstaddr.ifr_addr));			if (ioctl(fd, SIOCGIFDSTADDR,			    (char *)&ifrdstaddr) < 0) {				if (errno == EADDRNOTAVAIL) {					/*					 * Not available.					 */					dstaddr = NULL;					dstaddr_size = 0;				} else {					(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,					    "SIOCGIFDSTADDR: %.*s: %s",					    (int)sizeof(ifrdstaddr.ifr_name),					    ifrdstaddr.ifr_name,					    pcap_strerror(errno));					ret = -1;					break;				}			} else {				dstaddr = &ifrdstaddr.ifr_dstaddr;				dstaddr_size = SA_LEN(dstaddr);			}		} else {			/*			 * Not a point-to-point interface, so no destination			 * address.			 */			dstaddr = NULL;			dstaddr_size = 0;		}#if defined (HAVE_SOLARIS) || defined (HAVE_HPUX10_20_OR_LATER)		/*		 * If this entry has a colon followed by a number at		 * the end, it's a logical interface.  Those are just		 * the way you assign multiple IP addresses to a real		 * interface, so an entry for a logical interface should		 * be treated like the entry for the real interface;		 * we do that by stripping off the ":" and the number.		 */		p = strchr(ifrp->ifr_name, ':');		if (p != NULL) {			/*			 * We have a ":"; is it followed by a number?			 */			q = p + 1;			while (isdigit((unsigned char)*q))				q++;			if (*q == '\0') {				/*				 * All digits after the ":" until the end.				 * Strip off the ":" and everything after				 * it.				 */				*p = '\0';			}		}#endif		/*		 * Add information for this address to the list.		 */		if (add_addr_to_iflist(&devlist, ifrp->ifr_name,		    ifrflags.ifr_flags, &ifrp->ifr_addr,		    SA_LEN(&ifrp->ifr_addr), netmask, netmask_size,		    broadaddr, broadaddr_size, dstaddr, dstaddr_size,		    errbuf) < 0) {			ret = -1;			break;		}	}	free(buf);#ifdef HAVE_PROC_NET_DEV	if (ret != -1) {		/*		 * We haven't had any errors yet; now read "/proc/net/dev",		 * and add to the list of interfaces all interfaces listed		 * there that we don't already have, because, on Linux,		 * SIOCGIFCONF reports only interfaces with IPv4 addresses,		 * so you need to read "/proc/net/dev" to get the names of		 * the rest of the interfaces.		 */		ret = scan_proc_net_dev(&devlist, fd, errbuf);	}#endif	(void)close(fd);	if (ret != -1) {		/*		 * We haven't had any errors yet; do any platform-specific		 * operations to add devices.		 */		if (pcap_platform_finddevs(&devlist, errbuf) < 0)			ret = -1;	}	if (ret == -1) {		/*		 * We had an error; free the list we've been constructing.		 */		if (devlist != NULL) {			pcap_freealldevs(devlist);			devlist = NULL;		}	}	*alldevsp = devlist;	return (ret);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -