📄 print_rtmsg.c
字号:
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;
}
if (bits)
mask = 0xffffffff << (32 - bits);
sin->sin_addr.s_addr = htonl(addr);
sin = &so_mask.sin;
sin->sin_addr.s_addr = htonl(mask);
sin->sin_family = 0;
cp = (char *)(&sin->sin_addr + 1);
while (*--cp == 0 && cp > (char *)sin)
;
}
#ifdef INET6
/*
* XXX the function may need more improvement...
*/
static int
inet6_makenetandmask(sin6, plen)
struct sockaddr_in6 *sin6;
char *plen;
{
struct in6_addr in6;
if (!plen) {
if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) &&
sin6->sin6_scope_id == 0) {
plen = "0";
} else if ((sin6->sin6_addr.s6_addr[0] & 0xe0) == 0x20) {
/* aggregatable global unicast - RFC2374 */
memset(&in6, 0, sizeof(in6));
if (!memcmp(&sin6->sin6_addr.s6_addr[8],
&in6.s6_addr[8], 8))
plen = "64";
}
}
if (!plen || strcmp(plen, "128") == 0)
return 1;
rtm_addrs |= RTA_NETMASK;
(void)prefixlen(plen);
return 0;
}
#endif
int
prefixlen(s)
char *s;
{
int len = atoi(s), q, r;
int max;
char *p;
rtm_addrs |= RTA_NETMASK;
switch (af) {
#ifdef INET6
case AF_INET6:
max = 128;
p = (char *)&so_mask.sin6.sin6_addr;
break;
#endif
case AF_INET:
max = 32;
p = (char *)&so_mask.sin.sin_addr;
break;
default:
(void) fprintf(stderr, "prefixlen not supported in this af\n");
exit(1);
/*NOTREACHED*/
}
if (len < 0 || max < len) {
(void) fprintf(stderr, "%s: bad value\n", s);
exit(1);
}
q = len >> 3;
r = len & 7;
so_mask.sa.sa_family = af;
memset((void *)p, 0, max / 8);
if (q > 0)
memset((void *)p, 0xff, q);
if (r > 0)
*((u_char *)p + q) = (0xff00 >> r) & 0xff;
if (len == max)
return -1;
else
return len;
}
struct {
struct rt_msghdr m_rtm;
char m_space[512];
} m_rtmsg;
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",
"RTM_NEWMADDR: new multicast group membership on iface",
"RTM_DELMADDR: multicast group membership removed from iface",
"RTM_IFANNOUNCE: interface arrival/departure",
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\015BLACKHOLE\016b016"
"\017PROTO2\020PROTO1\021PRCLONING\022WASCLONED\023PROTO3\024CHAINDELETE"
"\025PINNED\026LOCAL\027BROADCAST\030MULTICAST";
char ifnetflags[] =
"\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5PTP\6b6\7RUNNING\010NOARP"
"\011PPROMISC\012ALLMULTI\013OACTIVE\014SIMPLEX\015LINK0\016LINK1"
"\017LINK2\020MULTICAST";
char addrnames[] =
"\1DST\2GATEWAY\3NETMASK\4GENMASK\5IFP\6IFA\7AUTHOR\010BRD";
void
print_rtmsg(rtm, msglen)
struct rt_msghdr *rtm;
int msglen;
{
struct if_msghdr *ifm;
struct ifa_msghdr *ifam;
#ifdef RTM_NEWMADDR
struct ifma_msghdr *ifmam;
#endif
struct if_announcemsghdr *ifan;
char *state;
if (rtm->rtm_version != RTM_VERSION) {
(void) printf("routing message version %d not understood\n",
rtm->rtm_version);
return;
}
if (msgtypes[rtm->rtm_type] != NULL)
(void)printf("%s: ", msgtypes[rtm->rtm_type]);
else
(void)printf("#%d: ", rtm->rtm_type);
(void)printf("len %d, ", rtm->rtm_msglen);
switch (rtm->rtm_type) {
case RTM_IFINFO:
ifm = (struct if_msghdr *)rtm;
(void) printf("if# %d, ", ifm->ifm_index);
switch (ifm->ifm_data.ifi_link_state) {
case LINK_STATE_DOWN:
state = "down";
break;
case LINK_STATE_UP:
state = "up";
break;
default:
state = "unknown";
break;
}
(void) printf("link: %s, flags:", state);
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;
case RTM_IFANNOUNCE:
ifan = (struct if_announcemsghdr *)rtm;
(void) printf("if# %d, what: ", ifan->ifan_index);
switch (ifan->ifan_what) {
case IFAN_ARRIVAL:
printf("arrival");
break;
case IFAN_DEPARTURE:
printf("departure");
break;
default:
printf("#%d", ifan->ifan_what);
break;
}
printf("\n");
break;
default:
(void) printf("pid: %ld, seq %d, errno %d, flags:",
(long)rtm->rtm_pid, rtm->rtm_seq, rtm->rtm_errno);
bprintf(stdout, rtm->rtm_flags, routeflags);
pmsg_common(rtm);
}
}
void
print_getmsg(rtm, msglen)
struct rt_msghdr *rtm;
int msglen;
{
struct sockaddr *dst = NULL, *gate = NULL, *mask = NULL;
struct sockaddr_dl *ifp = NULL;
struct sockaddr *sa;
char *cp;
int i;
(void) printf(" route to: %s\n", routename(&so_dst));
if (rtm->rtm_version != RTM_VERSION) {
warnx("routing message version %d not understood",
rtm->rtm_version);
return;
}
if (rtm->rtm_msglen > msglen) {
warnx("message length mismatch, in packet %d, returned %d",
rtm->rtm_msglen, msglen);
}
if (rtm->rtm_errno) {
errno = rtm->rtm_errno;
warn("message indicates error %d", 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:
break;
}
cp += SA_SIZE(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));
(void)printf(" flags: ");
bprintf(stdout, rtm->rtm_flags, routeflags);
#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
}
void
pmsg_common(rtm)
struct rt_msghdr *rtm;
{
(void) printf(" inits: ");
bprintf(stdout, rtm->rtm_inits, metricnames);
pmsg_addrs(((char *)(rtm + 1)), rtm->rtm_addrs);
}
void
pmsg_addrs(cp, addrs)
char *cp;
int addrs;
{
struct sockaddr *sa;
int i;
if (addrs == 0) {
(void) putchar('\n');
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));
cp += SA_SIZE(sa);
}
(void) putchar('\n');
(void) fflush(stdout);
}
void
bprintf(fp, b, s)
FILE *fp;
int b;
u_char *s;
{
int i;
int gotsome = 0;
if (b == 0)
return;
while ((i = *s++) != 0) {
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);
}
void
sodump(su, which)
sup su;
char *which;
{
switch (su->sa.sa_family) {
case AF_INET:
(void) printf("%s: inet %s; ",
which, inet_ntoa(su->sin.sin_addr));
break;
}
(void) fflush(stdout);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -