Deleted Added
full compact
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 ---