-
-
Save jshen28/7acd4eff6b88b91524916a0425e12d0c to your computer and use it in GitHub Desktop.
Netlink programming demo.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <unistd.h> | |
#include <sys/types.h> | |
#include <sys/socket.h> | |
#include <memory.h> | |
#include <linux/types.h> | |
#include <linux/netlink.h> | |
#include <linux/rtnetlink.h> | |
struct nl_req_s { | |
struct nlmsghdr hdr; | |
struct rtgenmsg gen; | |
}; | |
typedef struct nl_req_s nl_req_t; | |
int get_faces() { | |
int fd; | |
fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); | |
struct sockaddr_nl kernel; | |
struct msghdr rtnl_msg; | |
struct iovec io; | |
nl_req_t req; | |
memset(&rtnl_msg, 0, sizeof(rtnl_msg)); | |
memset(&kernel, 0, sizeof(kernel)); | |
memset(&req, 0, sizeof(req)); | |
kernel.nl_family = AF_NETLINK; /* fill-in kernel address (destination) */ | |
req.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg)); | |
req.hdr.nlmsg_type = RTM_GETLINK; | |
req.hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP; | |
req.hdr.nlmsg_seq = 1; | |
req.hdr.nlmsg_pid = getpid(); | |
req.gen.rtgen_family = AF_PACKET; /* no preferred AF, we will get *all* interfaces */ | |
io.iov_base = &req; | |
io.iov_len = req.hdr.nlmsg_len; | |
rtnl_msg.msg_iov = &io; | |
rtnl_msg.msg_iovlen = 1; | |
rtnl_msg.msg_name = &kernel; | |
rtnl_msg.msg_namelen = sizeof(kernel); | |
struct sockaddr_nl local; | |
memset(&local, 0, sizeof(local)); | |
local.nl_family = AF_NETLINK; | |
local.nl_pid = getpid(); /* can be obtained using getpid*/ | |
local.nl_groups = 0; | |
if (bind(fd, (struct sockaddr *) &local, sizeof(local)) < 0) { | |
perror("crap..."); | |
} | |
sendmsg(fd, (struct msghdr *) &rtnl_msg, 0); | |
char reply[1024]; /* a large buffer */ | |
int len; | |
struct nlmsghdr *msg_ptr; /* pointer to current part */ | |
struct msghdr rtnl_reply; /* generic msghdr structure */ | |
struct iovec io_reply; | |
memset(&io_reply, 0, sizeof(io_reply)); | |
memset(&rtnl_reply, 0, sizeof(rtnl_reply)); | |
io.iov_base = reply; | |
io.iov_len = 1024; | |
rtnl_reply.msg_iov = &io; | |
rtnl_reply.msg_iovlen = 1; | |
rtnl_reply.msg_name = &kernel; | |
rtnl_reply.msg_namelen = sizeof(kernel); | |
len = recvmsg(fd, &rtnl_reply, 0); /* read lots of data */ | |
for (msg_ptr = (struct nlmsghdr *) reply; NLMSG_OK(msg_ptr, len); msg_ptr = NLMSG_NEXT(msg_ptr, len)) | |
{ | |
if (msg_ptr->nlmsg_type == RTM_NEWLINK) { | |
rtnl_print_link(msg_ptr); | |
} | |
} | |
return 0; | |
} | |
void rtnl_print_link(struct nlmsghdr *h) | |
{ | |
struct ifinfomsg *iface; | |
struct rtattr *attribute; | |
int len; | |
iface = NLMSG_DATA(h); | |
len = h->nlmsg_len - NLMSG_LENGTH(sizeof(*iface)); | |
for (attribute = IFLA_RTA(iface); RTA_OK(attribute, len); attribute = RTA_NEXT(attribute, len)) | |
{ | |
switch(attribute->rta_type) | |
{ | |
case IFLA_IFNAME: | |
printf("Interface %d : %s\n", iface->ifi_index, (char *) RTA_DATA(attribute)); | |
break; | |
} | |
} | |
} | |
int main() | |
{ | |
get_faces(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment