On 08/26/2015 01:36 PM, Irrwahn wrote:
[...] Or, even better, you could easily pass the IF name as an additional parameter to the backend (and possily even use it as additional component to construct the interface file names).
An easy way to obtain a list of interface names on Linux is: awk 'NR>2{gsub(/:/,"");print $1}' /proc/net/dev For doing this in pure C, by the "rtnetlink" method, please see attached file, which is based on . Kind regards, Tilman.
/* ifnames - On Linux, list available network interfaces, one by line. gcc -g -o ifnames ifnames.c ./ifnames Based on "nprocnetdev.c": https://gist.github.com/javiermon/43a0b9e1c07abd4b13df (javiermon. "nprocnetdev.c: print proc/net/dev via netlink sockets") Originally based on: http://www.iijlab.net/~jean/iflist.c Reference: http://iijean.blogspot.com/2010/03/howto-get-list-of-network-interfaces-in.html */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <unistd.h> #include <linux/netlink.h> #include <linux/rtnetlink.h> #include <sys/ioctl.h> #include <net/if.h> #include <signal.h> #include <errno.h> #define IFLIST_REPLY_BUFFER 8192 // FIXME: is this defined somewhere? typedef struct nl_req_s nl_req_t; struct nl_req_s { struct nlmsghdr hdr; struct rtgenmsg gen; }; 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("%s\n", (char *) RTA_DATA(attribute)); break; default: break; } } } int main(void) { int fd; struct sockaddr_nl local; struct sockaddr_nl kernel; struct msghdr rtnl_msg; struct iovec io; nl_req_t req; char reply[IFLIST_REPLY_BUFFER]; pid_t pid = getpid(); unsigned int sleep_sec = 0; fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); if(-1 == fd) { fprintf(stderr, "ERROR: socket(): %s\n", strerror(errno)); return -1; } memset(&local, 0, sizeof(local)); local.nl_family = AF_NETLINK; local.nl_pid = pid; local.nl_groups = 0; if(0 > bind(fd, (struct sockaddr *) &local, sizeof(local))) { fprintf(stderr, "ERROR: bind(): %s\n", strerror(errno)); return -1; } int msg_done = 0; memset(&rtnl_msg, 0, sizeof(rtnl_msg)); memset(&kernel, 0, sizeof(kernel)); memset(&req, 0, sizeof(req)); kernel.nl_family = AF_NETLINK; 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 = pid; req.gen.rtgen_family = AF_PACKET; 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); if(sendmsg(fd, (struct msghdr *) &rtnl_msg, 0) < 0) fprintf(stderr, "ERROR: sendmsg(): %s", strerror(errno)); while (!msg_done) { int len; struct nlmsghdr *msg_ptr; struct msghdr rtnl_reply; 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 = IFLIST_REPLY_BUFFER; rtnl_reply.msg_iov = &io; rtnl_reply.msg_iovlen = 1; rtnl_reply.msg_name = &kernel; rtnl_reply.msg_namelen = sizeof(kernel); if ((len = recvmsg(fd, &rtnl_reply, 0)) != 0) { for ( msg_ptr = (struct nlmsghdr *) reply; NLMSG_OK(msg_ptr, len); msg_ptr = NLMSG_NEXT(msg_ptr, len) ) { switch(msg_ptr->nlmsg_type) { case NLMSG_DONE: msg_done = 1; break; case RTM_NEWLINK: rtnl_print_link(msg_ptr); break; default: break; } } } } close(fd); return 0; }
_______________________________________________ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng