使用netlink方式,监听dhcp客户端的IP地址

当机器联网后,会启动dhcpcd客户端程序获得ip,下面写一个netlink程序,监听

一下所获得的ip地址。代码很简陋,仅仅用于测试使用。

#define WM "eth0"
static int recv_netlink_ip(int fd)
{
	static char buf[512];
	char *devname;
	struct iovec iov = {buf, sizeof(buf) };
	struct sockaddr_nl sa;
	struct msghdr msg = {(void *)&sa, sizeof(sa), &iov, 1, NULL, 0, 0};
	struct nlmsghdr *nlh;
	int len, index;
	struct ifinfomsg *ifi;

	struct ifinfomsg *pstruIF; 
	struct nlmsgerr *pstruError;
	struct rtattr *pstruAttr;
	int nAttrLen;
	struct ifaddrmsg *ifa;
	struct rtattr *rth;
	int rtl;
	char name[IFNAMSIZ];
	uint32_t ipaddr;

	struct rtattr *rta;
	int ret = 0;
	int left;
	static char empty_ip[128];
	len = recvmsg(fd, &msg, 0);
	if (len <= (sizeof(struct nlmsghdr)+sizeof(struct ifinfomsg))) {
		printf("recvmsg(%d), len=%d\n", fd, len);
		goto out;
	}

	left = len;

	nlh = (struct nlmsghdr *)buf;
	while (NLMSG_OK(nlh, left))
	{
		switch(nlh->nlmsg_type)
		{
			case RTM_NEWLINK:
				break;
			case RTM_DELLINK:
				break;
			case RTM_NEWADDR:
				ifa = (struct ifaddrmsg *) NLMSG_DATA (nlh);
				rth = IFA_RTA (ifa);
				rtl = IFA_PAYLOAD (nlh);
				for (;rtl && RTA_OK (rth, rtl); rth = RTA_NEXT (rth,rtl))
				{
					if (rth->rta_type != IFA_LOCAL) continue;
					ipaddr = * ((uint32_t *)RTA_DATA(rth));
					ipaddr = htonl(ipaddr);
					printf ("%s added %X\n",if_indextoname(ifa->ifa_index,name),ipaddr);
					printf("%s is now %d.%d.%d.%d\n",
								name,
								(ipaddr >> 24) & 0xff,
								(ipaddr >> 16) & 0xff,
								(ipaddr >> 8) & 0xff,
								ipaddr & 0xff);
				}

				if(strcmp(WM, if_indextoname(ifa->ifa_index,name)) == 0)
				{
					
				}
				break;  /* ip */
			case RTM_DELADDR:
				ifa = (struct ifaddrmsg *) NLMSG_DATA (nlh);
				rth = IFA_RTA (ifa);
				rtl = IFA_PAYLOAD (nlh);
				for (;rtl && RTA_OK (rth, rtl); rth = RTA_NEXT (rth,rtl))
				{
					if (rth->rta_type != IFA_LOCAL) continue;
					ipaddr = * ((uint32_t *)RTA_DATA(rth));
					ipaddr = htonl(ipaddr);
					printf ("%s added %X\n",if_indextoname(ifa->ifa_index,name),ipaddr);
					printf("%s is now %d.%d.%d.%d\n",
								name,
								(ipaddr >> 24) & 0xff,
								(ipaddr >> 16) & 0xff,
								(ipaddr >> 8) & 0xff,
								ipaddr & 0xff);
				}

				if(strcmp(WM, if_indextoname(ifa->ifa_index,name)) == 0)
				{
				}
				break; /* del ip*/
			case RTM_GETADDR:
				break;
			case NLMSG_DONE:
				break;
			case NLMSG_ERROR:
				pstruError = (struct nlmsgerr *)NLMSG_DATA(nlh);
				printf("error : [%s]\n",strerror(-pstruError -> error));
				break;

		}
		nlh = NLMSG_NEXT(nlh, left);
	}
out:
	return ret;
}


int  check_ip()
{
	int fd;
	struct sockaddr_nl sa;
	int ret;

	fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
	if (fd < 0) 
	{
		return -1;
	}
	memset(&sa, 0, sizeof(sa));
	sa.nl_family = AF_NETLINK;
	sa.nl_groups = RTMGRP_IPV4_IFADDR;
	if (bind(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0)
	{
		close(fd);
		return -1;
	}

	while (1)
	{
		ret = recv_netlink_ip(fd);
		if (ret < 0)
		{
			printf("recv ip break \n");
			break;
		}
	}
	return 0;
}

 
 



猜你喜欢

转载自blog.csdn.net/zhangxu1024/article/details/8935561