📄 print_rtmsg.c
字号:
/* -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
* vim:set sts=4 ts=8:
*
* Copyright (c) 2001-2007 International Computer Science Institute
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software")
* to deal in the Software without restriction, subject to the conditions
* listed in the XORP LICENSE file. These conditions include: you must
* preserve this copyright notice, and you cannot mention the copyright
* holders in advertising related to the Software without their permission.
* The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
* notice is a summary of the XORP LICENSE file; the license in that file is
* legally binding.
*
* $XORP: xorp/contrib/win32/xorprtm/print_rtmsg.c,v 1.3 2007/02/16 22:45:32 pavlin Exp $
*/
/*
* Copyright (c) 1983, 1989, 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <winsock2.h>
#include <ws2tcpip.h>
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "bsdroute.h"
#ifndef MAXHOSTNAMELEN
#define MAXHOSTNAMELEN 256
#endif
int warnx(char *str, ...)
{
int ret;
va_list ap;
va_start(ap, str);
ret = vfprintf(stderr, str, ap);
va_end(ap);
exit(1);
return ret;
}
int warn(char *str,...)
{
int ret;
va_list ap;
va_start(ap, str);
ret = vfprintf(stderr, str, ap);
va_end(ap);
return ret;
}
int
snprintf(char *cp, size_t sz, char *fmt, ...)
{
int ret;
va_list ap;
va_start(ap, fmt);
ret = vsprintf(cp, fmt, ap);
va_end(ap);
return ret;
}
union sockunion {
struct sockaddr sa;
struct sockaddr_in sin;
#ifdef INET6
struct sockaddr_in6 sin6;
#endif
struct sockaddr_storage ss; /* added to avoid memory overrun */
} so_dst, so_gate, so_mask, so_genmask, so_ifa, so_ifp;
typedef union sockunion *sup;
int pid, rtm_addrs;
int s;
int forcehost, forcenet, doflush, nflag, af, qflag, tflag, keyword();
int iflag, aflen = sizeof (struct sockaddr_in);
int locking, lockrest, debugonly;
struct rt_metrics rt_metrics;
u_long rtm_inits;
const char *routename(), *netname();
void flushroutes(), newroute(), monitor(), sockaddr(), sodump(), bprintf();
void print_getmsg(), print_rtmsg(), pmsg_common(), pmsg_addrs(), mask_addr();
static int inet6_makenetandmask(struct sockaddr_in6 *, char *);
int getaddr(), rtmsg();
int prefixlen();
int verbose = 1;
const char *
routename(sa)
struct sockaddr *sa;
{
char *cp;
static char line[MAXHOSTNAMELEN + 1];
struct hostent *hp;
static char domain[MAXHOSTNAMELEN + 1];
static int first = 1, n;
if (first) {
first = 0;
if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
(cp = strchr(domain, '.'))) {
domain[MAXHOSTNAMELEN] = '\0';
(void) strcpy(domain, cp + 1);
} else
domain[0] = 0;
}
switch (sa->sa_family) {
case AF_INET:
{ struct in_addr in;
in = ((struct sockaddr_in *)sa)->sin_addr;
cp = 0;
if (in.s_addr == INADDR_ANY /*|| sa->sa_len < 4*/)
cp = "default";
if (cp == 0 && !nflag) {
hp = gethostbyaddr((char *)&in, sizeof (struct in_addr),
AF_INET);
if (hp) {
if ((cp = strchr(hp->h_name, '.')) &&
!strcmp(cp + 1, domain))
*cp = 0;
cp = hp->h_name;
}
}
if (cp) {
strncpy(line, cp, sizeof(line) - 1);
line[sizeof(line) - 1] = '\0';
} else
(void) sprintf(line, "%s", inet_ntoa(in));
break;
}
#ifdef INET6
case AF_INET6:
{
struct sockaddr_in6 sin6; /* use static var for safety */
int niflags = 0;
memset(&sin6, 0, sizeof(sin6));
memcpy(&sin6, sa, sizeof(sin6));
sin6.sin6_family = AF_INET6;
#ifdef __KAME__
if ((IN6_IS_ADDR_LINKLOCAL(&sin6.sin6_addr) ||
IN6_IS_ADDR_MC_LINKLOCAL(&sin6.sin6_addr)) &&
sin6.sin6_scope_id == 0) {
sin6.sin6_scope_id =
ntohs(*(USHORT *)&sin6.sin6_addr.s6_addr[2]);
sin6.sin6_addr.s6_addr[2] = 0;
sin6.sin6_addr.s6_addr[3] = 0;
}
#endif
if (nflag)
niflags |= NI_NUMERICHOST;
if (getnameinfo((struct sockaddr *)&sin6,
sizeof(struct sockaddr_in6),
line, sizeof(line), NULL, 0, niflags) != 0)
strncpy(line, "invalid", sizeof(line));
return(line);
}
#endif
default:
{ u_short *s = (u_short *)sa;
/*u_short *slim = s + ((sa->sa_len + 1) >> 1);*/
u_short *slim = s + ((sizeof(struct sockaddr_storage) + 1) >> 1);
char *cp = line + sprintf(line, "(%d)", sa->sa_family);
char *cpe = line + sizeof(line);
/* XXX: If not first, and family 0, assume it's
* a network mask in a 'struct sockaddr_storage' and
* just treat it as an inet mask.
*/
if (!first && sa->sa_family == 0) {
slim = s + ((sizeof(struct sockaddr_in) + 1) >> 1);
}
while (++s < slim && cp < cpe) /* start with sa->sa_data */
if ((n = snprintf(cp, cpe - cp, " %x", *s)) > 0)
cp += n;
else
*cp = '\0';
break;
}
}
return (line);
}
/*
* Return the name of the network whose address is given.
* The address is assumed to be that of a net or subnet, not a host.
*/
const char *
netname(sa)
struct sockaddr *sa;
{
char *cp = 0;
static char line[MAXHOSTNAMELEN + 1];
struct netent *np = 0;
u_long net, mask;
u_long i;
int n, subnetshift;
switch (sa->sa_family) {
case AF_INET:
{ struct in_addr in;
in = ((struct sockaddr_in *)sa)->sin_addr;
i = in.s_addr = ntohl(in.s_addr);
if (in.s_addr == 0)
cp = "default";
else if (!nflag) {
if (IN_CLASSA(i)) {
mask = IN_CLASSA_NET;
subnetshift = 8;
} else if (IN_CLASSB(i)) {
mask = IN_CLASSB_NET;
subnetshift = 8;
} else {
mask = IN_CLASSC_NET;
subnetshift = 4;
}
/*
* If there are more bits than the standard mask
* would suggest, subnets must be in use.
* Guess at the subnet mask, assuming reasonable
* width subnet fields.
*/
while (in.s_addr &~ mask)
mask = (long)mask >> subnetshift;
net = in.s_addr & mask;
while ((mask & 1) == 0)
mask >>= 1, net >>= 1;
np = NULL;
}
#define C(x) (unsigned)((x) & 0xff)
if (cp)
strncpy(line, cp, sizeof(line));
else if ((in.s_addr & 0xffffff) == 0)
(void) sprintf(line, "%u", C(in.s_addr >> 24));
else if ((in.s_addr & 0xffff) == 0)
(void) sprintf(line, "%u.%u", C(in.s_addr >> 24),
C(in.s_addr >> 16));
else if ((in.s_addr & 0xff) == 0)
(void) sprintf(line, "%u.%u.%u", C(in.s_addr >> 24),
C(in.s_addr >> 16), C(in.s_addr >> 8));
else
(void) sprintf(line, "%u.%u.%u.%u", C(in.s_addr >> 24),
C(in.s_addr >> 16), C(in.s_addr >> 8),
C(in.s_addr));
#undef C
break;
}
#ifdef INET6
case AF_INET6:
{
struct sockaddr_in6 sin6; /* use static var for safety */
int niflags = 0;
memset(&sin6, 0, sizeof(sin6));
memcpy(&sin6, sa, sizeof(sin6));
sin6.sin6_family = AF_INET6;
#ifdef __KAME__
if (/*sa->sa_len == sizeof(struct sockaddr_in6) &&*/
(IN6_IS_ADDR_LINKLOCAL(&sin6.sin6_addr) ||
IN6_IS_ADDR_MC_LINKLOCAL(&sin6.sin6_addr)) &&
sin6.sin6_scope_id == 0) {
sin6.sin6_scope_id =
ntohs(*(USHORT *)&sin6.sin6_addr.s6_addr[2]);
sin6.sin6_addr.s6_addr[2] = 0;
sin6.sin6_addr.s6_addr[3] = 0;
}
#endif
if (nflag)
niflags |= NI_NUMERICHOST;
if (getnameinfo((struct sockaddr *)&sin6,
sizeof(struct sockaddr_in6),
line, sizeof(line), NULL, 0, niflags) != 0)
strncpy(line, "invalid", sizeof(line));
return(line);
}
#endif
default:
{ u_short *s = (u_short *)sa->sa_data;
u_short *slim = s + ((sizeof(struct sockaddr_storage) + 1)>>1);
char *cp = line + sprintf(line, "af %d:", sa->sa_family);
char *cpe = line + sizeof(line);
while (s < slim && cp < cpe)
if ((n = snprintf(cp, cpe - cp, " %x", *s++)) > 0)
cp += n;
else
*cp = '\0';
break;
}
}
return (line);
}
void
inet_makenetandmask(net, sin, bits)
u_long net, bits;
struct sockaddr_in *sin;
{
u_long addr, mask = 0;
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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -