📄 route.c
字号:
int key;{ int flag = 0; u_long noval, *valp = &noval; switch (key) {#define caseof(x, y, z) case x: valp = &rt_metrics.z; flag = y; break caseof(K_MTU, RTV_MTU, rmx_mtu); caseof(K_HOPCOUNT, RTV_HOPCOUNT, rmx_hopcount); caseof(K_EXPIRE, RTV_EXPIRE, rmx_expire); caseof(K_RECVPIPE, RTV_RPIPE, rmx_recvpipe); caseof(K_SENDPIPE, RTV_SPIPE, rmx_sendpipe); caseof(K_SSTHRESH, RTV_SSTHRESH, rmx_ssthresh); caseof(K_RTT, RTV_RTT, rmx_rtt); caseof(K_RTTVAR, RTV_RTTVAR, rmx_rttvar); } rtm_inits |= flag; if (lockrest || locking) rt_metrics.rmx_locks |= flag; if (locking) locking = 0; *valp = atoi(value);}voidnewroute(argc, argv) int argc; register char **argv;{ char *cmd, *dest = "", *gateway = "", *err; int ishost = 0, ret, attempts, oerrno, flags = RTF_STATIC; int key; struct hostent *hp = 0; if (uid) { errno = EACCES; quit("must be root to alter routing table"); } cmd = argv[0]; if (*cmd != 'g') shutdown(s, 0); /* Don't want to read back our messages */ while (--argc > 0) { if (**(++argv)== '-') { switch (key = keyword(1 + *argv)) { case K_LINK: af = AF_LINK; aflen = sizeof(struct sockaddr_dl); break; case K_OSI: case K_ISO: af = AF_ISO; aflen = sizeof(struct sockaddr_iso); break; case K_INET: af = AF_INET; aflen = sizeof(struct sockaddr_in); break; case K_X25: af = AF_CCITT; aflen = sizeof(struct sockaddr_x25); break; case K_SA: af = PF_ROUTE; aflen = sizeof(union sockunion); break; case K_XNS: af = AF_NS; aflen = sizeof(struct sockaddr_ns); break; case K_IFACE: case K_INTERFACE: iflag++; case K_NOSTATIC: flags &= ~RTF_STATIC; break; case K_LOCK: locking = 1; break; case K_LOCKREST: lockrest = 1; break; case K_HOST: forcehost++; break; case K_REJECT: flags |= RTF_REJECT; break; case K_BLACKHOLE: flags |= RTF_BLACKHOLE; break; case K_PROTO1: flags |= RTF_PROTO1; break; case K_PROTO2: flags |= RTF_PROTO2; break; case K_CLONING: flags |= RTF_CLONING; break; case K_XRESOLVE: flags |= RTF_XRESOLVE; break; case K_STATIC: flags |= RTF_STATIC; break; case K_IFA: argc--; (void) getaddr(RTA_IFA, *++argv, 0); break; case K_IFP: argc--; (void) getaddr(RTA_IFP, *++argv, 0); break; case K_GENMASK: argc--; (void) getaddr(RTA_GENMASK, *++argv, 0); break; case K_GATEWAY: argc--; (void) getaddr(RTA_GATEWAY, *++argv, 0); break; case K_DST: argc--; ishost = getaddr(RTA_DST, *++argv, &hp); dest = *argv; break; case K_NETMASK: argc--; (void) getaddr(RTA_NETMASK, *++argv, 0); /* FALLTHROUGH */ case K_NET: forcenet++; break; case K_MTU: case K_HOPCOUNT: case K_EXPIRE: case K_RECVPIPE: case K_SENDPIPE: case K_SSTHRESH: case K_RTT: case K_RTTVAR: argc--; set_metric(*++argv, key); break; default: usage(1+*argv); } } else { if ((rtm_addrs & RTA_DST) == 0) { dest = *argv; ishost = getaddr(RTA_DST, *argv, &hp); } else if ((rtm_addrs & RTA_GATEWAY) == 0) { gateway = *argv; (void) getaddr(RTA_GATEWAY, *argv, &hp); } else { int ret = atoi(*argv); if (ret == 0) { if (strcmp(*argv, "0") == 0) printf("%s,%s", "old usage of trailing 0", "assuming route to if\n"); else usage((char *)NULL); iflag = 1; continue; } else if (ret > 0 && ret < 10) { printf("old usage of trailing digit, "); printf("assuming route via gateway\n"); iflag = 0; continue; } (void) getaddr(RTA_NETMASK, *argv, 0); } } } if (forcehost) ishost = 1; if (forcenet) ishost = 0; flags |= RTF_UP; if (ishost) flags |= RTF_HOST; if (iflag == 0) flags |= RTF_GATEWAY; for (attempts = 1; ; attempts++) { errno = 0; if ((ret = rtmsg(*cmd, flags)) == 0) break; if (errno != ENETUNREACH && errno != ESRCH) break; if (af == AF_INET && *gateway && hp && hp->h_addr_list[1]) { hp->h_addr_list++; bcopy(hp->h_addr_list[0], &so_gate.sin.sin_addr, hp->h_length); } else break; } if (*cmd == 'g') exit(0); oerrno = errno; (void) printf("%s %s %s", cmd, ishost? "host" : "net", dest); if (*gateway) { (void) printf(": gateway %s", gateway); if (attempts > 1 && ret == 0 && af == AF_INET) (void) printf(" (%s)", inet_ntoa(((struct sockaddr_in *)&route.rt_gateway)->sin_addr)); } if (ret == 0) (void) printf("\n"); else { switch (oerrno) { case ESRCH: err = "not in table"; break; case EBUSY: err = "entry in use"; break; case ENOBUFS: err = "routing table overflow"; break; default: err = strerror(oerrno); break; } (void) printf(": %s\n", err); }}voidinet_makenetandmask(net, sin) u_long net; register struct sockaddr_in *sin;{ u_long addr, mask = 0; register char *cp; rtm_addrs |= RTA_NETMASK; if (net == 0) mask = addr = 0; else if (net < 128) { addr = net << IN_CLASSA_NSHIFT; mask = IN_CLASSA_NET; } else if (net < 65536) { addr = net << IN_CLASSB_NSHIFT; mask = IN_CLASSB_NET; } else if (net < 16777216L) { addr = net << IN_CLASSC_NSHIFT; mask = IN_CLASSC_NET; } else { addr = net; if ((addr & IN_CLASSA_HOST) == 0) mask = IN_CLASSA_NET; else if ((addr & IN_CLASSB_HOST) == 0) mask = IN_CLASSB_NET; else if ((addr & IN_CLASSC_HOST) == 0) mask = IN_CLASSC_NET; else mask = -1; } sin->sin_addr.s_addr = htonl(addr); sin = &so_mask.sin; sin->sin_addr.s_addr = htonl(mask); sin->sin_len = 0; sin->sin_family = 0; cp = (char *)(&sin->sin_addr + 1); while (*--cp == 0 && cp > (char *)sin) ; sin->sin_len = 1 + cp - (char *)sin;}/* * Interpret an argument as a network address of some kind, * returning 1 if a host address, 0 if a network address. */intgetaddr(which, s, hpp) int which; char *s; struct hostent **hpp;{ register sup su; struct ns_addr ns_addr(); struct iso_addr *iso_addr(); struct hostent *hp; struct netent *np; u_long val; if (af == 0) { af = AF_INET; aflen = sizeof(struct sockaddr_in); } rtm_addrs |= which; switch (which) { case RTA_DST: su = &so_dst; su->sa.sa_family = af; break; case RTA_GATEWAY: su = &so_gate; su->sa.sa_family = af; break; case RTA_NETMASK: su = &so_mask; break; case RTA_GENMASK: su = &so_genmask; break; case RTA_IFP: su = &so_ifp; su->sa.sa_family = af; break; case RTA_IFA: su = &so_ifa; su->sa.sa_family = af; break; default: usage("Internal Error"); /*NOTREACHED*/ } su->sa.sa_len = aflen; if (strcmp(s, "default") == 0) { switch (which) { case RTA_DST: forcenet++; (void) getaddr(RTA_NETMASK, s, 0); break; case RTA_NETMASK: case RTA_GENMASK: su->sa.sa_len = 0; } return (0); } switch (af) { case AF_NS: if (which == RTA_DST) { extern short ns_bh[3]; struct sockaddr_ns *sms = &(so_mask.sns); bzero((char *)sms, sizeof(*sms)); sms->sns_family = 0; sms->sns_len = 6; sms->sns_addr.x_net = *(union ns_net *)ns_bh; rtm_addrs |= RTA_NETMASK; } su->sns.sns_addr = ns_addr(s); return (!ns_nullhost(su->sns.sns_addr)); case AF_OSI: su->siso.siso_addr = *iso_addr(s); if (which == RTA_NETMASK || which == RTA_GENMASK) { register char *cp = (char *)TSEL(&su->siso); su->siso.siso_nlen = 0; do {--cp ;} while ((cp > (char *)su) && (*cp == 0)); su->siso.siso_len = 1 + cp - (char *)su; } return (1); case AF_LINK: link_addr(s, &su->sdl); return (1); case AF_CCITT: ccitt_addr(s, &su->sx25); return (which == RTA_DST ? x25_makemask() : 1); case PF_ROUTE: su->sa.sa_len = sizeof(*su); sockaddr(s, &su->sa); return (1); case AF_INET: default: break; } if (hpp == NULL) hpp = &hp; *hpp = NULL; if (((val = inet_addr(s)) != -1) && (which != RTA_DST || forcenet == 0)) { su->sin.sin_addr.s_addr = val; if (inet_lnaof(su->sin.sin_addr) != INADDR_ANY) return (1); else { val = ntohl(val); goto netdone; } } if ((val = inet_network(s)) != -1 || ((np = getnetbyname(s)) != NULL && (val = np->n_net) != 0)) {netdone: if (which == RTA_DST) inet_makenetandmask(val, &su->sin); return (0); } hp = gethostbyname(s); if (hp) { *hpp = hp; su->sin.sin_family = hp->h_addrtype; bcopy(hp->h_addr, (char *)&su->sin.sin_addr, hp->h_length); return (1); } (void) fprintf(stderr, "%s: bad value\n", s); exit(1);}intx25_makemask(){ register char *cp; if ((rtm_addrs & RTA_NETMASK) == 0) { rtm_addrs |= RTA_NETMASK; for (cp = (char *)&so_mask.sx25.x25_net; cp < &so_mask.sx25.x25_opts.op_flags; cp++) *cp = -1; so_mask.sx25.x25_len = (u_char)&(((sup)0)->sx25.x25_opts); } return 0;}short ns_nullh[] = {0,0,0};short ns_bh[] = {-1,-1,-1};char *ns_print(sns) struct sockaddr_ns *sns;{ struct ns_addr work; union { union ns_net net_e; u_long long_e; } net; u_short port; static char mybuf[50], cport[10], chost[25]; char *host = ""; register char *p; register u_char *q; work = sns->sns_addr; port = ntohs(work.x_port); work.x_port = 0; net.net_e = work.x_net; if (ns_nullhost(work) && net.long_e == 0) { if (!port) return ("*.*"); (void) sprintf(mybuf, "*.%XH", port); return (mybuf); } if (bcmp((char *)ns_bh, (char *)work.x_host.c_host, 6) == 0) host = "any"; else if (bcmp((char *)ns_nullh, (char *)work.x_host.c_host, 6) == 0) host = "*"; else { q = work.x_host.c_host; (void) sprintf(chost, "%02X%02X%02X%02X%02X%02XH", q[0], q[1], q[2], q[3], q[4], q[5]); for (p = chost; *p == '0' && p < chost + 12; p++) /* void */; host = p; } if (port) (void) sprintf(cport, ".%XH", htons(port)); else *cport = 0; (void) sprintf(mybuf,"%XH.%s%s", ntohl(net.long_e), host, cport); return (mybuf);}voidinterfaces(){ size_t needed;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -