ifconfig.c (272448) | ifconfig.c (278080) |
---|---|
1/* 2 * Copyright (c) 1983, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 24 unchanged lines hidden (view full) --- 33 The Regents of the University of California. All rights reserved.\n"; 34#endif /* not lint */ 35 36#ifndef lint 37#if 0 38static char sccsid[] = "@(#)ifconfig.c 8.2 (Berkeley) 2/16/94"; 39#endif 40static const char rcsid[] = | 1/* 2 * Copyright (c) 1983, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 24 unchanged lines hidden (view full) --- 33 The Regents of the University of California. All rights reserved.\n"; 34#endif /* not lint */ 35 36#ifndef lint 37#if 0 38static char sccsid[] = "@(#)ifconfig.c 8.2 (Berkeley) 2/16/94"; 39#endif 40static const char rcsid[] = |
41 "$FreeBSD: head/sbin/ifconfig/ifconfig.c 272448 2014-10-02 20:17:16Z hrs $"; | 41 "$FreeBSD: head/sbin/ifconfig/ifconfig.c 278080 2015-02-02 13:03:04Z vsevolod $"; |
42#endif /* not lint */ 43 44#include <sys/param.h> 45#include <sys/ioctl.h> 46#include <sys/socket.h> 47#include <sys/time.h> 48#include <sys/module.h> 49#include <sys/linker.h> | 42#endif /* not lint */ 43 44#include <sys/param.h> 45#include <sys/ioctl.h> 46#include <sys/socket.h> 47#include <sys/time.h> 48#include <sys/module.h> 49#include <sys/linker.h> |
50#include <sys/queue.h> |
|
50 51#include <net/ethernet.h> 52#include <net/if.h> 53#include <net/if_var.h> 54#include <net/if_dl.h> 55#include <net/if_types.h> 56#include <net/route.h> 57 --- 47 unchanged lines hidden (view full) --- 105static void usage(void); 106 107static struct afswtch *af_getbyname(const char *name); 108static struct afswtch *af_getbyfamily(int af); 109static void af_other_status(int); 110 111static struct option *opts = NULL; 112 | 51 52#include <net/ethernet.h> 53#include <net/if.h> 54#include <net/if_var.h> 55#include <net/if_dl.h> 56#include <net/if_types.h> 57#include <net/route.h> 58 --- 47 unchanged lines hidden (view full) --- 106static void usage(void); 107 108static struct afswtch *af_getbyname(const char *name); 109static struct afswtch *af_getbyfamily(int af); 110static void af_other_status(int); 111 112static struct option *opts = NULL; 113 |
114struct ifa_order_elt { 115 int if_order; 116 int af_orders[255]; 117 struct ifaddrs *ifa; 118 TAILQ_ENTRY(ifa_order_elt) link; 119}; 120 121TAILQ_HEAD(ifa_queue, ifa_order_elt); 122 |
|
113void 114opt_register(struct option *p) 115{ 116 p->next = opts; 117 opts = p; 118} 119 120static void --- 15 unchanged lines hidden (view full) --- 136 " ifconfig interface create\n" 137 " ifconfig -a %s[-d] [-m] [-u] [-v] [address_family]\n" 138 " ifconfig -l [-d] [-u] [address_family]\n" 139 " ifconfig %s[-d] [-m] [-u] [-v]\n", 140 options, options, options); 141 exit(1); 142} 143 | 123void 124opt_register(struct option *p) 125{ 126 p->next = opts; 127 opts = p; 128} 129 130static void --- 15 unchanged lines hidden (view full) --- 146 " ifconfig interface create\n" 147 " ifconfig -a %s[-d] [-m] [-u] [-v] [address_family]\n" 148 " ifconfig -l [-d] [-u] [address_family]\n" 149 " ifconfig %s[-d] [-m] [-u] [-v]\n", 150 options, options, options); 151 exit(1); 152} 153 |
154static int 155calcorders(struct ifaddrs *ifa, struct ifa_queue *q) 156{ 157 unsigned int ord, af, ifa_ord; 158 struct ifaddrs *prev; 159 struct ifa_order_elt *cur; 160 161 prev = NULL; 162 cur = NULL; 163 ord = 0; 164 ifa_ord = 0; 165 166 while (ifa != NULL) { 167 if (prev == NULL || strcmp(ifa->ifa_name, prev->ifa_name) != 0) { 168 cur = calloc(1, sizeof(*cur)); 169 170 if (cur == NULL) 171 return (-1); 172 173 TAILQ_INSERT_TAIL(q, cur, link); 174 cur->if_order = ifa_ord ++; 175 cur->ifa = ifa; 176 ord = 0; 177 } 178 179 if (ifa->ifa_addr) { 180 af = ifa->ifa_addr->sa_family; 181 182 if (af < sizeof(cur->af_orders) / sizeof(cur->af_orders[0]) && 183 cur->af_orders[af] == 0) 184 cur->af_orders[af] = ++ord; 185 } 186 prev = ifa; 187 ifa = ifa->ifa_next; 188 } 189 190 return (0); 191} 192 193static int 194cmpifaddrs(struct ifaddrs *a, struct ifaddrs *b, struct ifa_queue *q) 195{ 196 int ret; 197 unsigned int af1, af2; 198 struct ifa_order_elt *cur, *e1, *e2; 199 200 e1 = e2 = NULL; 201 202 ret = strcmp(a->ifa_name, b->ifa_name); 203 if (ret != 0) { 204 /* We need to find elements corresponding to these different names */ 205 TAILQ_FOREACH(cur, q, link) { 206 if (e1 && e2) 207 break; 208 209 if (strcmp(cur->ifa->ifa_name, a->ifa_name) == 0) 210 e1 = cur; 211 else if (strcmp(cur->ifa->ifa_name, b->ifa_name) == 0) 212 e2 = cur; 213 } 214 215 if (!e1 || !e2) 216 return (0); 217 else 218 return (e1->if_order - e2->if_order); 219 220 } else if (a->ifa_addr != NULL && b->ifa_addr != NULL) { 221 TAILQ_FOREACH(cur, q, link) { 222 if (strcmp(cur->ifa->ifa_name, a->ifa_name) == 0) { 223 e1 = cur; 224 break; 225 } 226 } 227 228 if (!e1) 229 return (0); 230 231 af1 = a->ifa_addr->sa_family; 232 af2 = b->ifa_addr->sa_family; 233 234 if (af1 < sizeof(e1->af_orders) / sizeof(e1->af_orders[0]) && 235 af2 < sizeof(e1->af_orders) / sizeof(e1->af_orders[0])) 236 return (e1->af_orders[af2] - e1->af_orders[af1]); 237 } 238 239 return (0); 240} 241 242static struct ifaddrs * 243sortifaddrs(struct ifaddrs *list, 244 int (*compare)(struct ifaddrs *, struct ifaddrs *, struct ifa_queue *), 245 struct ifa_queue *q) 246{ 247 248 struct ifaddrs *right, *temp, *last, *result, *next, *tail; 249 250 right = list; 251 temp = list; 252 last = list; 253 result = NULL; 254 next = NULL; 255 tail = NULL; 256 257 if (!list || !list->ifa_next) 258 return (list); 259 260 while (temp && temp->ifa_next) { 261 last = right; 262 right = right->ifa_next; 263 temp = temp->ifa_next->ifa_next; 264 } 265 266 last->ifa_next = NULL; 267 268 list = sortifaddrs(list, compare, q); 269 right = sortifaddrs(right, compare, q); 270 271 while (list || right) { 272 273 if (!right) { 274 next = list; 275 list = list->ifa_next; 276 } else if (!list) { 277 next = right; 278 right = right->ifa_next; 279 } else if (compare(list, right, q) <= 0) { 280 next = list; 281 list = list->ifa_next; 282 } else { 283 next = right; 284 right = right->ifa_next; 285 } 286 287 if (!result) 288 result = next; 289 else 290 tail->ifa_next = next; 291 292 tail = next; 293 } 294 295 return (result); 296} 297 |
|
144int 145main(int argc, char *argv[]) 146{ 147 int c, all, namesonly, downonly, uponly; 148 const struct afswtch *afp = NULL; 149 int ifindex; | 298int 299main(int argc, char *argv[]) 300{ 301 int c, all, namesonly, downonly, uponly; 302 const struct afswtch *afp = NULL; 303 int ifindex; |
150 struct ifaddrs *ifap, *ifa; | 304 struct ifaddrs *ifap, *sifap, *ifa; |
151 struct ifreq paifr; 152 const struct sockaddr_dl *sdl; 153 char options[1024], *cp, *namecp = NULL; | 305 struct ifreq paifr; 306 const struct sockaddr_dl *sdl; 307 char options[1024], *cp, *namecp = NULL; |
308 struct ifa_queue q = TAILQ_HEAD_INITIALIZER(q); 309 struct ifa_order_elt *cur, *tmp; |
|
154 const char *ifname; 155 struct option *p; 156 size_t iflen; 157 158 all = downonly = uponly = namesonly = noload = verbose = 0; 159 160 /* Parse leading line options */ 161 strlcpy(options, "adklmnuv", sizeof(options)); --- 118 unchanged lines hidden (view full) --- 280 if (argc > 0) { 281 afp = af_getbyname(*argv); 282 if (afp != NULL) 283 argc--, argv++; 284 } 285 286 if (getifaddrs(&ifap) != 0) 287 err(EXIT_FAILURE, "getifaddrs"); | 310 const char *ifname; 311 struct option *p; 312 size_t iflen; 313 314 all = downonly = uponly = namesonly = noload = verbose = 0; 315 316 /* Parse leading line options */ 317 strlcpy(options, "adklmnuv", sizeof(options)); --- 118 unchanged lines hidden (view full) --- 436 if (argc > 0) { 437 afp = af_getbyname(*argv); 438 if (afp != NULL) 439 argc--, argv++; 440 } 441 442 if (getifaddrs(&ifap) != 0) 443 err(EXIT_FAILURE, "getifaddrs"); |
444 |
|
288 cp = NULL; | 445 cp = NULL; |
446 447 if (calcorders(ifap, &q) != 0) 448 err(EXIT_FAILURE, "calcorders"); 449 450 sifap = sortifaddrs(ifap, cmpifaddrs, &q); 451 452 TAILQ_FOREACH_SAFE(cur, &q, link, tmp) 453 free(cur); 454 |
|
289 ifindex = 0; | 455 ifindex = 0; |
290 for (ifa = ifap; ifa; ifa = ifa->ifa_next) { | 456 for (ifa = sifap; ifa; ifa = ifa->ifa_next) { |
291 memset(&paifr, 0, sizeof(paifr)); 292 strncpy(paifr.ifr_name, ifa->ifa_name, sizeof(paifr.ifr_name)); 293 if (sizeof(paifr.ifr_addr) >= ifa->ifa_addr->sa_len) { 294 memcpy(&paifr.ifr_addr, ifa->ifa_addr, 295 ifa->ifa_addr->sa_len); 296 } 297 298 if (ifname != NULL && strcmp(ifname, ifa->ifa_name) != 0) --- 933 unchanged lines hidden --- | 457 memset(&paifr, 0, sizeof(paifr)); 458 strncpy(paifr.ifr_name, ifa->ifa_name, sizeof(paifr.ifr_name)); 459 if (sizeof(paifr.ifr_addr) >= ifa->ifa_addr->sa_len) { 460 memcpy(&paifr.ifr_addr, ifa->ifa_addr, 461 ifa->ifa_addr->sa_len); 462 } 463 464 if (ifname != NULL && strcmp(ifname, ifa->ifa_name) != 0) --- 933 unchanged lines hidden --- |