当机器联网后,会启动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;
}