+ if (strcmp(*argv, "-f") == 0) {
+ argc--, argv++;
+ flushroutes();
+ }
+ if (argc > 0) {
+ if (strcmp(*argv, "add") == 0)
+ newroute(argc, argv);
+ else if (strcmp(*argv, "delete") == 0)
+ newroute(argc, argv);
+ else if (strcmp(*argv, "change") == 0)
+ changeroute(argc-1, argv+1);
+ else
+ printf("%s: huh?\n", *argv);
+ }
+}
+
+/*
+ * Purge all entries in the routing tables not
+ * associated with network interfaces.
+ */
+#include <nlist.h>
+
+struct nlist nl[] = {
+#define N_RTHOST 0
+ { "_rthost" },
+#define N_RTNET 1
+ { "_rtnet" },
+ "",
+};
+
+flushroutes()
+{
+ struct mbuf mb;
+ register struct rtentry *rt;
+ register struct mbuf *m;
+ struct mbuf *routehash[RTHASHSIZ];
+ int i, doinghost = 1, kmem;
+ char *routename();
+
+ nlist("/vmunix", nl);
+ if (nl[N_RTHOST].n_value == 0) {
+ printf("route: \"rthost\", symbol not in namelist\n");
+ exit(1);
+ }
+ if (nl[N_RTNET].n_value == 0) {
+ printf("route: \"rtnet\", symbol not in namelist\n");
+ exit(1);
+ }
+ kmem = open("/dev/kmem", 0);
+ if (kmem < 0) {
+ perror("route: /dev/kmem");
+ exit(1);
+ }
+ lseek(kmem, nl[N_RTHOST].n_value, 0);
+ read(kmem, routehash, sizeof (routehash));
+ printf("Flushing routing tables:\n");
+again:
+ for (i = 0; i < RTHASHSIZ; i++) {
+ if (routehash[i] == 0)
+ continue;
+ m = routehash[i];
+ while (m) {
+ lseek(kmem, m, 0);
+ read(kmem, &mb, sizeof (mb));
+ rt = mtod(&mb, struct rtentry *);
+ if (rt->rt_flags & RTF_GATEWAY) {
+ struct sockaddr_in *sin;
+
+ sin = (struct sockaddr_in *)&rt->rt_dst;
+ printf("%-15.15s ", routename(sin->sin_addr));
+ sin = (struct sockaddr_in *)&rt->rt_gateway;
+ printf("%-15.15s ", routename(sin->sin_addr));
+ if (ioctl(s, SIOCDELRT, (caddr_t)rt) < 0)
+ error("delete");
+ else
+ printf("done\n");
+ }
+ m = mb.m_next;
+ }
+ }
+ if (doinghost) {
+ lseek(kmem, nl[N_RTNET].n_value, 0);
+ read(kmem, routehash, sizeof (routehash));
+ doinghost = 0;
+ goto again;
+ }
+ close(kmem);
+}
+
+char *
+routename(in)
+ struct in_addr in;
+{
+ char *cp = 0;
+ static char line[50];
+ int lna, net;
+
+ net = inet_netof(in);
+ lna = inet_lnaof(in);
+ if (lna == INADDR_ANY) {
+ struct netent *np = getnetbyaddr(net, AF_INET);
+
+ if (np)
+ cp = np->n_name;
+ } else {
+ struct hostent *hp;
+
+ hp = gethostbyaddr(&in, sizeof (struct in_addr),
+ AF_INET);
+ if (hp)
+ cp = hp->h_name;
+ }
+ if (cp)
+ strcpy(line, cp);
+ else {
+ u_char *ucp = (u_char *)∈
+ if (lna == INADDR_ANY)
+ sprintf(line, "%u.%u.%u", ucp[0], ucp[1], ucp[2]);
+ else
+ sprintf(line, "%u.%u.%u.%u", ucp[0], ucp[1],
+ ucp[2], ucp[3]);
+ }
+ return (line);