fd277e9e0f54b8a5714b5ab98f04862bd556a3c0
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/.
23 struct fwd_addr_list
* fwd_get_addrs(int fd
, int family
)
37 struct nlmsghdr
*nlmp
;
38 struct ifaddrmsg
*rtmp
;
40 struct fwd_addr_list
*head
, *entry
;
43 memset(&req
, 0, sizeof(req
));
44 req
.n
.nlmsg_len
= NLMSG_LENGTH(sizeof(struct ifaddrmsg
));
45 req
.n
.nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ROOT
;
46 req
.n
.nlmsg_type
= RTM_GETADDR
;
47 req
.r
.ifa_family
= family
;
49 rta
= (struct rtattr
*)(((char *)&req
) + NLMSG_ALIGN(req
.n
.nlmsg_len
));
50 rta
->rta_len
= RTA_LENGTH(family
== AF_INET
? 4 : 16);
55 if( send(fd
, &req
, sizeof(req
), 0) <= 0 )
58 /* Receive responses */
59 for( dump_done
= 0; !dump_done
; )
61 if( (offlen
= recv(fd
, buf
, sizeof(buf
), 0)) <= 0 )
65 for(nlmp
= (struct nlmsghdr
*)buf
; offlen
> sizeof(*nlmp
);)
68 if( nlmp
->nlmsg_type
== NLMSG_DONE
)
74 int len
= nlmp
->nlmsg_len
;
75 int req_len
= len
- sizeof(*nlmp
);
77 if( req_len
<0 || len
>offlen
)
80 if( !NLMSG_OK(nlmp
, offlen
) )
83 rtmp
= (struct ifaddrmsg
*) NLMSG_DATA(nlmp
);
84 rtatp
= (struct rtattr
*) IFA_RTA(rtmp
);
86 if( !(entry
= fwd_alloc_ptr(struct fwd_addr_list
)) )
89 entry
->index
= rtmp
->ifa_index
;
90 if_indextoname(rtmp
->ifa_index
, (char *)&entry
->ifname
);
92 rtattrlen
= IFA_PAYLOAD(nlmp
);
94 for( ; RTA_OK(rtatp
, rtattrlen
); rtatp
= RTA_NEXT(rtatp
, rtattrlen
) )
96 if( rtatp
->rta_type
== IFA_ADDRESS
)
98 memcpy(&entry
->ipaddr
.addr
, (char *) RTA_DATA(rtatp
), rtatp
->rta_len
);
99 entry
->ipaddr
.prefix
= rtmp
->ifa_prefixlen
;
100 entry
->family
= family
;
102 else if( rtatp
->rta_type
== IFA_LABEL
)
104 memcpy(&entry
->label
, (char *) RTA_DATA(rtatp
), rtatp
->rta_len
);
111 offlen
-= NLMSG_ALIGN(len
);
112 nlmp
= (struct nlmsghdr
*)((char*)nlmp
+ NLMSG_ALIGN(len
));
121 fwd_free_addrs(head
);
127 void fwd_free_addrs(struct fwd_addr_list
*head
)
129 struct fwd_addr_list
*entry
= head
;
131 while( entry
!= NULL
)
141 struct fwd_addr_list
* fwd_append_addrs(struct fwd_addr_list
*head
, struct fwd_addr_list
*add
)
143 struct fwd_addr_list
*entry
= head
;
145 while( entry
->next
!= NULL
)
148 return (entry
->next
= add
);