Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(161)

Side by Side Diff: fusl/src/network/getifaddrs.c

Issue 1714623002: [fusl] clang-format fusl (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: headers too Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 #define _GNU_SOURCE 1 #define _GNU_SOURCE
2 #include <errno.h> 2 #include <errno.h>
3 #include <string.h> 3 #include <string.h>
4 #include <stdlib.h> 4 #include <stdlib.h>
5 #include <unistd.h> 5 #include <unistd.h>
6 #include <ifaddrs.h> 6 #include <ifaddrs.h>
7 #include <syscall.h> 7 #include <syscall.h>
8 #include <net/if.h> 8 #include <net/if.h>
9 #include <netinet/in.h> 9 #include <netinet/in.h>
10 #include "netlink.h" 10 #include "netlink.h"
11 11
12 #define IFADDRS_HASH_SIZE 64 12 #define IFADDRS_HASH_SIZE 64
13 13
14 /* getifaddrs() reports hardware addresses with PF_PACKET that implies 14 /* getifaddrs() reports hardware addresses with PF_PACKET that implies
15 * struct sockaddr_ll. But e.g. Infiniband socket address length is 15 * struct sockaddr_ll. But e.g. Infiniband socket address length is
16 * longer than sockaddr_ll.ssl_addr[8] can hold. Use this hack struct 16 * longer than sockaddr_ll.ssl_addr[8] can hold. Use this hack struct
17 * to extend ssl_addr - callers should be able to still use it. */ 17 * to extend ssl_addr - callers should be able to still use it. */
18 struct sockaddr_ll_hack { 18 struct sockaddr_ll_hack {
19 » unsigned short sll_family, sll_protocol; 19 unsigned short sll_family, sll_protocol;
20 » int sll_ifindex; 20 int sll_ifindex;
21 » unsigned short sll_hatype; 21 unsigned short sll_hatype;
22 » unsigned char sll_pkttype, sll_halen; 22 unsigned char sll_pkttype, sll_halen;
23 » unsigned char sll_addr[24]; 23 unsigned char sll_addr[24];
24 }; 24 };
25 25
26 union sockany { 26 union sockany {
27 » struct sockaddr sa; 27 struct sockaddr sa;
28 » struct sockaddr_ll_hack ll; 28 struct sockaddr_ll_hack ll;
29 » struct sockaddr_in v4; 29 struct sockaddr_in v4;
30 » struct sockaddr_in6 v6; 30 struct sockaddr_in6 v6;
31 }; 31 };
32 32
33 struct ifaddrs_storage { 33 struct ifaddrs_storage {
34 » struct ifaddrs ifa; 34 struct ifaddrs ifa;
35 » struct ifaddrs_storage *hash_next; 35 struct ifaddrs_storage* hash_next;
36 » union sockany addr, netmask, ifu; 36 union sockany addr, netmask, ifu;
37 » unsigned int index; 37 unsigned int index;
38 » char name[IFNAMSIZ+1]; 38 char name[IFNAMSIZ + 1];
39 }; 39 };
40 40
41 struct ifaddrs_ctx { 41 struct ifaddrs_ctx {
42 struct ifaddrs_storage *first; 42 struct ifaddrs_storage* first;
43 struct ifaddrs_storage *last; 43 struct ifaddrs_storage* last;
44 struct ifaddrs_storage *hash[IFADDRS_HASH_SIZE]; 44 struct ifaddrs_storage* hash[IFADDRS_HASH_SIZE];
45 }; 45 };
46 46
47 void freeifaddrs(struct ifaddrs *ifp) 47 void freeifaddrs(struct ifaddrs* ifp) {
48 { 48 struct ifaddrs* n;
49 struct ifaddrs *n; 49 while (ifp) {
50 while (ifp) { 50 n = ifp->ifa_next;
51 n = ifp->ifa_next; 51 free(ifp);
52 free(ifp); 52 ifp = n;
53 ifp = n; 53 }
54 } 54 }
55 } 55
56 56 static void copy_addr(struct sockaddr** r,
57 static void copy_addr(struct sockaddr **r, int af, union sockany *sa, void *addr , size_t addrlen, int ifindex) 57 int af,
58 { 58 union sockany* sa,
59 uint8_t *dst; 59 void* addr,
60 int len; 60 size_t addrlen,
61 61 int ifindex) {
62 switch (af) { 62 uint8_t* dst;
63 case AF_INET: 63 int len;
64 dst = (uint8_t*) &sa->v4.sin_addr; 64
65 len = 4; 65 switch (af) {
66 break; 66 case AF_INET:
67 case AF_INET6: 67 dst = (uint8_t*)&sa->v4.sin_addr;
68 dst = (uint8_t*) &sa->v6.sin6_addr; 68 len = 4;
69 len = 16; 69 break;
70 if (IN6_IS_ADDR_LINKLOCAL(addr) || IN6_IS_ADDR_MC_LINKLOCAL(addr )) 70 case AF_INET6:
71 sa->v6.sin6_scope_id = ifindex; 71 dst = (uint8_t*)&sa->v6.sin6_addr;
72 break; 72 len = 16;
73 default: 73 if (IN6_IS_ADDR_LINKLOCAL(addr) || IN6_IS_ADDR_MC_LINKLOCAL(addr))
74 return; 74 sa->v6.sin6_scope_id = ifindex;
75 } 75 break;
76 if (addrlen < len) return; 76 default:
77 sa->sa.sa_family = af; 77 return;
78 memcpy(dst, addr, len); 78 }
79 *r = &sa->sa; 79 if (addrlen < len)
80 } 80 return;
81 81 sa->sa.sa_family = af;
82 static void gen_netmask(struct sockaddr **r, int af, union sockany *sa, int pref ixlen) 82 memcpy(dst, addr, len);
83 { 83 *r = &sa->sa;
84 uint8_t addr[16] = {0}; 84 }
85 int i; 85
86 86 static void gen_netmask(struct sockaddr** r,
87 if (prefixlen > 8*sizeof(addr)) prefixlen = 8*sizeof(addr); 87 int af,
88 i = prefixlen / 8; 88 union sockany* sa,
89 memset(addr, 0xff, i); 89 int prefixlen) {
90 if (i < sizeof(addr)) addr[i++] = 0xff << (8 - (prefixlen % 8)); 90 uint8_t addr[16] = {0};
91 copy_addr(r, af, sa, addr, sizeof(addr), 0); 91 int i;
92 } 92
93 93 if (prefixlen > 8 * sizeof(addr))
94 static void copy_lladdr(struct sockaddr **r, union sockany *sa, void *addr, size _t addrlen, int ifindex, unsigned short hatype) 94 prefixlen = 8 * sizeof(addr);
95 { 95 i = prefixlen / 8;
96 if (addrlen > sizeof(sa->ll.sll_addr)) return; 96 memset(addr, 0xff, i);
97 sa->ll.sll_family = AF_PACKET; 97 if (i < sizeof(addr))
98 sa->ll.sll_ifindex = ifindex; 98 addr[i++] = 0xff << (8 - (prefixlen % 8));
99 sa->ll.sll_hatype = hatype; 99 copy_addr(r, af, sa, addr, sizeof(addr), 0);
100 sa->ll.sll_halen = addrlen; 100 }
101 memcpy(sa->ll.sll_addr, addr, addrlen); 101
102 *r = &sa->sa; 102 static void copy_lladdr(struct sockaddr** r,
103 } 103 union sockany* sa,
104 104 void* addr,
105 static int netlink_msg_to_ifaddr(void *pctx, struct nlmsghdr *h) 105 size_t addrlen,
106 { 106 int ifindex,
107 struct ifaddrs_ctx *ctx = pctx; 107 unsigned short hatype) {
108 struct ifaddrs_storage *ifs, *ifs0; 108 if (addrlen > sizeof(sa->ll.sll_addr))
109 struct ifinfomsg *ifi = NLMSG_DATA(h); 109 return;
110 struct ifaddrmsg *ifa = NLMSG_DATA(h); 110 sa->ll.sll_family = AF_PACKET;
111 struct rtattr *rta; 111 sa->ll.sll_ifindex = ifindex;
112 int stats_len = 0; 112 sa->ll.sll_hatype = hatype;
113 113 sa->ll.sll_halen = addrlen;
114 if (h->nlmsg_type == RTM_NEWLINK) { 114 memcpy(sa->ll.sll_addr, addr, addrlen);
115 for (rta = NLMSG_RTA(h, sizeof(*ifi)); NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta)) { 115 *r = &sa->sa;
116 if (rta->rta_type != IFLA_STATS) continue; 116 }
117 stats_len = RTA_DATALEN(rta); 117
118 break; 118 static int netlink_msg_to_ifaddr(void* pctx, struct nlmsghdr* h) {
119 } 119 struct ifaddrs_ctx* ctx = pctx;
120 } else { 120 struct ifaddrs_storage *ifs, *ifs0;
121 for (ifs0 = ctx->hash[ifa->ifa_index % IFADDRS_HASH_SIZE]; ifs0; ifs0 = ifs0->hash_next) 121 struct ifinfomsg* ifi = NLMSG_DATA(h);
122 if (ifs0->index == ifa->ifa_index) 122 struct ifaddrmsg* ifa = NLMSG_DATA(h);
123 break; 123 struct rtattr* rta;
124 if (!ifs0) return 0; 124 int stats_len = 0;
125 } 125
126 126 if (h->nlmsg_type == RTM_NEWLINK) {
127 ifs = calloc(1, sizeof(struct ifaddrs_storage) + stats_len); 127 for (rta = NLMSG_RTA(h, sizeof(*ifi)); NLMSG_RTAOK(rta, h);
128 if (ifs == 0) return -1; 128 rta = RTA_NEXT(rta)) {
129 129 if (rta->rta_type != IFLA_STATS)
130 if (h->nlmsg_type == RTM_NEWLINK) { 130 continue;
131 ifs->index = ifi->ifi_index; 131 stats_len = RTA_DATALEN(rta);
132 ifs->ifa.ifa_flags = ifi->ifi_flags; 132 break;
133 133 }
134 for (rta = NLMSG_RTA(h, sizeof(*ifi)); NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta)) { 134 } else {
135 switch (rta->rta_type) { 135 for (ifs0 = ctx->hash[ifa->ifa_index % IFADDRS_HASH_SIZE]; ifs0;
136 case IFLA_IFNAME: 136 ifs0 = ifs0->hash_next)
137 if (RTA_DATALEN(rta) < sizeof(ifs->name)) { 137 if (ifs0->index == ifa->ifa_index)
138 memcpy(ifs->name, RTA_DATA(rta), RTA_DAT ALEN(rta)); 138 break;
139 ifs->ifa.ifa_name = ifs->name; 139 if (!ifs0)
140 } 140 return 0;
141 break; 141 }
142 case IFLA_ADDRESS: 142
143 copy_lladdr(&ifs->ifa.ifa_addr, &ifs->addr, RTA_ DATA(rta), RTA_DATALEN(rta), ifi->ifi_index, ifi->ifi_type); 143 ifs = calloc(1, sizeof(struct ifaddrs_storage) + stats_len);
144 break; 144 if (ifs == 0)
145 case IFLA_BROADCAST: 145 return -1;
146 copy_lladdr(&ifs->ifa.ifa_broadaddr, &ifs->ifu, RTA_DATA(rta), RTA_DATALEN(rta), ifi->ifi_index, ifi->ifi_type); 146
147 break; 147 if (h->nlmsg_type == RTM_NEWLINK) {
148 case IFLA_STATS: 148 ifs->index = ifi->ifi_index;
149 ifs->ifa.ifa_data = (void*)(ifs+1); 149 ifs->ifa.ifa_flags = ifi->ifi_flags;
150 memcpy(ifs->ifa.ifa_data, RTA_DATA(rta), RTA_DAT ALEN(rta)); 150
151 break; 151 for (rta = NLMSG_RTA(h, sizeof(*ifi)); NLMSG_RTAOK(rta, h);
152 } 152 rta = RTA_NEXT(rta)) {
153 } 153 switch (rta->rta_type) {
154 if (ifs->ifa.ifa_name) { 154 case IFLA_IFNAME:
155 unsigned int bucket = ifs->index % IFADDRS_HASH_SIZE; 155 if (RTA_DATALEN(rta) < sizeof(ifs->name)) {
156 ifs->hash_next = ctx->hash[bucket]; 156 memcpy(ifs->name, RTA_DATA(rta), RTA_DATALEN(rta));
157 ctx->hash[bucket] = ifs; 157 ifs->ifa.ifa_name = ifs->name;
158 } 158 }
159 } else { 159 break;
160 ifs->ifa.ifa_name = ifs0->ifa.ifa_name; 160 case IFLA_ADDRESS:
161 ifs->ifa.ifa_flags = ifs0->ifa.ifa_flags; 161 copy_lladdr(&ifs->ifa.ifa_addr, &ifs->addr, RTA_DATA(rta),
162 for (rta = NLMSG_RTA(h, sizeof(*ifa)); NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta)) { 162 RTA_DATALEN(rta), ifi->ifi_index, ifi->ifi_type);
163 switch (rta->rta_type) { 163 break;
164 case IFA_ADDRESS: 164 case IFLA_BROADCAST:
165 /* If ifa_addr is already set we, received an IF A_LOCAL before 165 copy_lladdr(&ifs->ifa.ifa_broadaddr, &ifs->ifu, RTA_DATA(rta),
166 * so treat this as destination address */ 166 RTA_DATALEN(rta), ifi->ifi_index, ifi->ifi_type);
167 if (ifs->ifa.ifa_addr) 167 break;
168 copy_addr(&ifs->ifa.ifa_dstaddr, ifa->if a_family, &ifs->ifu, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index); 168 case IFLA_STATS:
169 else 169 ifs->ifa.ifa_data = (void*)(ifs + 1);
170 copy_addr(&ifs->ifa.ifa_addr, ifa->ifa_f amily, &ifs->addr, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index); 170 memcpy(ifs->ifa.ifa_data, RTA_DATA(rta), RTA_DATALEN(rta));
171 break; 171 break;
172 case IFA_BROADCAST: 172 }
173 copy_addr(&ifs->ifa.ifa_broadaddr, ifa->ifa_fami ly, &ifs->ifu, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index); 173 }
174 break; 174 if (ifs->ifa.ifa_name) {
175 case IFA_LOCAL: 175 unsigned int bucket = ifs->index % IFADDRS_HASH_SIZE;
176 /* If ifa_addr is set and we get IFA_LOCAL, assu me we have 176 ifs->hash_next = ctx->hash[bucket];
177 * a point-to-point network. Move address to cor rect field. */ 177 ctx->hash[bucket] = ifs;
178 if (ifs->ifa.ifa_addr) { 178 }
179 ifs->ifu = ifs->addr; 179 } else {
180 ifs->ifa.ifa_dstaddr = &ifs->ifu.sa; 180 ifs->ifa.ifa_name = ifs0->ifa.ifa_name;
181 memset(&ifs->addr, 0, sizeof(ifs->addr)) ; 181 ifs->ifa.ifa_flags = ifs0->ifa.ifa_flags;
182 } 182 for (rta = NLMSG_RTA(h, sizeof(*ifa)); NLMSG_RTAOK(rta, h);
183 copy_addr(&ifs->ifa.ifa_addr, ifa->ifa_family, & ifs->addr, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index); 183 rta = RTA_NEXT(rta)) {
184 break; 184 switch (rta->rta_type) {
185 case IFA_LABEL: 185 case IFA_ADDRESS:
186 if (RTA_DATALEN(rta) < sizeof(ifs->name)) { 186 /* If ifa_addr is already set we, received an IFA_LOCAL before
187 memcpy(ifs->name, RTA_DATA(rta), RTA_DAT ALEN(rta)); 187 * so treat this as destination address */
188 ifs->ifa.ifa_name = ifs->name; 188 if (ifs->ifa.ifa_addr)
189 } 189 copy_addr(&ifs->ifa.ifa_dstaddr, ifa->ifa_family, &ifs->ifu,
190 break; 190 RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
191 } 191 else
192 } 192 copy_addr(&ifs->ifa.ifa_addr, ifa->ifa_family, &ifs->addr,
193 if (ifs->ifa.ifa_addr) 193 RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
194 gen_netmask(&ifs->ifa.ifa_netmask, ifa->ifa_family, &ifs ->netmask, ifa->ifa_prefixlen); 194 break;
195 } 195 case IFA_BROADCAST:
196 196 copy_addr(&ifs->ifa.ifa_broadaddr, ifa->ifa_family, &ifs->ifu,
197 if (ifs->ifa.ifa_name) { 197 RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
198 if (!ctx->first) ctx->first = ifs; 198 break;
199 if (ctx->last) ctx->last->ifa.ifa_next = &ifs->ifa; 199 case IFA_LOCAL:
200 ctx->last = ifs; 200 /* If ifa_addr is set and we get IFA_LOCAL, assume we have
201 } else { 201 * a point-to-point network. Move address to correct field. */
202 free(ifs); 202 if (ifs->ifa.ifa_addr) {
203 } 203 ifs->ifu = ifs->addr;
204 return 0; 204 ifs->ifa.ifa_dstaddr = &ifs->ifu.sa;
205 } 205 memset(&ifs->addr, 0, sizeof(ifs->addr));
206 206 }
207 int getifaddrs(struct ifaddrs **ifap) 207 copy_addr(&ifs->ifa.ifa_addr, ifa->ifa_family, &ifs->addr,
208 { 208 RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
209 struct ifaddrs_ctx _ctx, *ctx = &_ctx; 209 break;
210 int r; 210 case IFA_LABEL:
211 memset(ctx, 0, sizeof *ctx); 211 if (RTA_DATALEN(rta) < sizeof(ifs->name)) {
212 r = __rtnetlink_enumerate(AF_UNSPEC, AF_UNSPEC, netlink_msg_to_ifaddr, c tx); 212 memcpy(ifs->name, RTA_DATA(rta), RTA_DATALEN(rta));
213 if (r == 0) *ifap = &ctx->first->ifa; 213 ifs->ifa.ifa_name = ifs->name;
214 else freeifaddrs(&ctx->first->ifa); 214 }
215 return r; 215 break;
216 } 216 }
217 }
218 if (ifs->ifa.ifa_addr)
219 gen_netmask(&ifs->ifa.ifa_netmask, ifa->ifa_family, &ifs->netmask,
220 ifa->ifa_prefixlen);
221 }
222
223 if (ifs->ifa.ifa_name) {
224 if (!ctx->first)
225 ctx->first = ifs;
226 if (ctx->last)
227 ctx->last->ifa.ifa_next = &ifs->ifa;
228 ctx->last = ifs;
229 } else {
230 free(ifs);
231 }
232 return 0;
233 }
234
235 int getifaddrs(struct ifaddrs** ifap) {
236 struct ifaddrs_ctx _ctx, *ctx = &_ctx;
237 int r;
238 memset(ctx, 0, sizeof *ctx);
239 r = __rtnetlink_enumerate(AF_UNSPEC, AF_UNSPEC, netlink_msg_to_ifaddr, ctx);
240 if (r == 0)
241 *ifap = &ctx->first->ifa;
242 else
243 freeifaddrs(&ctx->first->ifa);
244 return r;
245 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698