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

Defined functions

netname defined in line 245; used 5 times
ns_phost defined in line 375; used 1 times
ns_print defined in line 330; used 4 times
routename defined in line 200; used 5 times
routepr defined in line 45; used 1 times
rt_stats defined in line 303; used 1 times
upHex defined in line 391; used 3 times

Defined variables

bits defined in line 34; used 1 times
ns_bh defined in line 328; used 1 times
ns_nullh defined in line 327; used 1 times
sccsid defined in line 8; never used

Defined struct's

bits defined in line 31; used 2 times
  • in line 50(2)

Defined macros

C defined in line 233; used 14 times
Last modified: 1994-01-01
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 120
Valid CSS Valid XHTML 1.0 Strict