Commit | Line | Data |
---|---|---|
4bec325f | 1 | #ifndef lint |
183ef13b | 2 | static char sccsid[] = "@(#)route.c 4.2 82/08/19"; |
4bec325f BJ |
3 | #endif |
4 | ||
5 | #include <stdio.h> | |
6 | #include <sys/types.h> | |
7 | #include <sys/socket.h> | |
8 | #include <sys/ioctl.h> | |
9 | #include <net/route.h> | |
10 | #include <net/in.h> | |
11 | #include <errno.h> | |
12 | #include <ctype.h> | |
13 | ||
14 | struct rtentry route; | |
15 | int options; | |
16 | int s; | |
17 | struct sockaddr_in sin = { AF_INET }; | |
18 | ||
19 | main(argc, argv) | |
20 | int argc; | |
21 | char *argv[]; | |
22 | { | |
23 | ||
24 | if (argc < 2) | |
25 | printf("usage: route [ cmd ] [ args ]\n"), exit(1); | |
26 | s = socket(SOCK_RAW, 0, 0, options); | |
27 | if (s < 0) { | |
28 | perror("socket"); | |
29 | exit(1); | |
30 | } | |
31 | argc--, argv++; | |
32 | if (strcmp(*argv, "add") == 0) | |
33 | newroute(argc, argv); | |
34 | else if (strcmp(*argv, "delete") == 0) | |
35 | newroute(argc, argv); | |
36 | else if (strcmp(*argv, "change") == 0) | |
37 | changeroute(argc-1, argv+1); | |
38 | else | |
39 | printf("%s: huh?\n", *argv); | |
40 | } | |
41 | ||
42 | newroute(argc, argv) | |
43 | int argc; | |
44 | char *argv[]; | |
45 | { | |
46 | struct sockaddr_in *sin; | |
47 | char *cmd; | |
48 | ||
183ef13b SL |
49 | if (argc < 3 || argc > 4) { |
50 | printf("usage: %s destination gateway [ metric ]\n", argv[0]); | |
4bec325f BJ |
51 | return; |
52 | } | |
183ef13b SL |
53 | cmd = argv[0]; |
54 | getaddr(argv[1], &route.rt_dst); | |
55 | getaddr(argv[2], &route.rt_gateway); | |
4bec325f BJ |
56 | sin = (struct sockaddr_in *)&route.rt_dst; |
57 | route.rt_flags = RTF_UP; | |
183ef13b | 58 | if (in_lnaof(sin->sin_addr) != 0) |
4bec325f | 59 | route.rt_flags |= RTF_HOST; |
183ef13b SL |
60 | if (argc > 3 && atoi(argv[3]) > 0) |
61 | route.rt_flags |= RTF_GATEWAY; | |
62 | printf("%s %x: gateway %x, flags %x\n", cmd, sin->sin_addr, | |
63 | ((struct sockaddr_in *)&route.rt_gateway)->sin_addr, | |
64 | route.rt_flags); | |
4bec325f BJ |
65 | if (ioctl(s, *cmd == 'a' ? SIOCADDRT : SIOCDELRT, (caddr_t)&route)) |
66 | error(cmd); | |
67 | } | |
68 | ||
69 | changeroute(argc, argv) | |
70 | int argc; | |
71 | char *argv[]; | |
72 | { | |
73 | printf("not supported\n"); | |
74 | } | |
75 | ||
76 | error(cmd) | |
77 | char *cmd; | |
78 | { | |
79 | extern int errno; | |
80 | ||
81 | if (errno == ESRCH) | |
82 | fprintf(stderr, "not in table\n"); | |
83 | else if (errno == EBUSY) | |
84 | fprintf(stderr, "entry in use\n"); | |
85 | else if (errno == ENOBUFS) | |
86 | fprintf(stderr, "routing table overflow\n"); | |
87 | else | |
88 | perror(cmd); | |
89 | } | |
90 | ||
91 | getaddr(s, sin) | |
92 | char *s; | |
93 | struct sockaddr_in *sin; | |
94 | { | |
95 | sin->sin_family = AF_INET; | |
96 | if ((sin->sin_addr.s_addr = rhost(&s)) != -1) | |
97 | return; | |
98 | if (!isdigit(*s)) { | |
99 | fprintf(stderr, "%s: unknown host\n", s); | |
100 | exit(1); | |
101 | } | |
102 | sin->sin_addr.s_addr = atoi(s); | |
103 | if (sin->sin_addr.s_addr == -1) { | |
104 | fprintf(stderr, "%s: bad value\n", s); | |
105 | exit(1); | |
106 | } | |
107 | } | |
183ef13b SL |
108 | |
109 | /* | |
110 | * Return the local network address portion of an | |
111 | * internet address; handles class a/b/c network | |
112 | * number formats. | |
113 | */ | |
114 | in_lnaof(in) | |
115 | struct in_addr in; | |
116 | { | |
117 | #if vax || pdp11 | |
118 | #define IN_LNAOF(in) \ | |
119 | (((in).s_addr&IN_CLASSA) == 0 ? (in).s_addr&IN_CLASSA_LNA : \ | |
120 | ((in).s_addr&IN_CLASSB) == 0 ? (in).s_addr&IN_CLASSB_LNA : \ | |
121 | (in).s_addr&IN_CLASSC_LNA) | |
122 | return ((int)htonl((u_long)IN_LNAOF(in))); | |
123 | #else | |
124 | return (IN_LNAOF(in)); | |
125 | #endif | |
126 | } |