📄 route.c
字号:
int mib[6]; char *buf, *lim, *next; register struct rt_msghdr *rtm; mib[0] = CTL_NET; mib[1] = PF_ROUTE; mib[2] = 0; /* protocol */ mib[3] = 0; /* wildcard address family */ mib[4] = NET_RT_IFLIST; mib[5] = 0; /* no flags */ if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) quit("route-sysctl-estimate"); if ((buf = malloc(needed)) == NULL) quit("malloc"); if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) quit("actual retrieval of interface table"); lim = buf + needed; for (next = buf; next < lim; next += rtm->rtm_msglen) { rtm = (struct rt_msghdr *)next; print_rtmsg(rtm, rtm->rtm_msglen); }}voidmonitor(){ int n; char msg[2048]; verbose = 1; if (debugonly) { interfaces(); exit(0); } for(;;) { n = read(s, msg, 2048); (void) printf("got message of size %d\n", n); print_rtmsg((struct rt_msghdr *)msg, n); }}struct { struct rt_msghdr m_rtm; char m_space[512];} m_rtmsg;intrtmsg(cmd, flags) int cmd, flags;{ static int seq; int rlen; register char *cp = m_rtmsg.m_space; register int l;#define NEXTADDR(w, u) \ if (rtm_addrs & (w)) {\ l = ROUNDUP(u.sa.sa_len); bcopy((char *)&(u), cp, l); cp += l;\ if (verbose) sodump(&(u),"u");\ } errno = 0; bzero((char *)&m_rtmsg, sizeof(m_rtmsg)); if (cmd == 'a') cmd = RTM_ADD; else if (cmd == 'c') cmd = RTM_CHANGE; else if (cmd == 'g') { cmd = RTM_GET; if (so_ifp.sa.sa_family == 0) { so_ifp.sa.sa_family == AF_LINK; so_ifp.sa.sa_len == sizeof(struct sockaddr_dl); rtm_addrs |= RTA_IFP; } } else cmd = RTM_DELETE;#define rtm m_rtmsg.m_rtm rtm.rtm_type = cmd; rtm.rtm_flags = flags; rtm.rtm_version = RTM_VERSION; rtm.rtm_seq = ++seq; rtm.rtm_addrs = rtm_addrs; rtm.rtm_rmx = rt_metrics; rtm.rtm_inits = rtm_inits; if (rtm_addrs & RTA_NETMASK) mask_addr(); NEXTADDR(RTA_DST, so_dst); NEXTADDR(RTA_GATEWAY, so_gate); NEXTADDR(RTA_NETMASK, so_mask); NEXTADDR(RTA_GENMASK, so_genmask); NEXTADDR(RTA_IFP, so_ifp); NEXTADDR(RTA_IFA, so_ifa); rtm.rtm_msglen = l = cp - (char *)&m_rtmsg; if (verbose) print_rtmsg(&rtm, l); if (debugonly) return (0); if ((rlen = write(s, (char *)&m_rtmsg, l)) < 0) { perror("writing to routing socket"); return (-1); } if (cmd == RTM_GET) { do { l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg)); } while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid)); if (l < 0) (void) fprintf(stderr, "route: read from routing socket: %s\n", strerror(errno)); else print_getmsg(&rtm, l); }#undef rtm return (0);}voidmask_addr(){ int olen = so_mask.sa.sa_len; register char *cp1 = olen + (char *)&so_mask, *cp2; for (so_mask.sa.sa_len = 0; cp1 > (char *)&so_mask; ) if (*--cp1 != 0) { so_mask.sa.sa_len = 1 + cp1 - (char *)&so_mask; break; } if ((rtm_addrs & RTA_DST) == 0) return; switch (so_dst.sa.sa_family) { case AF_NS: case AF_INET: case AF_CCITT: case 0: return; case AF_ISO: olen = MIN(so_dst.siso.siso_nlen, MAX(so_mask.sa.sa_len - 6, 0)); break; } cp1 = so_mask.sa.sa_len + 1 + (char *)&so_dst; cp2 = so_dst.sa.sa_len + 1 + (char *)&so_dst; while (cp2 > cp1) *--cp2 = 0; cp2 = so_mask.sa.sa_len + 1 + (char *)&so_mask; while (cp1 > so_dst.sa.sa_data) *--cp1 &= *--cp2; switch (so_dst.sa.sa_family) { case AF_ISO: so_dst.siso.siso_nlen = olen; break; }}char *msgtypes[] = { "", "RTM_ADD: Add Route", "RTM_DELETE: Delete Route", "RTM_CHANGE: Change Metrics or flags", "RTM_GET: Report Metrics", "RTM_LOSING: Kernel Suspects Partitioning", "RTM_REDIRECT: Told to use different route", "RTM_MISS: Lookup failed on this address", "RTM_LOCK: fix specified metrics", "RTM_OLDADD: caused by SIOCADDRT", "RTM_OLDDEL: caused by SIOCDELRT", "RTM_RESOLVE: Route created by cloning", "RTM_NEWADDR: address being added to iface", "RTM_DELADDR: address being removed from iface", "RTM_IFINFO: iface status change", 0,};char metricnames[] ="\011pksent\010rttvar\7rtt\6ssthresh\5sendpipe\4recvpipe\3expire\2hopcount\1mtu";char routeflags[] ="\1UP\2GATEWAY\3HOST\4REJECT\5DYNAMIC\6MODIFIED\7DONE\010MASK_PRESENT\011CLONING\012XRESOLVE\013LLINFO\014STATIC\017PROTO2\020PROTO1";char ifnetflags[] ="\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5PTP\6NOTRAILERS\7RUNNING\010NOARP\011PPROMISC\012ALLMULTI\013OACTIVE\014SIMPLEX\015LINK0\016LINK1\017LINK2\020MULTICAST";char addrnames[] ="\1DST\2GATEWAY\3NETMASK\4GENMASK\5IFP\6IFA\7AUTHOR\010BRD";voidprint_rtmsg(rtm, msglen) register struct rt_msghdr *rtm; int msglen;{ struct if_msghdr *ifm; struct ifa_msghdr *ifam; if (verbose == 0) return; if (rtm->rtm_version != RTM_VERSION) { (void) printf("routing message version %d not understood\n", rtm->rtm_version); return; } (void)printf("%s: len %d, ", msgtypes[rtm->rtm_type], rtm->rtm_msglen); switch (rtm->rtm_type) { case RTM_IFINFO: ifm = (struct if_msghdr *)rtm; (void) printf("if# %d, flags:", ifm->ifm_index); bprintf(stdout, ifm->ifm_flags, ifnetflags); pmsg_addrs((char *)(ifm + 1), ifm->ifm_addrs); break; case RTM_NEWADDR: case RTM_DELADDR: ifam = (struct ifa_msghdr *)rtm; (void) printf("metric %d, flags:", ifam->ifam_metric); bprintf(stdout, ifam->ifam_flags, routeflags); pmsg_addrs((char *)(ifam + 1), ifam->ifam_addrs); break; default: (void) printf("pid: %d, seq %d, errno %d, flags:", rtm->rtm_pid, rtm->rtm_seq, rtm->rtm_errno); bprintf(stdout, rtm->rtm_flags, routeflags); pmsg_common(rtm); }}voidprint_getmsg(rtm, msglen) register struct rt_msghdr *rtm; int msglen;{ struct sockaddr *dst = NULL, *gate = NULL, *mask = NULL; struct sockaddr_dl *ifp = NULL; register struct sockaddr *sa; register char *cp; register int i; (void) printf(" route to: %s\n", routename(&so_dst)); if (rtm->rtm_version != RTM_VERSION) { (void)fprintf(stderr, "routing message version %d not understood\n", rtm->rtm_version); return; } if (rtm->rtm_msglen > msglen) { (void)fprintf(stderr, "message length mismatch, in packet %d, returned %d\n", rtm->rtm_msglen, msglen); } if (rtm->rtm_errno) { (void) fprintf(stderr, "RTM_GET: %s (errno %d)\n", strerror(rtm->rtm_errno), rtm->rtm_errno); return; } cp = ((char *)(rtm + 1)); if (rtm->rtm_addrs) for (i = 1; i; i <<= 1) if (i & rtm->rtm_addrs) { sa = (struct sockaddr *)cp; switch (i) { case RTA_DST: dst = sa; break; case RTA_GATEWAY: gate = sa; break; case RTA_NETMASK: mask = sa; break; case RTA_IFP: if (sa->sa_family == AF_LINK && ((struct sockaddr_dl *)sa)->sdl_nlen) ifp = (struct sockaddr_dl *)sa; break; } ADVANCE(cp, sa); } if (dst && mask) mask->sa_family = dst->sa_family; /* XXX */ if (dst) (void)printf("destination: %s\n", routename(dst)); if (mask) { int savenflag = nflag; nflag = 1; (void)printf(" mask: %s\n", routename(mask)); nflag = savenflag; } if (gate && rtm->rtm_flags & RTF_GATEWAY) (void)printf(" gateway: %s\n", routename(gate)); if (ifp) (void)printf(" interface: %.*s\n", ifp->sdl_nlen, ifp->sdl_data); (void)printf(" flags: "); bprintf(stdout, rtm->rtm_flags, routeflags);#define lock(f) ((rtm->rtm_rmx.rmx_locks & __CONCAT(RTV_,f)) ? 'L' : ' ')#define msec(u) (((u) + 500) / 1000) /* usec to msec */ (void) printf("\n%s\n", "\ recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire"); printf("%8d%c ", rtm->rtm_rmx.rmx_recvpipe, lock(RPIPE)); printf("%8d%c ", rtm->rtm_rmx.rmx_sendpipe, lock(SPIPE)); printf("%8d%c ", rtm->rtm_rmx.rmx_ssthresh, lock(SSTHRESH)); printf("%8d%c ", msec(rtm->rtm_rmx.rmx_rtt), lock(RTT)); printf("%8d%c ", msec(rtm->rtm_rmx.rmx_rttvar), lock(RTTVAR)); printf("%8d%c ", rtm->rtm_rmx.rmx_hopcount, lock(HOPCOUNT)); printf("%8d%c ", rtm->rtm_rmx.rmx_mtu, lock(MTU)); if (rtm->rtm_rmx.rmx_expire) rtm->rtm_rmx.rmx_expire -= time(0); printf("%8d%c\n", rtm->rtm_rmx.rmx_expire, lock(EXPIRE));#undef lock#undef msec#define RTA_IGN (RTA_DST|RTA_GATEWAY|RTA_NETMASK|RTA_IFP|RTA_IFA|RTA_BRD) if (verbose) pmsg_common(rtm); else if (rtm->rtm_addrs &~ RTA_IGN) { (void) printf("sockaddrs: "); bprintf(stdout, rtm->rtm_addrs, addrnames); putchar('\n'); }#undef RTA_IGN}voidpmsg_common(rtm) register struct rt_msghdr *rtm;{ (void) printf("\nlocks: "); bprintf(stdout, rtm->rtm_rmx.rmx_locks, metricnames); (void) printf(" inits: "); bprintf(stdout, rtm->rtm_inits, metricnames); pmsg_addrs(((char *)(rtm + 1)), rtm->rtm_addrs);}voidpmsg_addrs(cp, addrs) char *cp; int addrs;{ register struct sockaddr *sa; int i; if (addrs == 0) return; (void) printf("\nsockaddrs: "); bprintf(stdout, addrs, addrnames); (void) putchar('\n'); for (i = 1; i; i <<= 1) if (i & addrs) { sa = (struct sockaddr *)cp; (void) printf(" %s", routename(sa)); ADVANCE(cp, sa); } (void) putchar('\n'); (void) fflush(stdout);}voidbprintf(fp, b, s) register FILE *fp; register int b; register u_char *s;{ register int i; int gotsome = 0; if (b == 0) return; while (i = *s++) { if (b & (1 << (i-1))) { if (gotsome == 0) i = '<'; else i = ','; (void) putc(i, fp); gotsome = 1; for (; (i = *s) > 32; s++) (void) putc(i, fp); } else while (*s > 32) s++; } if (gotsome) (void) putc('>', fp);}intkeyword(cp) char *cp;{ register struct keytab *kt = keywords; while (kt->kt_cp && strcmp(kt->kt_cp, cp)) kt++; return kt->kt_i;}voidsodump(su, which) register sup su; char *which;{ switch (su->sa.sa_family) { case AF_LINK: (void) printf("%s: link %s; ", which, link_ntoa(&su->sdl)); break; case AF_ISO: (void) printf("%s: iso %s; ", which, iso_ntoa(&su->siso.siso_addr)); break; case AF_INET: (void) printf("%s: inet %s; ", which, inet_ntoa(su->sin.sin_addr)); break; case AF_NS: (void) printf("%s: xns %s; ", which, ns_ntoa(su->sns.sns_addr)); break; } (void) fflush(stdout);}/* States*/#define VIRGIN 0#define GOTONE 1#define GOTTWO 2/* Inputs */#define DIGIT (4*0)#define END (4*1)#define DELIM (4*2)voidsockaddr(addr, sa) register char *addr; register struct sockaddr *sa;{ register char *cp = (char *)sa; int size = sa->sa_len; char *cplim = cp + size; register int byte = 0, state = VIRGIN, new; bzero(cp, size); cp++; do { if ((*addr >= '0') && (*addr <= '9')) { new = *addr - '0'; } else if ((*addr >= 'a') && (*addr <= 'f')) { new = *addr - 'a' + 10; } else if ((*addr >= 'A') && (*addr <= 'F')) { new = *addr - 'A' + 10; } else if (*addr == 0) state |= END; else state |= DELIM; addr++; switch (state /* | INPUT */) { case GOTTWO | DIGIT: *cp++ = byte; /*FALLTHROUGH*/ case VIRGIN | DIGIT: state = GOTONE; byte = new; continue; case GOTONE | DIGIT: state = GOTTWO; byte = new + (byte << 4); continue; default: /* | DELIM */ state = VIRGIN; *cp++ = byte; byte = 0; continue; case GOTONE | END: case GOTTWO | END: *cp++ = byte; /* FALLTHROUGH */ case VIRGIN | END: break; } break; } while (cp < cplim); sa->sa_len = cp - (char *)sa;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -