route.c (245682) | route.c (253234) |
---|---|
1/* 2 * Copyright (c) 1983, 1989, 1991, 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 --- 26 unchanged lines hidden (view full) --- 35 36#ifndef lint 37#if 0 38static char sccsid[] = "@(#)route.c 8.6 (Berkeley) 4/28/95"; 39#endif 40#endif /* not lint */ 41 42#include <sys/cdefs.h> | 1/* 2 * Copyright (c) 1983, 1989, 1991, 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 --- 26 unchanged lines hidden (view full) --- 35 36#ifndef lint 37#if 0 38static char sccsid[] = "@(#)route.c 8.6 (Berkeley) 4/28/95"; 39#endif 40#endif /* not lint */ 41 42#include <sys/cdefs.h> |
43__FBSDID("$FreeBSD: stable/9/sbin/route/route.c 245682 2013-01-20 07:38:38Z glebius $"); | 43__FBSDID("$FreeBSD: stable/9/sbin/route/route.c 253234 2013-07-12 01:23:41Z hrs $"); |
44 45#include <sys/param.h> 46#include <sys/file.h> 47#include <sys/socket.h> 48#include <sys/ioctl.h> 49#include <sys/sysctl.h> 50#include <sys/types.h> | 44 45#include <sys/param.h> 46#include <sys/file.h> 47#include <sys/socket.h> 48#include <sys/ioctl.h> 49#include <sys/sysctl.h> 50#include <sys/types.h> |
51#include <sys/queue.h> |
|
51 52#include <net/if.h> 53#include <net/route.h> 54#include <net/if_dl.h> 55#include <netinet/in.h> 56#include <netinet/if_ether.h> 57#include <netatalk/at.h> 58#include <arpa/inet.h> --- 13 unchanged lines hidden (view full) --- 72struct keytab { 73 const char *kt_cp; 74 int kt_i; 75} keywords[] = { 76#include "keywords.h" 77 {0, 0} 78}; 79 | 52 53#include <net/if.h> 54#include <net/route.h> 55#include <net/if_dl.h> 56#include <netinet/in.h> 57#include <netinet/if_ether.h> 58#include <netatalk/at.h> 59#include <arpa/inet.h> --- 13 unchanged lines hidden (view full) --- 73struct keytab { 74 const char *kt_cp; 75 int kt_i; 76} keywords[] = { 77#include "keywords.h" 78 {0, 0} 79}; 80 |
80struct ortentry route; | |
81union sockunion { 82 struct sockaddr sa; 83 struct sockaddr_in sin; 84#ifdef INET6 85 struct sockaddr_in6 sin6; 86#endif 87 struct sockaddr_at sat; 88 struct sockaddr_dl sdl; --- 5 unchanged lines hidden (view full) --- 94int pid, rtm_addrs; 95int s; 96int forcehost, forcenet, doflush, nflag, af, qflag, tflag; 97int iflag, verbose, aflen = sizeof (struct sockaddr_in); 98int locking, lockrest, debugonly; 99struct rt_metrics rt_metrics; 100u_long rtm_inits; 101uid_t uid; | 81union sockunion { 82 struct sockaddr sa; 83 struct sockaddr_in sin; 84#ifdef INET6 85 struct sockaddr_in6 sin6; 86#endif 87 struct sockaddr_at sat; 88 struct sockaddr_dl sdl; --- 5 unchanged lines hidden (view full) --- 94int pid, rtm_addrs; 95int s; 96int forcehost, forcenet, doflush, nflag, af, qflag, tflag; 97int iflag, verbose, aflen = sizeof (struct sockaddr_in); 98int locking, lockrest, debugonly; 99struct rt_metrics rt_metrics; 100u_long rtm_inits; 101uid_t uid; |
102static int defaultfib; 103static int numfibs; |
|
102 103static int atalk_aton(const char *, struct at_addr *); 104static char *atalk_ntoa(struct at_addr); 105static void bprintf(FILE *, int, u_char *); 106static void flushroutes(int argc, char *argv[]); | 104 105static int atalk_aton(const char *, struct at_addr *); 106static char *atalk_ntoa(struct at_addr); 107static void bprintf(FILE *, int, u_char *); 108static void flushroutes(int argc, char *argv[]); |
109static int flushroutes_fib(int); |
|
107static int getaddr(int, char *, struct hostent **); 108static int keyword(const char *); 109static void inet_makenetandmask(u_long, struct sockaddr_in *, u_long); 110#ifdef INET6 111static int inet6_makenetandmask(struct sockaddr_in6 *, const char *); 112#endif 113static void interfaces(void); 114static void mask_addr(void); | 110static int getaddr(int, char *, struct hostent **); 111static int keyword(const char *); 112static void inet_makenetandmask(u_long, struct sockaddr_in *, u_long); 113#ifdef INET6 114static int inet6_makenetandmask(struct sockaddr_in6 *, const char *); 115#endif 116static void interfaces(void); 117static void mask_addr(void); |
115static void monitor(void); | 118static void monitor(int, char*[]); |
116static const char *netname(struct sockaddr *); 117static void newroute(int, char **); | 119static const char *netname(struct sockaddr *); 120static void newroute(int, char **); |
121static int newroute_fib(int, char *, int); |
|
118static void pmsg_addrs(char *, int, size_t); 119static void pmsg_common(struct rt_msghdr *, size_t); 120static int prefixlen(const char *); | 122static void pmsg_addrs(char *, int, size_t); 123static void pmsg_common(struct rt_msghdr *, size_t); 124static int prefixlen(const char *); |
121static void print_getmsg(struct rt_msghdr *, int); | 125static void print_getmsg(struct rt_msghdr *, int, int); |
122static void print_rtmsg(struct rt_msghdr *, size_t); 123static const char *routename(struct sockaddr *); | 126static void print_rtmsg(struct rt_msghdr *, size_t); 127static const char *routename(struct sockaddr *); |
124static int rtmsg(int, int); | 128static int rtmsg(int, int, int); |
125static void set_metric(char *, int); | 129static void set_metric(char *, int); |
130static int set_sofib(int); 131static int set_procfib(int); |
|
126static void sockaddr(char *, struct sockaddr *); 127static void sodump(sup, const char *); 128extern char *iso_ntoa(void); 129 | 132static void sockaddr(char *, struct sockaddr *); 133static void sodump(sup, const char *); 134extern char *iso_ntoa(void); 135 |
136struct fibl { 137 TAILQ_ENTRY(fibl) fl_next; 138 139 int fl_num; 140 int fl_error; 141 int fl_errno; 142}; 143TAILQ_HEAD(fibl_head_t, fibl) fibl_head; 144 145static int fiboptlist_csv(const char *, struct fibl_head_t *); 146static int fiboptlist_range(const char *, struct fibl_head_t *); 147 |
|
130static void usage(const char *) __dead2; 131 132void 133usage(const char *cp) 134{ 135 if (cp != NULL) 136 warnx("bad keyword: %s", cp); 137 (void) fprintf(stderr, 138 "usage: route [-dnqtv] command [[modifiers] args]\n"); 139 exit(EX_USAGE); 140 /* NOTREACHED */ 141} 142 143int 144main(int argc, char **argv) 145{ 146 int ch; | 148static void usage(const char *) __dead2; 149 150void 151usage(const char *cp) 152{ 153 if (cp != NULL) 154 warnx("bad keyword: %s", cp); 155 (void) fprintf(stderr, 156 "usage: route [-dnqtv] command [[modifiers] args]\n"); 157 exit(EX_USAGE); 158 /* NOTREACHED */ 159} 160 161int 162main(int argc, char **argv) 163{ 164 int ch; |
165 size_t len; |
|
147 148 if (argc < 2) 149 usage(NULL); 150 151 while ((ch = getopt(argc, argv, "nqdtv")) != -1) 152 switch(ch) { 153 case 'n': 154 nflag = 1; --- 20 unchanged lines hidden (view full) --- 175 pid = getpid(); 176 uid = geteuid(); 177 if (tflag) 178 s = open(_PATH_DEVNULL, O_WRONLY, 0); 179 else 180 s = socket(PF_ROUTE, SOCK_RAW, 0); 181 if (s < 0) 182 err(EX_OSERR, "socket"); | 166 167 if (argc < 2) 168 usage(NULL); 169 170 while ((ch = getopt(argc, argv, "nqdtv")) != -1) 171 switch(ch) { 172 case 'n': 173 nflag = 1; --- 20 unchanged lines hidden (view full) --- 194 pid = getpid(); 195 uid = geteuid(); 196 if (tflag) 197 s = open(_PATH_DEVNULL, O_WRONLY, 0); 198 else 199 s = socket(PF_ROUTE, SOCK_RAW, 0); 200 if (s < 0) 201 err(EX_OSERR, "socket"); |
202 203 len = sizeof(numfibs); 204 if (sysctlbyname("net.fibs", (void *)&numfibs, &len, NULL, 0) == -1) 205 numfibs = -1; 206 207 len = sizeof(defaultfib); 208 if (numfibs != -1 && 209 sysctlbyname("net.my_fibnum", (void *)&defaultfib, &len, NULL, 210 0) == -1) 211 defaultfib = -1; 212 |
|
183 if (*argv != NULL) 184 switch (keyword(*argv)) { 185 case K_GET: 186 case K_SHOW: 187 uid = 0; 188 /* FALLTHROUGH */ 189 190 case K_CHANGE: 191 case K_ADD: 192 case K_DEL: 193 case K_DELETE: 194 newroute(argc, argv); 195 /* NOTREACHED */ 196 197 case K_MONITOR: | 213 if (*argv != NULL) 214 switch (keyword(*argv)) { 215 case K_GET: 216 case K_SHOW: 217 uid = 0; 218 /* FALLTHROUGH */ 219 220 case K_CHANGE: 221 case K_ADD: 222 case K_DEL: 223 case K_DELETE: 224 newroute(argc, argv); 225 /* NOTREACHED */ 226 227 case K_MONITOR: |
198 monitor(); | 228 monitor(argc, argv); |
199 /* NOTREACHED */ 200 201 case K_FLUSH: 202 flushroutes(argc, argv); 203 exit(0); 204 /* NOTREACHED */ 205 } 206 usage(*argv); 207 /* NOTREACHED */ 208} 209 | 229 /* NOTREACHED */ 230 231 case K_FLUSH: 232 flushroutes(argc, argv); 233 exit(0); 234 /* NOTREACHED */ 235 } 236 usage(*argv); 237 /* NOTREACHED */ 238} 239 |
240static int 241set_sofib(int fib) 242{ 243 244 if (fib < 0) 245 return (0); 246 return (setsockopt(s, SOL_SOCKET, SO_SETFIB, (void *)&fib, 247 sizeof(fib))); 248} 249 250static int 251set_procfib(int fib) 252{ 253 254 if (fib < 0) 255 return (0); 256 return (setfib(fib)); 257} 258 259static int 260fiboptlist_range(const char *arg, struct fibl_head_t *flh) 261{ 262 struct fibl *fl; 263 char *str, *token, *endptr; 264 int fib[2], i, error; 265 266 str = strdup(arg); 267 error = 0; 268 i = 0; 269 while ((token = strsep(&str, "-")) != NULL) { 270 switch (i) { 271 case 0: 272 case 1: 273 fib[i] = strtol(token, &endptr, 0); 274 if (*endptr != '\0' || (fib[i] == 0 && 275 (errno == EINVAL || errno == ERANGE))) 276 error = 1; 277 break; 278 default: 279 error = 1; 280 } 281 if (error) 282 goto fiboptlist_range_ret; 283 i++; 284 } 285 if (fib[0] >= fib[1]) { 286 error = 1; 287 goto fiboptlist_range_ret; 288 } 289 for (i = fib[0]; i <= fib[1]; i++) { 290 fl = calloc(1, sizeof(*fl)); 291 if (fl == NULL) { 292 error = 1; 293 goto fiboptlist_range_ret; 294 } 295 fl->fl_num = i; 296 TAILQ_INSERT_TAIL(flh, fl, fl_next); 297 } 298fiboptlist_range_ret: 299 free(str); 300 return (error); 301} 302 303#define ALLSTRLEN 64 304static int 305fiboptlist_csv(const char *arg, struct fibl_head_t *flh) 306{ 307 struct fibl *fl; 308 char *str, *token, *endptr; 309 int fib, error; 310 311 if (strcmp("all", arg) == 0) { 312 str = calloc(1, ALLSTRLEN); 313 if (str == NULL) { 314 error = 1; 315 goto fiboptlist_csv_ret; 316 } 317 if (numfibs > 1) 318 snprintf(str, ALLSTRLEN - 1, "%d-%d", 0, numfibs - 1); 319 else 320 snprintf(str, ALLSTRLEN - 1, "%d", 0); 321 } else if (strcmp("default", arg) == 0) { 322 str = calloc(1, ALLSTRLEN); 323 if (str == NULL) { 324 error = 1; 325 goto fiboptlist_csv_ret; 326 } 327 snprintf(str, ALLSTRLEN - 1, "%d", defaultfib); 328 } else 329 str = strdup(arg); 330 331 error = 0; 332 while ((token = strsep(&str, ",")) != NULL) { 333 if (*token != '-' && strchr(token, '-') != NULL) { 334 error = fiboptlist_range(token, flh); 335 if (error) 336 goto fiboptlist_csv_ret; 337 } else { 338 fib = strtol(token, &endptr, 0); 339 if (*endptr != '\0' || (fib == 0 && 340 (errno == EINVAL || errno == ERANGE))) { 341 error = 1; 342 goto fiboptlist_csv_ret; 343 } 344 fl = calloc(1, sizeof(*fl)); 345 if (fl == NULL) { 346 error = 1; 347 goto fiboptlist_csv_ret; 348 } 349 fl->fl_num = fib; 350 TAILQ_INSERT_TAIL(flh, fl, fl_next); 351 } 352 } 353fiboptlist_csv_ret: 354 free(str); 355 return (error); 356} 357 |
|
210/* 211 * Purge all entries in the routing tables not 212 * associated with network interfaces. 213 */ 214static void 215flushroutes(int argc, char *argv[]) 216{ | 358/* 359 * Purge all entries in the routing tables not 360 * associated with network interfaces. 361 */ 362static void 363flushroutes(int argc, char *argv[]) 364{ |
217 size_t needed; 218 int mib[6], rlen, seqno, count = 0; 219 char *buf, *next, *lim; 220 struct rt_msghdr *rtm; | 365 struct fibl *fl; 366 int error; |
221 222 if (uid != 0 && !debugonly) { 223 errx(EX_NOPERM, "must be root to alter routing table"); 224 } 225 shutdown(s, SHUT_RD); /* Don't want to read back our messages */ | 367 368 if (uid != 0 && !debugonly) { 369 errx(EX_NOPERM, "must be root to alter routing table"); 370 } 371 shutdown(s, SHUT_RD); /* Don't want to read back our messages */ |
226 if (argc > 1) { | 372 373 TAILQ_INIT(&fibl_head); 374 while (argc > 1) { 375 argc--; |
227 argv++; | 376 argv++; |
228 if (argc == 2 && **argv == '-') 229 switch (keyword(*argv + 1)) { 230 case K_INET: 231 af = AF_INET; 232 break; | 377 if (**argv != '-') 378 usage(*argv); 379 switch (keyword(*argv + 1)) { 380 case K_INET: 381 af = AF_INET; 382 break; |
233#ifdef INET6 | 383#ifdef INET6 |
234 case K_INET6: 235 af = AF_INET6; 236 break; | 384 case K_INET6: 385 af = AF_INET6; 386 break; |
237#endif | 387#endif |
238 case K_ATALK: 239 af = AF_APPLETALK; 240 break; 241 case K_LINK: 242 af = AF_LINK; 243 break; 244 default: 245 goto bad; 246 } else 247bad: usage(*argv); | 388 case K_ATALK: 389 af = AF_APPLETALK; 390 break; 391 case K_LINK: 392 af = AF_LINK; 393 break; 394 case K_FIB: 395 if (!--argc) 396 usage(*argv); 397 error = fiboptlist_csv(*++argv, &fibl_head); 398 if (error) 399 usage(*argv); 400 break; 401 default: 402 usage(*argv); 403 } |
248 } | 404 } |
405 if (TAILQ_EMPTY(&fibl_head)) { 406 error = fiboptlist_csv("default", &fibl_head); 407 if (error) 408 errx(EX_OSERR, "fiboptlist_csv failed."); 409 } 410 TAILQ_FOREACH(fl, &fibl_head, fl_next) 411 flushroutes_fib(fl->fl_num); 412} 413 414static int 415flushroutes_fib(int fib) 416{ 417 struct rt_msghdr *rtm; 418 size_t needed; 419 char *buf, *next, *lim; 420 int mib[6], rlen, seqno, count = 0; 421 int error; 422 423 error = set_sofib(fib); 424 error += set_procfib(fib); 425 if (error) { 426 warn("fib number %d is ignored", fib); 427 return (error); 428 } 429 |
|
249retry: 250 mib[0] = CTL_NET; 251 mib[1] = PF_ROUTE; 252 mib[2] = 0; /* protocol */ 253 mib[3] = 0; /* wildcard address family */ 254 mib[4] = NET_RT_DUMP; 255 mib[5] = 0; /* no flags */ 256 if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) --- 41 unchanged lines hidden (view full) --- 298 } 299 seqno++; 300 if (qflag) 301 continue; 302 if (verbose) 303 print_rtmsg(rtm, rlen); 304 else { 305 struct sockaddr *sa = (struct sockaddr *)(rtm + 1); | 430retry: 431 mib[0] = CTL_NET; 432 mib[1] = PF_ROUTE; 433 mib[2] = 0; /* protocol */ 434 mib[3] = 0; /* wildcard address family */ 435 mib[4] = NET_RT_DUMP; 436 mib[5] = 0; /* no flags */ 437 if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) --- 41 unchanged lines hidden (view full) --- 479 } 480 seqno++; 481 if (qflag) 482 continue; 483 if (verbose) 484 print_rtmsg(rtm, rlen); 485 else { 486 struct sockaddr *sa = (struct sockaddr *)(rtm + 1); |
306 (void) printf("%-20.20s ", rtm->rtm_flags & RTF_HOST ? | 487 488 printf("%-20.20s ", rtm->rtm_flags & RTF_HOST ? |
307 routename(sa) : netname(sa)); 308 sa = (struct sockaddr *)(SA_SIZE(sa) + (char *)sa); | 489 routename(sa) : netname(sa)); 490 sa = (struct sockaddr *)(SA_SIZE(sa) + (char *)sa); |
309 (void) printf("%-20.20s ", routename(sa)); 310 (void) printf("done\n"); | 491 printf("%-20.20s ", routename(sa)); 492 if (fib >= 0) 493 printf("-fib %-3d ", fib); 494 printf("done\n"); |
311 } 312 } | 495 } 496 } |
497 return (error); |
|
313} 314 315const char * 316routename(struct sockaddr *sa) 317{ 318 const char *cp; 319 static char line[MAXHOSTNAMELEN + 1]; 320 struct hostent *hp; --- 247 unchanged lines hidden (view full) --- 568 rtm_inits |= flag; 569 if (lockrest || locking) 570 rt_metrics.rmx_locks |= flag; 571 if (locking) 572 locking = 0; 573 *valp = atoi(value); 574} 575 | 498} 499 500const char * 501routename(struct sockaddr *sa) 502{ 503 const char *cp; 504 static char line[MAXHOSTNAMELEN + 1]; 505 struct hostent *hp; --- 247 unchanged lines hidden (view full) --- 753 rtm_inits |= flag; 754 if (lockrest || locking) 755 rt_metrics.rmx_locks |= flag; 756 if (locking) 757 locking = 0; 758 *valp = atoi(value); 759} 760 |
761#define F_ISHOST 0x01 762#define F_FORCENET 0x02 763#define F_FORCEHOST 0x04 764#define F_PROXY 0x08 765#define F_INTERFACE 0x10 766 |
|
576static void 577newroute(int argc, char **argv) 578{ | 767static void 768newroute(int argc, char **argv) 769{ |
770 struct hostent *hp; 771 struct fibl *fl; |
|
579 char *cmd; | 772 char *cmd; |
580 const char *dest = "", *gateway = "", *errmsg; 581 int ishost = 0, proxy = 0, ret, attempts, oerrno, flags = RTF_STATIC; 582 int key; 583 struct hostent *hp = 0; | 773 const char *dest, *gateway, *errmsg; 774 int key, error, flags, nrflags, fibnum; |
584 585 if (uid != 0) { 586 errx(EX_NOPERM, "must be root to alter routing table"); 587 } | 775 776 if (uid != 0) { 777 errx(EX_NOPERM, "must be root to alter routing table"); 778 } |
779 780 dest = NULL; 781 gateway = NULL; 782 flags = RTF_STATIC; 783 nrflags = 0; 784 hp = NULL; 785 TAILQ_INIT(&fibl_head); 786 |
|
588 cmd = argv[0]; 589 if (*cmd != 'g' && *cmd != 's') 590 shutdown(s, SHUT_RD); /* Don't want to read back our messages */ 591 592 while (--argc > 0) { 593 if (**(++argv)== '-') { 594 switch (key = keyword(1 + *argv)) { 595 case K_LINK: --- 15 unchanged lines hidden (view full) --- 611 aflen = sizeof(struct sockaddr_at); 612 break; 613 case K_SA: 614 af = PF_ROUTE; 615 aflen = sizeof(union sockunion); 616 break; 617 case K_IFACE: 618 case K_INTERFACE: | 787 cmd = argv[0]; 788 if (*cmd != 'g' && *cmd != 's') 789 shutdown(s, SHUT_RD); /* Don't want to read back our messages */ 790 791 while (--argc > 0) { 792 if (**(++argv)== '-') { 793 switch (key = keyword(1 + *argv)) { 794 case K_LINK: --- 15 unchanged lines hidden (view full) --- 810 aflen = sizeof(struct sockaddr_at); 811 break; 812 case K_SA: 813 af = PF_ROUTE; 814 aflen = sizeof(union sockunion); 815 break; 816 case K_IFACE: 817 case K_INTERFACE: |
619 iflag++; | 818 nrflags |= F_INTERFACE; |
620 break; 621 case K_NOSTATIC: 622 flags &= ~RTF_STATIC; 623 break; 624 case K_LOCK: 625 locking = 1; 626 break; 627 case K_LOCKREST: 628 lockrest = 1; 629 break; 630 case K_HOST: | 819 break; 820 case K_NOSTATIC: 821 flags &= ~RTF_STATIC; 822 break; 823 case K_LOCK: 824 locking = 1; 825 break; 826 case K_LOCKREST: 827 lockrest = 1; 828 break; 829 case K_HOST: |
631 forcehost++; | 830 nrflags |= F_FORCEHOST; |
632 break; 633 case K_REJECT: 634 flags |= RTF_REJECT; 635 break; 636 case K_BLACKHOLE: 637 flags |= RTF_BLACKHOLE; 638 break; 639 case K_PROTO1: 640 flags |= RTF_PROTO1; 641 break; 642 case K_PROTO2: 643 flags |= RTF_PROTO2; 644 break; 645 case K_PROXY: | 831 break; 832 case K_REJECT: 833 flags |= RTF_REJECT; 834 break; 835 case K_BLACKHOLE: 836 flags |= RTF_BLACKHOLE; 837 break; 838 case K_PROTO1: 839 flags |= RTF_PROTO1; 840 break; 841 case K_PROTO2: 842 flags |= RTF_PROTO2; 843 break; 844 case K_PROXY: |
646 proxy = 1; | 845 nrflags |= F_PROXY; |
647 break; 648 case K_XRESOLVE: 649 flags |= RTF_XRESOLVE; 650 break; 651 case K_STATIC: 652 flags |= RTF_STATIC; 653 break; 654 case K_STICKY: 655 flags |= RTF_STICKY; 656 break; 657 case K_NOSTICK: 658 flags &= ~RTF_STICKY; 659 break; | 846 break; 847 case K_XRESOLVE: 848 flags |= RTF_XRESOLVE; 849 break; 850 case K_STATIC: 851 flags |= RTF_STATIC; 852 break; 853 case K_STICKY: 854 flags |= RTF_STICKY; 855 break; 856 case K_NOSTICK: 857 flags &= ~RTF_STICKY; 858 break; |
859 case K_FIB: 860 if (!--argc) 861 usage(NULL); 862 error = fiboptlist_csv(*++argv, &fibl_head); 863 if (error) 864 usage(NULL); 865 break; |
|
660 case K_IFA: 661 if (!--argc) 662 usage(NULL); 663 (void) getaddr(RTA_IFA, *++argv, 0); 664 break; 665 case K_IFP: 666 if (!--argc) 667 usage(NULL); --- 7 unchanged lines hidden (view full) --- 675 case K_GATEWAY: 676 if (!--argc) 677 usage(NULL); 678 (void) getaddr(RTA_GATEWAY, *++argv, 0); 679 break; 680 case K_DST: 681 if (!--argc) 682 usage(NULL); | 866 case K_IFA: 867 if (!--argc) 868 usage(NULL); 869 (void) getaddr(RTA_IFA, *++argv, 0); 870 break; 871 case K_IFP: 872 if (!--argc) 873 usage(NULL); --- 7 unchanged lines hidden (view full) --- 881 case K_GATEWAY: 882 if (!--argc) 883 usage(NULL); 884 (void) getaddr(RTA_GATEWAY, *++argv, 0); 885 break; 886 case K_DST: 887 if (!--argc) 888 usage(NULL); |
683 ishost = getaddr(RTA_DST, *++argv, &hp); | 889 if (getaddr(RTA_DST, *++argv, &hp)) 890 nrflags |= F_ISHOST; |
684 dest = *argv; 685 break; 686 case K_NETMASK: 687 if (!--argc) 688 usage(NULL); 689 (void) getaddr(RTA_NETMASK, *++argv, 0); 690 /* FALLTHROUGH */ 691 case K_NET: | 891 dest = *argv; 892 break; 893 case K_NETMASK: 894 if (!--argc) 895 usage(NULL); 896 (void) getaddr(RTA_NETMASK, *++argv, 0); 897 /* FALLTHROUGH */ 898 case K_NET: |
692 forcenet++; | 899 nrflags |= F_FORCENET; |
693 break; 694 case K_PREFIXLEN: 695 if (!--argc) 696 usage(NULL); 697 if (prefixlen(*++argv) == -1) { | 900 break; 901 case K_PREFIXLEN: 902 if (!--argc) 903 usage(NULL); 904 if (prefixlen(*++argv) == -1) { |
698 forcenet = 0; 699 ishost = 1; | 905 nrflags &= ~F_FORCENET; 906 nrflags |= F_ISHOST; |
700 } else { | 907 } else { |
701 forcenet = 1; 702 ishost = 0; | 908 nrflags |= F_FORCENET; 909 nrflags &= ~F_ISHOST; |
703 } 704 break; 705 case K_MTU: 706 case K_HOPCOUNT: 707 case K_EXPIRE: 708 case K_RECVPIPE: 709 case K_SENDPIPE: 710 case K_SSTHRESH: --- 5 unchanged lines hidden (view full) --- 716 set_metric(*++argv, key); 717 break; 718 default: 719 usage(1+*argv); 720 } 721 } else { 722 if ((rtm_addrs & RTA_DST) == 0) { 723 dest = *argv; | 910 } 911 break; 912 case K_MTU: 913 case K_HOPCOUNT: 914 case K_EXPIRE: 915 case K_RECVPIPE: 916 case K_SENDPIPE: 917 case K_SSTHRESH: --- 5 unchanged lines hidden (view full) --- 923 set_metric(*++argv, key); 924 break; 925 default: 926 usage(1+*argv); 927 } 928 } else { 929 if ((rtm_addrs & RTA_DST) == 0) { 930 dest = *argv; |
724 ishost = getaddr(RTA_DST, *argv, &hp); | 931 if (getaddr(RTA_DST, *argv, &hp)) 932 nrflags |= F_ISHOST; |
725 } else if ((rtm_addrs & RTA_GATEWAY) == 0) { 726 gateway = *argv; 727 (void) getaddr(RTA_GATEWAY, *argv, &hp); 728 } else { 729 (void) getaddr(RTA_NETMASK, *argv, 0); | 933 } else if ((rtm_addrs & RTA_GATEWAY) == 0) { 934 gateway = *argv; 935 (void) getaddr(RTA_GATEWAY, *argv, &hp); 936 } else { 937 (void) getaddr(RTA_NETMASK, *argv, 0); |
730 forcenet = 1; | 938 nrflags |= F_FORCENET; |
731 } 732 } 733 } | 939 } 940 } 941 } |
734 if (forcehost) { 735 ishost = 1; | 942 943 if (nrflags & F_FORCEHOST) { 944 nrflags |= F_ISHOST; |
736#ifdef INET6 737 if (af == AF_INET6) { 738 rtm_addrs &= ~RTA_NETMASK; 739 memset((void *)&so_mask, 0, sizeof(so_mask)); 740 } 741#endif 742 } | 945#ifdef INET6 946 if (af == AF_INET6) { 947 rtm_addrs &= ~RTA_NETMASK; 948 memset((void *)&so_mask, 0, sizeof(so_mask)); 949 } 950#endif 951 } |
743 if (forcenet) 744 ishost = 0; | 952 if (nrflags & F_FORCENET) 953 nrflags &= ~F_ISHOST; |
745 flags |= RTF_UP; | 954 flags |= RTF_UP; |
746 if (ishost) | 955 if (nrflags & F_ISHOST) |
747 flags |= RTF_HOST; | 956 flags |= RTF_HOST; |
748 if (iflag == 0) | 957 if ((nrflags & F_INTERFACE) == 0) |
749 flags |= RTF_GATEWAY; | 958 flags |= RTF_GATEWAY; |
750 if (proxy) { | 959 if (nrflags & F_PROXY) { |
751 so_dst.sinarp.sin_other = SIN_PROXY; 752 flags |= RTF_ANNOUNCE; 753 } | 960 so_dst.sinarp.sin_other = SIN_PROXY; 961 flags |= RTF_ANNOUNCE; 962 } |
754 for (attempts = 1; ; attempts++) { 755 errno = 0; 756 if ((ret = rtmsg(*cmd, flags)) == 0) 757 break; 758 if (errno != ENETUNREACH && errno != ESRCH) 759 break; 760 if (af == AF_INET && *gateway != '\0' && 761 hp != NULL && hp->h_addr_list[1] != NULL) { 762 hp->h_addr_list++; 763 memmove(&so_gate.sin.sin_addr, hp->h_addr_list[0], 764 MIN((size_t)hp->h_length, 765 sizeof(so_gate.sin.sin_addr))); 766 } else 767 break; | 963 if (dest == NULL) 964 dest = ""; 965 if (gateway == NULL) 966 gateway = ""; 967 968 if (TAILQ_EMPTY(&fibl_head)) { 969 error = fiboptlist_csv("default", &fibl_head); 970 if (error) 971 errx(EX_OSERR, "fiboptlist_csv failed."); |
768 } | 972 } |
973 error = 0; 974 TAILQ_FOREACH(fl, &fibl_head, fl_next) { 975 fl->fl_error = newroute_fib(fl->fl_num, cmd, flags); 976 if (fl->fl_error) 977 fl->fl_errno = errno; 978 error += fl->fl_error; 979 } |
|
769 if (*cmd == 'g' || *cmd == 's') | 980 if (*cmd == 'g' || *cmd == 's') |
770 exit(ret != 0); | 981 exit(error); 982 983 error = 0; |
771 if (!qflag) { | 984 if (!qflag) { |
772 oerrno = errno; 773 (void) printf("%s %s %s", cmd, ishost? "host" : "net", dest); 774 if (*gateway) { 775 (void) printf(": gateway %s", gateway); 776 if (attempts > 1 && ret == 0 && af == AF_INET) 777 (void) printf(" (%s)", 778 inet_ntoa(((struct sockaddr_in *)&route.rt_gateway)->sin_addr)); | 985 fibnum = 0; 986 TAILQ_FOREACH(fl, &fibl_head, fl_next) { 987 if (fl->fl_error == 0) 988 fibnum++; |
779 } | 989 } |
780 if (ret == 0) { 781 (void) printf("\n"); 782 } else { 783 switch (oerrno) { 784 case ESRCH: 785 errmsg = "not in table"; 786 break; 787 case EBUSY: 788 errmsg = "entry in use"; 789 break; 790 case ENOBUFS: 791 errmsg = "not enough memory"; 792 break; 793 case EADDRINUSE: 794 /* handle recursion avoidance in rt_setgate() */ 795 errmsg = "gateway uses the same route"; 796 break; 797 case EEXIST: 798 errmsg = "route already in table"; 799 break; 800 default: 801 errmsg = strerror(oerrno); 802 break; | 990 if (fibnum > 0) { 991 int firstfib = 1; 992 993 printf("%s %s %s", cmd, 994 (nrflags & F_ISHOST) ? "host" : "net", dest); 995 if (*gateway) 996 printf(": gateway %s", gateway); 997 998 if (numfibs > 1) { 999 TAILQ_FOREACH(fl, &fibl_head, fl_next) { 1000 if (fl->fl_error == 0 1001 && fl->fl_num >= 0) { 1002 if (firstfib) { 1003 printf(" fib "); 1004 firstfib = 0; 1005 } 1006 printf("%d", fl->fl_num); 1007 if (fibnum-- > 1) 1008 printf(","); 1009 } 1010 } |
803 } | 1011 } |
804 (void) printf(": %s\n", errmsg); | 1012 printf("\n"); |
805 } | 1013 } |
1014 1015 fibnum = 0; 1016 TAILQ_FOREACH(fl, &fibl_head, fl_next) { 1017 if (fl->fl_error != 0) { 1018 printf("%s %s %s", cmd, (nrflags & F_ISHOST) 1019 ? "host" : "net", dest); 1020 if (*gateway) 1021 printf(": gateway %s", gateway); 1022 1023 if (fl->fl_num >= 0) 1024 printf(" fib %d", fl->fl_num); 1025 1026 switch (fl->fl_errno) { 1027 case ESRCH: 1028 errmsg = "not in table"; 1029 break; 1030 case EBUSY: 1031 errmsg = "entry in use"; 1032 break; 1033 case ENOBUFS: 1034 errmsg = "not enough memory"; 1035 break; 1036 case EADDRINUSE: 1037 /* 1038 * handle recursion avoidance 1039 * in rt_setgate() 1040 */ 1041 errmsg = "gateway uses the same route"; 1042 break; 1043 case EEXIST: 1044 errmsg = "route already in table"; 1045 break; 1046 default: 1047 errmsg = strerror(fl->fl_errno); 1048 break; 1049 } 1050 printf(": %s\n", errmsg); 1051 error = 1; 1052 } 1053 } |
|
806 } | 1054 } |
807 exit(ret != 0); | 1055 exit(error); |
808} 809 | 1056} 1057 |
1058static int 1059newroute_fib(int fib, char *cmd, int flags) 1060{ 1061 int error; 1062 1063 error = set_sofib(fib); 1064 if (error) { 1065 warn("fib number %d is ignored", fib); 1066 return (error); 1067 } 1068 1069 error = rtmsg(*cmd, flags, fib); 1070 return (error); 1071} 1072 |
|
810static void 811inet_makenetandmask(u_long net, struct sockaddr_in *sin, u_long bits) 812{ 813 u_long addr, mask = 0; 814 char *cp; 815 816 rtm_addrs |= RTA_NETMASK; 817 /* --- 342 unchanged lines hidden (view full) --- 1160 lim = buf + needed; 1161 for (next = buf; next < lim; next += rtm->rtm_msglen) { 1162 rtm = (struct rt_msghdr *)next; 1163 print_rtmsg(rtm, rtm->rtm_msglen); 1164 } 1165} 1166 1167static void | 1073static void 1074inet_makenetandmask(u_long net, struct sockaddr_in *sin, u_long bits) 1075{ 1076 u_long addr, mask = 0; 1077 char *cp; 1078 1079 rtm_addrs |= RTA_NETMASK; 1080 /* --- 342 unchanged lines hidden (view full) --- 1423 lim = buf + needed; 1424 for (next = buf; next < lim; next += rtm->rtm_msglen) { 1425 rtm = (struct rt_msghdr *)next; 1426 print_rtmsg(rtm, rtm->rtm_msglen); 1427 } 1428} 1429 1430static void |
1168monitor(void) | 1431monitor(int argc, char *argv[]) |
1169{ | 1432{ |
1170 int n; 1171 char msg[2048]; | 1433 int n, fib, error; 1434 char msg[2048], *endptr; |
1172 | 1435 |
1436 fib = defaultfib; 1437 while (argc > 1) { 1438 argc--; 1439 argv++; 1440 if (**argv != '-') 1441 usage(*argv); 1442 switch (keyword(*argv + 1)) { 1443 case K_FIB: 1444 if (!--argc) 1445 usage(*argv); 1446 fib = strtol(*++argv, &endptr, 0); 1447 if (*endptr != '\0' || (fib == 0 && 1448 (errno == EINVAL || errno == ERANGE))) 1449 usage(*argv); 1450 break; 1451 default: 1452 usage(*argv); 1453 } 1454 } 1455 error = set_sofib(fib); 1456 if (error) 1457 errx(EX_USAGE, "invalid fib number: %d", fib); 1458 |
|
1173 verbose = 1; 1174 if (debugonly) { 1175 interfaces(); 1176 exit(0); 1177 } 1178 for (;;) { 1179 time_t now; 1180 n = read(s, msg, 2048); --- 4 unchanged lines hidden (view full) --- 1185} 1186 1187struct { 1188 struct rt_msghdr m_rtm; 1189 char m_space[512]; 1190} m_rtmsg; 1191 1192static int | 1459 verbose = 1; 1460 if (debugonly) { 1461 interfaces(); 1462 exit(0); 1463 } 1464 for (;;) { 1465 time_t now; 1466 n = read(s, msg, 2048); --- 4 unchanged lines hidden (view full) --- 1471} 1472 1473struct { 1474 struct rt_msghdr m_rtm; 1475 char m_space[512]; 1476} m_rtmsg; 1477 1478static int |
1193rtmsg(int cmd, int flags) | 1479rtmsg(int cmd, int flags, int fib) |
1194{ 1195 static int seq; 1196 int rlen; 1197 char *cp = m_rtmsg.m_space; 1198 int l; 1199 1200#define NEXTADDR(w, u) \ 1201 if (rtm_addrs & (w)) {\ --- 46 unchanged lines hidden (view full) --- 1248 } 1249 if (cmd == RTM_GET) { 1250 do { 1251 l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg)); 1252 } while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid)); 1253 if (l < 0) 1254 warn("read from routing socket"); 1255 else | 1480{ 1481 static int seq; 1482 int rlen; 1483 char *cp = m_rtmsg.m_space; 1484 int l; 1485 1486#define NEXTADDR(w, u) \ 1487 if (rtm_addrs & (w)) {\ --- 46 unchanged lines hidden (view full) --- 1534 } 1535 if (cmd == RTM_GET) { 1536 do { 1537 l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg)); 1538 } while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid)); 1539 if (l < 0) 1540 warn("read from routing socket"); 1541 else |
1256 print_getmsg(&rtm, l); | 1542 print_getmsg(&rtm, l, fib); |
1257 } 1258#undef rtm 1259 return (0); 1260} 1261 1262static void 1263mask_addr(void) 1264{ --- 161 unchanged lines hidden (view full) --- 1426 return; 1427 1428badlen: 1429 (void)printf(errfmt, __func__, msglen); 1430#undef REQUIRE 1431} 1432 1433static void | 1543 } 1544#undef rtm 1545 return (0); 1546} 1547 1548static void 1549mask_addr(void) 1550{ --- 161 unchanged lines hidden (view full) --- 1712 return; 1713 1714badlen: 1715 (void)printf(errfmt, __func__, msglen); 1716#undef REQUIRE 1717} 1718 1719static void |
1434print_getmsg(struct rt_msghdr *rtm, int msglen) | 1720print_getmsg(struct rt_msghdr *rtm, int msglen, int fib) |
1435{ 1436 struct sockaddr *dst = NULL, *gate = NULL, *mask = NULL; 1437 struct sockaddr_dl *ifp = NULL; 1438 struct sockaddr *sa; 1439 char *cp; 1440 int i; 1441 1442 (void) printf(" route to: %s\n", --- 43 unchanged lines hidden (view full) --- 1486 int savenflag = nflag; 1487 1488 nflag = 1; 1489 (void)printf(" mask: %s\n", routename(mask)); 1490 nflag = savenflag; 1491 } 1492 if (gate && rtm->rtm_flags & RTF_GATEWAY) 1493 (void)printf(" gateway: %s\n", routename(gate)); | 1721{ 1722 struct sockaddr *dst = NULL, *gate = NULL, *mask = NULL; 1723 struct sockaddr_dl *ifp = NULL; 1724 struct sockaddr *sa; 1725 char *cp; 1726 int i; 1727 1728 (void) printf(" route to: %s\n", --- 43 unchanged lines hidden (view full) --- 1772 int savenflag = nflag; 1773 1774 nflag = 1; 1775 (void)printf(" mask: %s\n", routename(mask)); 1776 nflag = savenflag; 1777 } 1778 if (gate && rtm->rtm_flags & RTF_GATEWAY) 1779 (void)printf(" gateway: %s\n", routename(gate)); |
1780 if (fib >= 0) 1781 (void)printf(" fib: %u\n", (unsigned int)fib); |
|
1494 if (ifp) 1495 (void)printf(" interface: %.*s\n", 1496 ifp->sdl_nlen, ifp->sdl_data); 1497 (void)printf(" flags: "); 1498 bprintf(stdout, rtm->rtm_flags, routeflags); 1499 1500#define lock(f) ((rtm->rtm_rmx.rmx_locks & __CONCAT(RTV_,f)) ? 'L' : ' ') 1501#define msec(u) (((u) + 500) / 1000) /* usec to msec */ --- 195 unchanged lines hidden --- | 1782 if (ifp) 1783 (void)printf(" interface: %.*s\n", 1784 ifp->sdl_nlen, ifp->sdl_data); 1785 (void)printf(" flags: "); 1786 bprintf(stdout, rtm->rtm_flags, routeflags); 1787 1788#define lock(f) ((rtm->rtm_rmx.rmx_locks & __CONCAT(RTV_,f)) ? 'L' : ' ') 1789#define msec(u) (((u) + 500) / 1000) /* usec to msec */ --- 195 unchanged lines hidden --- |