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