未完


nmap 路由解析

一、获取系统中所有的网络接口的方法

方法1.读取/proc/net/dev

intf_loop(intf_t *intf, intf_handler callback, void *arg)//按行读取/proc/net/dev,来获取接口名
{
	FILE *fp;
	struct intf_entry *entry;
	char *p, buf[BUFSIZ], ebuf[BUFSIZ];
	int ret;
	
	if ((fp = fopen(PROC_DEV_FILE, "r")) == NULL)//#define PROC_DEV_FILE    "/proc/net/dev"
		return (-1);	
	...

	while (fgets(buf, sizeof(buf), fp) != NULL) { //按行读取/proc/net/dev
		if ((p = strchr(buf, ':')) == NULL)  //遇到:,则保存指针
			continue;
		*p = '\0';                             //在原先‘:‘ 的位置,存入'\0',截断字符串
		for (p = buf; *p == ' '; p++)         //去掉多余的空格
			;
		}
		if (_intf_get_noalias(intf, entry) < 0) {
			ret = -1;
			break;
		}
		....
	
	return (ret);
}

写一段小程序,理解这里的字符串截取

   char buf[] = "123:456";
    char *p;
    p = strchr(buf,':');
    *p = '\0';
    printf("buf is %s\n",buf);

输出结果buf is 123


方法2、利用ioctl

int
intf_loop(intf_t *intf, intf_handler callback, void *arg)
{
        struct intf_entry *entry;
        struct ifreq *ifr, *lifr, *pifr;
        char *p, ebuf[BUFSIZ];
        int ret;

        entry = (struct intf_entry *)ebuf;

        intf->ifc.ifc_buf = (caddr_t)intf->ifcbuf;
        intf->ifc.ifc_len = sizeof(intf->ifcbuf);
        
        if (ioctl(intf->fd, SIOCGIFCONF, &intf->ifc) < 0)
                return (-1);

        pifr = NULL;
        lifr = (struct ifreq *)&intf->ifc.ifc_buf[intf->ifc.ifc_len];//指向ifc.ifc_buf数组的最后位置
        
        for (ifr = intf->ifc.ifc_req; ifr < lifr; ifr = NEXTIFR(ifr)) {//指针的增加,
        strcmp(ifr->ifr_name, pifr->ifr_name);

这里,使用指针直接增加。看到过两种:

上面是一种,是

ifr->ifr_addr +max(ifr->ifr_addr.sa_len, sizeof(struct sockaddr))

是直接用ip地址位置 + ip地址长度。

其中max因为有ipv4  ipv6两种,其中,ipv4的sa_len和sizeof(struct sockaddr)是一样大的,而ipv6的 sa_len >  sizeof(struct sockaddr)

第二种,是ifr +ifr_name长度+ ip 地址长度

for( ifr = ifc.ifc_req; ifr < buf +ifc.ifc_len; )
{
    ifr +=sizeof(ifr->ifr_name)+max(ifr->ifr_addr.sa_len, sizeof(struct sockaddr));
}

这两种方法,试过总出问题,并且提示sockaddr没有sa_len成员

第三种是直接计数,这中方法是要点是 1.struct ifreq *buf;  2.buf[i].ifr_name

struct ifreq *buf;
    if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
        return -1;
    buf = malloc(10*sizeof(struct ifreq));
    memset(buf, 0 ,10*sizeof(struct ifreq));
    ifc.ifc_len = 10 *sizeof(struct ifreq);
    ifc.ifc_req = buf;
    
    ioctl(fd,SIOCGIFCONF, &ifc);
    lifr = (struct ifreq*)&ifc.ifc_buf[ifc.ifc_len];
    count = ifc.ifc_len/(sizeof(struct ifreq));
    
    for(i=0; i< count;i++)
    {

        printf("intf %s\n",buf[i].ifr_name);
    }
    close(fd);


_intf_get_noalias(intf_t *intf, struct intf_entry *entry)
{
	struct ifreq ifr;

	/* Get interface index. */
	entry->intf_index = if_nametoindex(entry->intf_name);//通过接口名获得接口索引
	if (entry->intf_index == 0)
		return (-1);

	strlcpy(ifr.ifr_name, entry->intf_name, sizeof(ifr.ifr_name));

	/* Get interface flags. */
	if (ioctl(intf->fd, SIOCGIFFLAGS, &ifr) < 0)
		return (-1);
	
	entry->intf_flags = intf_iff_to_flags(ifr.ifr_flags);
	_intf_set_type(entry);
	
	/* Get interface MTU. */
#ifdef SIOCGIFMTU
	if (ioctl(intf->fd, SIOCGIFMTU, &ifr) < 0)
#endif
		return (-1);
	entry->intf_mtu = ifr.ifr_mtu;

	entry->intf_addr.addr_type = entry->intf_dst_addr.addr_type =
	    entry->intf_link_addr.addr_type = ADDR_TYPE_NONE;
	
	/* Get primary interface address. */
	if (ioctl(intf->fd, SIOCGIFADDR, &ifr) == 0) {
		addr_ston(&ifr.ifr_addr, &entry->intf_addr);
		if (ioctl(intf->fd, SIOCGIFNETMASK, &ifr) < 0)
			return (-1);
		addr_stob(&ifr.ifr_addr, &entry->intf_addr.addr_bits);
	}
	/* Get other addresses. */
	if (entry->intf_type == INTF_TYPE_TUN) {
		if (ioctl(intf->fd, SIOCGIFDSTADDR, &ifr) == 0) {
			if (addr_ston(&ifr.ifr_addr,
			    &entry->intf_dst_addr) < 0)
				return (-1);
		}
	} else if (entry->intf_type == INTF_TYPE_ETH) {
#if defined(SIOCGIFHWADDR)
		if (ioctl(intf->fd, SIOCGIFHWADDR, &ifr) < 0)
			return (-1);
		if (addr_ston(&ifr.ifr_addr, &entry->intf_link_addr) < 0)
			return (-1);
#elif defined(SIOCRPHYSADDR)
		/* Tru64 */
		struct ifdevea *ifd = (struct ifdevea *)


size_t
strlcpy(dst, src, siz)
	char *dst;
	const char *src;
	size_t siz;
{
	register char *d = dst;
	register const char *s = src;
	register size_t n = siz;

	/* Copy as many bytes as will fit */
	if (n != 0 && --n != 0) {                //判断n是否为0,或1,同时这样的--n也为字符串末尾的'\0'空出位置
		do {
			if ((*d++ = *s++) == 0)
				break;
		} while (--n != 0);
	}

	/* Not enough room in dst, add NUL and traverse rest of src */
	if (n == 0) {
		if (siz != 0)
			*d = '\0';		/* NUL-terminate dst */
		while (*s++)
			;
	}

	return(s - src - 1);	/* count does not include NUL */
}

猜你喜欢

转载自blog.csdn.net/maryfei/article/details/80259759
今日推荐