|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1983 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: */ ! 6: ! 7: #ifndef lint ! 8: static char sccsid[] = "@(#)route.c 5.6 (Berkeley) 86/04/23"; ! 9: #endif ! 10: ! 11: #include <sys/param.h> ! 12: #include <sys/socket.h> ! 13: #include <sys/mbuf.h> ! 14: ! 15: #include <net/if.h> ! 16: #include <net/route.h> ! 17: #include <netinet/in.h> ! 18: ! 19: #include <netns/ns.h> ! 20: ! 21: #include <netdb.h> ! 22: ! 23: extern int kmem; ! 24: extern int nflag; ! 25: extern char *routename(), *netname(), *ns_print(); ! 26: ! 27: /* ! 28: * Definitions for showing gateway flags. ! 29: */ ! 30: struct bits { ! 31: short b_mask; ! 32: char b_val; ! 33: } bits[] = { ! 34: { RTF_UP, 'U' }, ! 35: { RTF_GATEWAY, 'G' }, ! 36: { RTF_HOST, 'H' }, ! 37: { RTF_DYNAMIC, 'D' }, ! 38: { 0 } ! 39: }; ! 40: ! 41: /* ! 42: * Print routing tables. ! 43: */ ! 44: routepr(hostaddr, netaddr, hashsizeaddr) ! 45: off_t hostaddr, netaddr, hashsizeaddr; ! 46: { ! 47: struct mbuf mb; ! 48: register struct rtentry *rt; ! 49: register struct mbuf *m; ! 50: register struct bits *p; ! 51: char name[16], *flags; ! 52: struct mbuf **routehash; ! 53: struct ifnet ifnet; ! 54: int hashsize; ! 55: int i, doinghost = 1; ! 56: ! 57: if (hostaddr == 0) { ! 58: printf("rthost: symbol not in namelist\n"); ! 59: return; ! 60: } ! 61: if (netaddr == 0) { ! 62: printf("rtnet: symbol not in namelist\n"); ! 63: return; ! 64: } ! 65: if (hashsizeaddr == 0) { ! 66: printf("rthashsize: symbol not in namelist\n"); ! 67: return; ! 68: } ! 69: klseek(kmem, hashsizeaddr, 0); ! 70: read(kmem, &hashsize, sizeof (hashsize)); ! 71: routehash = (struct mbuf **)malloc( hashsize*sizeof (struct mbuf *) ); ! 72: klseek(kmem, hostaddr, 0); ! 73: read(kmem, routehash, hashsize*sizeof (struct mbuf *)); ! 74: printf("Routing tables\n"); ! 75: printf("%-20.20s %-20.20s %-8.8s %-6.6s %-10.10s %s\n", ! 76: "Destination", "Gateway", ! 77: "Flags", "Refcnt", "Use", "Interface"); ! 78: again: ! 79: for (i = 0; i < hashsize; i++) { ! 80: if (routehash[i] == 0) ! 81: continue; ! 82: m = routehash[i]; ! 83: while (m) { ! 84: struct sockaddr_in *sin; ! 85: struct sockaddr_ns *sns; ! 86: ! 87: klseek(kmem, m, 0); ! 88: read(kmem, &mb, sizeof (mb)); ! 89: rt = mtod(&mb, struct rtentry *); ! 90: if ((unsigned)rt < (unsigned)&mb || ! 91: (unsigned)rt >= (unsigned)(&mb + 1)) { ! 92: printf("???\n"); ! 93: return; ! 94: } ! 95: ! 96: switch(rt->rt_dst.sa_family) { ! 97: case AF_INET: ! 98: sin = (struct sockaddr_in *)&rt->rt_dst; ! 99: printf("%-20.20s ", ! 100: (sin->sin_addr.s_addr == 0) ? "default" : ! 101: (rt->rt_flags & RTF_HOST) ? ! 102: routename(sin->sin_addr) : ! 103: netname(sin->sin_addr, 0)); ! 104: sin = (struct sockaddr_in *)&rt->rt_gateway; ! 105: printf("%-20.20s ", routename(sin->sin_addr)); ! 106: break; ! 107: case AF_NS: ! 108: printf("%-20s ", ! 109: ns_print((struct sockaddr_ns *)&rt->rt_dst)); ! 110: printf("%-20s ", ! 111: ns_print((struct sockaddr_ns *)&rt->rt_gateway)); ! 112: break; ! 113: default: ! 114: { ! 115: u_short *s = (u_short *)rt->rt_dst.sa_data; ! 116: printf("(%d)%x %x %x %x %x %x %x ", ! 117: rt->rt_dst.sa_family, ! 118: s[0], s[1], s[2], s[3], s[4], s[5], s[6]); ! 119: s = (u_short *)rt->rt_gateway.sa_data; ! 120: printf("(%d)%x %x %x %x %x %x %x ", ! 121: rt->rt_gateway.sa_family, ! 122: s[0], s[1], s[2], s[3], s[4], s[5], s[6]); ! 123: } ! 124: } ! 125: for (flags = name, p = bits; p->b_mask; p++) ! 126: if (p->b_mask & rt->rt_flags) ! 127: *flags++ = p->b_val; ! 128: *flags = '\0'; ! 129: printf("%-8.8s %-6d %-10d ", name, ! 130: rt->rt_refcnt, rt->rt_use); ! 131: if (rt->rt_ifp == 0) { ! 132: putchar('\n'); ! 133: m = mb.m_next; ! 134: continue; ! 135: } ! 136: klseek(kmem, rt->rt_ifp, 0); ! 137: read(kmem, &ifnet, sizeof (ifnet)); ! 138: klseek(kmem, (int)ifnet.if_name, 0); ! 139: read(kmem, name, 16); ! 140: printf("%s%d\n", name, ifnet.if_unit); ! 141: m = mb.m_next; ! 142: } ! 143: } ! 144: if (doinghost) { ! 145: klseek(kmem, netaddr, 0); ! 146: read(kmem, routehash, hashsize*sizeof (struct mbuf *)); ! 147: doinghost = 0; ! 148: goto again; ! 149: } ! 150: free(routehash); ! 151: } ! 152: ! 153: char * ! 154: routename(in) ! 155: struct in_addr in; ! 156: { ! 157: register char *cp; ! 158: static char line[50]; ! 159: struct hostent *hp; ! 160: static char domain[MAXHOSTNAMELEN + 1]; ! 161: static int first = 1; ! 162: char *index(); ! 163: ! 164: if (first) { ! 165: first = 0; ! 166: if (gethostname(domain, MAXHOSTNAMELEN) == 0 && ! 167: (cp = index(domain, '.'))) ! 168: (void) strcpy(domain, cp + 1); ! 169: else ! 170: domain[0] = 0; ! 171: } ! 172: cp = 0; ! 173: if (!nflag) { ! 174: hp = gethostbyaddr(&in, sizeof (struct in_addr), ! 175: AF_INET); ! 176: if (hp) { ! 177: if ((cp = index(hp->h_name, '.')) && ! 178: !strcmp(cp + 1, domain)) ! 179: *cp = 0; ! 180: cp = hp->h_name; ! 181: } ! 182: } ! 183: if (cp) ! 184: strcpy(line, cp); ! 185: else { ! 186: #define C(x) ((x) & 0xff) ! 187: in.s_addr = ntohl(in.s_addr); ! 188: sprintf(line, "%u.%u.%u.%u", C(in.s_addr >> 24), ! 189: C(in.s_addr >> 16), C(in.s_addr >> 8), C(in.s_addr)); ! 190: } ! 191: return (line); ! 192: } ! 193: ! 194: /* ! 195: * Return the name of the network whose address is given. ! 196: * The address is assumed to be that of a net or subnet, not a host. ! 197: */ ! 198: char * ! 199: netname(in, mask) ! 200: struct in_addr in; ! 201: u_long mask; ! 202: { ! 203: char *cp = 0; ! 204: static char line[50]; ! 205: struct netent *np = 0; ! 206: u_long net; ! 207: register i; ! 208: int subnetshift; ! 209: ! 210: in.s_addr = ntohl(in.s_addr); ! 211: if (!nflag && in.s_addr) { ! 212: if (mask == 0) { ! 213: if (IN_CLASSA(i)) { ! 214: mask = IN_CLASSA_NET; ! 215: subnetshift = 8; ! 216: } else if (IN_CLASSB(i)) { ! 217: mask = IN_CLASSB_NET; ! 218: subnetshift = 8; ! 219: } else { ! 220: mask = IN_CLASSC_NET; ! 221: subnetshift = 4; ! 222: } ! 223: /* ! 224: * If there are more bits than the standard mask ! 225: * would suggest, subnets must be in use. ! 226: * Guess at the subnet mask, assuming reasonable ! 227: * width subnet fields. ! 228: */ ! 229: while (in.s_addr &~ mask) ! 230: mask = (long)mask >> subnetshift; ! 231: } ! 232: net = in.s_addr & mask; ! 233: while ((mask & 1) == 0) ! 234: mask >>= 1, net >>= 1; ! 235: np = getnetbyaddr(net, AF_INET); ! 236: if (np) ! 237: cp = np->n_name; ! 238: } ! 239: if (cp) ! 240: strcpy(line, cp); ! 241: else if ((in.s_addr & 0xffffff) == 0) ! 242: sprintf(line, "%u", C(in.s_addr >> 24)); ! 243: else if ((in.s_addr & 0xffff) == 0) ! 244: sprintf(line, "%u.%u", C(in.s_addr >> 24) , C(in.s_addr >> 16)); ! 245: else if ((in.s_addr & 0xff) == 0) ! 246: sprintf(line, "%u.%u.%u", C(in.s_addr >> 24), ! 247: C(in.s_addr >> 16), C(in.s_addr >> 8)); ! 248: else ! 249: sprintf(line, "%u.%u.%u.%u", C(in.s_addr >> 24), ! 250: C(in.s_addr >> 16), C(in.s_addr >> 8), C(in.s_addr)); ! 251: return (line); ! 252: } ! 253: ! 254: /* ! 255: * Print routing statistics ! 256: */ ! 257: rt_stats(off) ! 258: off_t off; ! 259: { ! 260: struct rtstat rtstat; ! 261: ! 262: if (off == 0) { ! 263: printf("rtstat: symbol not in namelist\n"); ! 264: return; ! 265: } ! 266: klseek(kmem, off, 0); ! 267: read(kmem, (char *)&rtstat, sizeof (rtstat)); ! 268: printf("routing:\n"); ! 269: printf("\t%d bad routing redirect%s\n", ! 270: rtstat.rts_badredirect, plural(rtstat.rts_badredirect)); ! 271: printf("\t%d dynamically created route%s\n", ! 272: rtstat.rts_dynamic, plural(rtstat.rts_dynamic)); ! 273: printf("\t%d new gateway%s due to redirects\n", ! 274: rtstat.rts_newgateway, plural(rtstat.rts_newgateway)); ! 275: printf("\t%d destination%s found unreachable\n", ! 276: rtstat.rts_unreach, plural(rtstat.rts_unreach)); ! 277: printf("\t%d use%s of a wildcard route\n", ! 278: rtstat.rts_wildcard, plural(rtstat.rts_wildcard)); ! 279: } ! 280: short ns_nullh[] = {0,0,0}; ! 281: short ns_bh[] = {-1,-1,-1}; ! 282: ! 283: char * ! 284: ns_print(sns) ! 285: struct sockaddr_ns *sns; ! 286: { ! 287: struct ns_addr work; ! 288: union { union ns_net net_e; u_long long_e; } net; ! 289: u_short port; ! 290: static char mybuf[50], cport[10], chost[25]; ! 291: char *host = ""; ! 292: register char *p; register u_char *q; u_char *q_lim; ! 293: ! 294: work = sns->sns_addr; ! 295: port = ntohs(work.x_port); ! 296: work.x_port = 0; ! 297: net.net_e = work.x_net; ! 298: if (ns_nullhost(work) && net.long_e == 0) { ! 299: if (port ) { ! 300: sprintf(mybuf, "*.%xH", port); ! 301: upHex(mybuf); ! 302: } else ! 303: sprintf(mybuf, "*.*"); ! 304: return (mybuf); ! 305: } ! 306: ! 307: if (bcmp(ns_bh, work.x_host.c_host, 6) == 0) { ! 308: host = "any"; ! 309: } else if (bcmp(ns_nullh, work.x_host.c_host, 6) == 0) { ! 310: host = "*"; ! 311: } else { ! 312: q = work.x_host.c_host; ! 313: sprintf(chost, "%02x%02x%02x%02x%02x%02xH", ! 314: q[0], q[1], q[2], q[3], q[4], q[5]); ! 315: for (p = chost; *p == '0' && p < chost + 12; p++); ! 316: host = p; ! 317: } ! 318: if (port) ! 319: sprintf(cport, ".%xH", htons(port)); ! 320: else ! 321: *cport = 0; ! 322: ! 323: sprintf(mybuf,"%xH.%s%s", ntohl(net.long_e), host, cport); ! 324: upHex(mybuf); ! 325: return(mybuf); ! 326: } ! 327: ! 328: char * ! 329: ns_phost(sns) ! 330: struct sockaddr_ns *sns; ! 331: { ! 332: struct sockaddr_ns work; ! 333: static union ns_net ns_zeronet; ! 334: char *p; ! 335: ! 336: work = *sns; ! 337: work.sns_addr.x_port = 0; ! 338: work.sns_addr.x_net = ns_zeronet; ! 339: ! 340: p = ns_print(&work); ! 341: if (strncmp("0H.", p, 3) == 0) p += 3; ! 342: return(p); ! 343: } ! 344: upHex(p0) ! 345: char *p0; ! 346: { ! 347: register char *p = p0; ! 348: for (; *p; p++) switch (*p) { ! 349: ! 350: case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': ! 351: *p += ('A' - 'a'); ! 352: } ! 353: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.