|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)route.c 4.8 (Berkeley) 83/08/21";
3: #endif
4:
5: #include <sys/types.h>
6: #include <sys/socket.h>
7: #include <sys/ioctl.h>
8: #include <sys/mbuf.h>
9:
10: #define KERNEL
11: #include <net/route.h>
12: #include <netinet/in.h>
13:
14: #include <stdio.h>
15: #include <errno.h>
16: #include <ctype.h>
17: #include <netdb.h>
18:
19: struct rtentry route;
20: int options;
21: int s;
22: struct sockaddr_in sin = { AF_INET };
23: struct in_addr inet_makeaddr();
24:
25: main(argc, argv)
26: int argc;
27: char *argv[];
28: {
29:
30: if (argc < 2)
31: printf("usage: route [ -f ] [ cmd args ]\n"), exit(1);
32: s = socket(AF_INET, SOCK_RAW, 0, 0);
33: if (s < 0) {
34: perror("route: socket");
35: exit(1);
36: }
37: argc--, argv++;
38: if (strcmp(*argv, "-f") == 0) {
39: argc--, argv++;
40: flushroutes();
41: }
42: if (argc > 0) {
43: if (strcmp(*argv, "add") == 0)
44: newroute(argc, argv);
45: else if (strcmp(*argv, "delete") == 0)
46: newroute(argc, argv);
47: else if (strcmp(*argv, "change") == 0)
48: changeroute(argc-1, argv+1);
49: else
50: printf("%s: huh?\n", *argv);
51: }
52: }
53:
54: /*
55: * Purge all entries in the routing tables not
56: * associated with network interfaces.
57: */
58: #include <nlist.h>
59:
60: struct nlist nl[] = {
61: #define N_RTHOST 0
62: { "_rthost" },
63: #define N_RTNET 1
64: { "_rtnet" },
65: "",
66: };
67:
68: flushroutes()
69: {
70: struct mbuf mb;
71: register struct rtentry *rt;
72: register struct mbuf *m;
73: struct mbuf *routehash[RTHASHSIZ];
74: int i, doinghost = 1, kmem;
75: char *routename();
76:
77: nlist("/vmunix", nl);
78: if (nl[N_RTHOST].n_value == 0) {
79: printf("route: \"rthost\", symbol not in namelist\n");
80: exit(1);
81: }
82: if (nl[N_RTNET].n_value == 0) {
83: printf("route: \"rtnet\", symbol not in namelist\n");
84: exit(1);
85: }
86: kmem = open("/dev/kmem", 0);
87: if (kmem < 0) {
88: perror("route: /dev/kmem");
89: exit(1);
90: }
91: lseek(kmem, nl[N_RTHOST].n_value, 0);
92: read(kmem, routehash, sizeof (routehash));
93: printf("Flushing routing tables:\n");
94: again:
95: for (i = 0; i < RTHASHSIZ; i++) {
96: if (routehash[i] == 0)
97: continue;
98: m = routehash[i];
99: while (m) {
100: lseek(kmem, m, 0);
101: read(kmem, &mb, sizeof (mb));
102: rt = mtod(&mb, struct rtentry *);
103: if (rt->rt_flags & RTF_GATEWAY) {
104: struct sockaddr_in *sin;
105:
106: sin = (struct sockaddr_in *)&rt->rt_dst;
107: printf("%-15.15s ", routename(sin->sin_addr));
108: sin = (struct sockaddr_in *)&rt->rt_gateway;
109: printf("%-15.15s ", routename(sin->sin_addr));
110: if (ioctl(s, SIOCDELRT, (caddr_t)rt) < 0)
111: error("delete");
112: else
113: printf("done\n");
114: }
115: m = mb.m_next;
116: }
117: }
118: if (doinghost) {
119: lseek(kmem, nl[N_RTNET].n_value, 0);
120: read(kmem, routehash, sizeof (routehash));
121: doinghost = 0;
122: goto again;
123: }
124: close(kmem);
125: }
126:
127: char *
128: routename(in)
129: struct in_addr in;
130: {
131: char *cp = 0;
132: static char line[50];
133: int lna, net;
134:
135: net = inet_netof(in);
136: lna = inet_lnaof(in);
137: if (lna == INADDR_ANY) {
138: struct netent *np = getnetbyaddr(net, AF_INET);
139:
140: if (np)
141: cp = np->n_name;
142: } else {
143: struct hostent *hp;
144:
145: hp = gethostbyaddr(&in, sizeof (struct in_addr),
146: AF_INET);
147: if (hp)
148: cp = hp->h_name;
149: }
150: if (cp)
151: strcpy(line, cp);
152: else {
153: u_char *ucp = (u_char *)∈
154: if (lna == INADDR_ANY)
155: sprintf(line, "%u.%u.%u", ucp[0], ucp[1], ucp[2]);
156: else
157: sprintf(line, "%u.%u.%u.%u", ucp[0], ucp[1],
158: ucp[2], ucp[3]);
159: }
160: return (line);
161: }
162:
163: newroute(argc, argv)
164: int argc;
165: char *argv[];
166: {
167: struct sockaddr_in *sin;
168: char *cmd;
169:
170: if (argc < 3 || argc > 4) {
171: printf("usage: %s destination gateway [ metric ]\n", argv[0]);
172: return;
173: }
174: cmd = argv[0];
175: getaddr(argv[1], &route.rt_dst);
176: getaddr(argv[2], &route.rt_gateway);
177: sin = (struct sockaddr_in *)&route.rt_dst;
178: route.rt_flags = RTF_UP;
179: if (inet_lnaof(sin->sin_addr) != 0)
180: route.rt_flags |= RTF_HOST;
181: if (argc > 3 && atoi(argv[3]) > 0)
182: route.rt_flags |= RTF_GATEWAY;
183: printf("%s %s: gateway ", cmd, routename(sin->sin_addr));
184: sin = (struct sockaddr_in *)&route.rt_gateway;
185: printf("%s, flags %x\n", routename(sin->sin_addr), route.rt_flags);
186: if (ioctl(s, *cmd == 'a' ? SIOCADDRT : SIOCDELRT, (caddr_t)&route))
187: error(cmd);
188: }
189:
190: changeroute(argc, argv)
191: int argc;
192: char *argv[];
193: {
194: printf("not supported\n");
195: }
196:
197: error(cmd)
198: char *cmd;
199: {
200: extern int errno;
201:
202: if (errno == ESRCH)
203: fprintf(stderr, "not in table\n");
204: else if (errno == EBUSY)
205: fprintf(stderr, "entry in use\n");
206: else if (errno == ENOBUFS)
207: fprintf(stderr, "routing table overflow\n");
208: else
209: perror(cmd);
210: }
211:
212: getaddr(s, sin)
213: char *s;
214: struct sockaddr_in *sin;
215: {
216: struct hostent *hp;
217: struct netent *np;
218: u_long val;
219:
220: if (strcmp(s, "default") == 0) {
221: sin->sin_family = AF_INET;
222: sin->sin_addr = inet_makeaddr(0, INADDR_ANY);
223: return;
224: }
225: hp = gethostbyname(s);
226: if (hp) {
227: sin->sin_family = hp->h_addrtype;
228: bcopy(hp->h_addr, &sin->sin_addr, hp->h_length);
229: return;
230: }
231: np = getnetbyname(s);
232: if (np) {
233: sin->sin_family = np->n_addrtype;
234: sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY);
235: return;
236: }
237: sin->sin_family = AF_INET;
238: val = inet_addr(s);
239: if (val != -1) {
240: sin->sin_addr.s_addr = val;
241: return;
242: }
243: val = inet_network(s);
244: if (val != -1) {
245: sin->sin_addr = inet_makeaddr(val, INADDR_ANY);
246: return;
247: }
248: fprintf(stderr, "%s: bad value\n", s);
249: exit(1);
250: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.