2 * fwd - OpenWrt firewall daemon - rtnetlink communication
4 * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org>
6 * The fwd program is free software: you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version 2
8 * as published by the Free Software Foundation.
10 * The fwd program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with the fwd program. If not, see http://www.gnu.org/licenses/.
22 #include "fwd_utils.h"
24 struct fwd_addr * fwd_get_addrs(int fd, int family)
38 struct nlmsghdr *nlmp;
39 struct ifaddrmsg *rtmp;
41 struct fwd_addr *head, *entry;
44 memset(&req, 0, sizeof(req));
45 req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
46 req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT;
47 req.n.nlmsg_type = RTM_GETADDR;
48 req.r.ifa_family = family;
50 rta = (struct rtattr *)(((char *)&req) + NLMSG_ALIGN(req.n.nlmsg_len));
51 rta->rta_len = RTA_LENGTH(family == AF_INET ? 4 : 16);
56 if( send(fd, &req, sizeof(req), 0) <= 0 )
59 /* Receive responses */
60 for( dump_done = 0; !dump_done; )
62 if( (offlen = recv(fd, buf, sizeof(buf), 0)) <= 0 )
66 for(nlmp = (struct nlmsghdr *)buf; offlen > sizeof(*nlmp);)
69 if( nlmp->nlmsg_type == NLMSG_DONE )
75 int len = nlmp->nlmsg_len;
76 int req_len = len - sizeof(*nlmp);
78 if( req_len<0 || len>offlen )
81 if( !NLMSG_OK(nlmp, offlen) )
84 rtmp = (struct ifaddrmsg *) NLMSG_DATA(nlmp);
85 rtatp = (struct rtattr *) IFA_RTA(rtmp);
87 if( !(entry = fwd_alloc_ptr(struct fwd_addr)) )
90 entry->index = rtmp->ifa_index;
91 if_indextoname(rtmp->ifa_index, (char *)&entry->ifname);
93 rtattrlen = IFA_PAYLOAD(nlmp);
95 for( ; RTA_OK(rtatp, rtattrlen); rtatp = RTA_NEXT(rtatp, rtattrlen) )
97 if( rtatp->rta_type == IFA_ADDRESS )
99 memcpy(&entry->ipaddr.addr, (char *) RTA_DATA(rtatp), rtatp->rta_len);
100 entry->ipaddr.prefix = rtmp->ifa_prefixlen;
101 entry->family = family;
103 else if( rtatp->rta_type == IFA_LABEL)
105 memcpy(&entry->label, (char *) RTA_DATA(rtatp), rtatp->rta_len);
112 offlen -= NLMSG_ALIGN(len);
113 nlmp = (struct nlmsghdr*)((char*)nlmp + NLMSG_ALIGN(len));
122 fwd_free_addrs(head);
128 struct fwd_cidr * fwd_lookup_addr(struct fwd_addr *head, const char *ifname)
130 struct fwd_addr *entry;
132 for( entry = head; entry; entry = entry->next )
133 if( !strncmp(entry->ifname, ifname, IFNAMSIZ) )
134 return &entry->ipaddr;
139 void fwd_free_addrs(struct fwd_addr *head)
141 struct fwd_addr *entry = head;
143 while( entry != NULL )
153 struct fwd_addr * fwd_append_addrs(struct fwd_addr *head, struct fwd_addr *add)
155 struct fwd_addr *entry = head;
157 while( entry->next != NULL )
160 return (entry->next = add);