[BACK]Return to route.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sbin / route

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sbin/route/route.c between version 1.106 and 1.106.12.2

version 1.106, 2007/02/18 01:48:37 version 1.106.12.2, 2009/01/17 13:48:53
Line 31 
Line 31 
   
 #include <sys/cdefs.h>  #include <sys/cdefs.h>
 #ifndef lint  #ifndef lint
 __COPYRIGHT("@(#) Copyright (c) 1983, 1989, 1991, 1993\n\  __COPYRIGHT("@(#) Copyright (c) 1983, 1989, 1991, 1993\
         The Regents of the University of California.  All rights reserved.\n");   The Regents of the University of California.  All rights reserved.");
 #endif /* not lint */  #endif /* not lint */
   
 #ifndef lint  #ifndef lint
Line 73  __RCSID("$NetBSD$");
Line 73  __RCSID("$NetBSD$");
 #include "keywords.h"  #include "keywords.h"
 #include "extern.h"  #include "extern.h"
   
   union sockunion {
           struct  sockaddr sa;
           struct  sockaddr_in sin;
   #ifdef INET6
           struct  sockaddr_in6 sin6;
   #endif
           struct  sockaddr_at sat;
           struct  sockaddr_dl sdl;
   #ifndef SMALL
           struct  sockaddr_iso siso;
   #endif /* SMALL */
   };
   
 typedef union sockunion *sup;  typedef union sockunion *sup;
   
   struct sou {
           union sockunion so_dst, so_gate, so_mask, so_genmask, so_ifa, so_ifp;
   };
   
 static char *any_ntoa(const struct sockaddr *);  static char *any_ntoa(const struct sockaddr *);
 static const char *route_strerror(int);  static const char *route_strerror(int);
 static void set_metric(char *, int);  static void set_metric(const char *, int);
 static int newroute(int, char **);  static int newroute(int, char *const *);
 static void inet_makenetandmask(u_int32_t, struct sockaddr_in *);  static void inet_makenetandmask(u_int32_t, struct sockaddr_in *, struct sou *);
 #ifdef INET6  #ifdef INET6
 static int inet6_makenetandmask(struct sockaddr_in6 *);  static int inet6_makenetandmask(const struct sockaddr_in6 *, struct sou *);
 #endif  #endif
 static int getaddr(int, char *, struct hostent **);  static int getaddr(int, const char *, struct hostent **, struct sou *);
 static int flushroutes(int, char *[], int);  static int flushroutes(int, char *const [], int);
 static int prefixlen(const char *);  static int prefixlen(const char *, struct sou *);
 #ifndef SMALL  #ifndef SMALL
 static void interfaces(void);  static void interfaces(void);
 static void monitor(void);  static void monitor(void);
 static int print_getmsg(struct rt_msghdr *, int);  static int print_getmsg(struct rt_msghdr *, int, struct sou *);
 static const char *linkstate(struct if_msghdr *);  static const char *linkstate(struct if_msghdr *);
 #endif /* SMALL */  #endif /* SMALL */
 static int rtmsg(int, int );  static int rtmsg(int, int, struct sou *);
 static void mask_addr(void);  static void mask_addr(struct sou *);
 static void print_rtmsg(struct rt_msghdr *, int);  static void print_rtmsg(struct rt_msghdr *, int);
 static void pmsg_common(struct rt_msghdr *);  static void pmsg_common(struct rt_msghdr *);
 static void pmsg_addrs(char *, int);  static void pmsg_addrs(const char *, int);
 static void bprintf(FILE *, int, const char *);  static void bprintf(FILE *, int, const char *);
 static void sodump(sup, const char *);  static void sodump(sup, const char *);
 static void sockaddr(char *, struct sockaddr *);  static void sockaddr(const char *, struct sockaddr *);
   
 union   sockunion {  
         struct  sockaddr sa;  
         struct  sockaddr_in sin;  
 #ifdef INET6  
         struct  sockaddr_in6 sin6;  
 #endif  
         struct  sockaddr_at sat;  
         struct  sockaddr_dl sdl;  
 #ifndef SMALL  
         struct  sockaddr_iso siso;  
 #endif /* SMALL */  
 } so_dst, so_gate, so_mask, so_genmask, so_ifa, so_ifp;  
   
 int     pid, rtm_addrs;  int     pid, rtm_addrs;
 int     sock;  int     sock;
Line 146  usage(const char *cp)
Line 150  usage(const char *cp)
 #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))  #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
   
 int  int
 main(int argc, char **argv)  main(int argc, char * const *argv)
 {  {
         int ch;          int ch;
   
Line 241  main(int argc, char **argv)
Line 245  main(int argc, char **argv)
  * associated with network interfaces.   * associated with network interfaces.
  */   */
 static int  static int
 flushroutes(int argc, char *argv[], int doall)  flushroutes(int argc, char * const argv[], int doall)
 {  {
         struct sockaddr *sa;          struct sockaddr *sa;
         size_t needed;          size_t needed;
Line 253  flushroutes(int argc, char *argv[], int 
Line 257  flushroutes(int argc, char *argv[], int 
         flags = 0;          flags = 0;
         af = AF_UNSPEC;          af = AF_UNSPEC;
         shutdown(sock, SHUT_RD); /* Don't want to read back our messages */          shutdown(sock, SHUT_RD); /* Don't want to read back our messages */
         parse_show_opts(argc, argv, &af, &flags, &afname, 0);          parse_show_opts(argc, argv, &af, &flags, &afname, false);
         mib[0] = CTL_NET;          mib[0] = CTL_NET;
         mib[1] = PF_ROUTE;          mib[1] = PF_ROUTE;
         mib[2] = 0;             /* protocol */          mib[2] = 0;             /* protocol */
Line 419  netmask_length(struct sockaddr *nm, int 
Line 423  netmask_length(struct sockaddr *nm, int 
 }  }
   
 char *  char *
 netmask_string(struct sockaddr *mask, int len, int family)  netmask_string(const struct sockaddr *mask, int len, int family)
 {  {
         static char smask[INET6_ADDRSTRLEN];          static char smask[INET6_ADDRSTRLEN];
         struct sockaddr_in nsin;          struct sockaddr_in nsin;
Line 450  netmask_string(struct sockaddr *mask, in
Line 454  netmask_string(struct sockaddr *mask, in
 }  }
   
 const char *  const char *
 routename(struct sockaddr *sa, struct sockaddr *nm, int flags)  routename(const struct sockaddr *sa, struct sockaddr *nm, int flags)
 {  {
         const char *cp;          const char *cp;
         static char line[50];          static char line[50];
Line 477  routename(struct sockaddr *sa, struct so
Line 481  routename(struct sockaddr *sa, struct so
         else switch (sa->sa_family) {          else switch (sa->sa_family) {
   
         case AF_INET:          case AF_INET:
                 in = ((struct sockaddr_in *)sa)->sin_addr;                  in = ((const struct sockaddr_in *)sa)->sin_addr;
                 nml = netmask_length(nm, AF_INET);                  nml = netmask_length(nm, AF_INET);
   
                 cp = 0;                  cp = 0;
Line 511  routename(struct sockaddr *sa, struct so
Line 515  routename(struct sockaddr *sa, struct so
                 break;                  break;
   
         case AF_LINK:          case AF_LINK:
                 return (link_ntoa((struct sockaddr_dl *)sa));                  return link_ntoa((const struct sockaddr_dl *)sa);
   
 #ifdef INET6  #ifdef INET6
         case AF_INET6:          case AF_INET6:
Line 563  routename(struct sockaddr *sa, struct so
Line 567  routename(struct sockaddr *sa, struct so
 #ifndef SMALL  #ifndef SMALL
         case AF_ISO:          case AF_ISO:
                 (void)snprintf(line, sizeof line, "iso %s",                  (void)snprintf(line, sizeof line, "iso %s",
                     iso_ntoa(&((struct sockaddr_iso *)sa)->siso_addr));                      iso_ntoa(&((const struct sockaddr_iso *)sa)->siso_addr));
                 break;                  break;
   
         case AF_APPLETALK:          case AF_APPLETALK:
                 (void)snprintf(line, sizeof(line), "atalk %d.%d",                  (void)snprintf(line, sizeof(line), "atalk %d.%d",
                     ((struct sockaddr_at *)sa)->sat_addr.s_net,                      ((const struct sockaddr_at *)sa)->sat_addr.s_net,
                     ((struct sockaddr_at *)sa)->sat_addr.s_node);                      ((const struct sockaddr_at *)sa)->sat_addr.s_node);
                 break;                  break;
 #endif /* SMALL */  #endif /* SMALL */
   
Line 579  routename(struct sockaddr *sa, struct so
Line 583  routename(struct sockaddr *sa, struct so
                 break;                  break;
   
         }          }
         return (line);          return line;
 }  }
   
 /*  /*
Line 587  routename(struct sockaddr *sa, struct so
Line 591  routename(struct sockaddr *sa, struct so
  * The address is assumed to be that of a net or subnet, not a host.   * The address is assumed to be that of a net or subnet, not a host.
  */   */
 const char *  const char *
 netname(struct sockaddr *sa, struct sockaddr *nm)  netname(const struct sockaddr *sa, struct sockaddr *nm)
 {  {
         const char *cp = 0;          const char *cp = 0;
         static char line[50];          static char line[50];
Line 600  netname(struct sockaddr *sa, struct sock
Line 604  netname(struct sockaddr *sa, struct sock
         switch (sa->sa_family) {          switch (sa->sa_family) {
   
         case AF_INET:          case AF_INET:
                 in = ((struct sockaddr_in *)sa)->sin_addr;                  in = ((const struct sockaddr_in *)sa)->sin_addr;
                 i = ntohl(in.s_addr);                  i = ntohl(in.s_addr);
                 nml = netmask_length(nm, AF_INET);                  nml = netmask_length(nm, AF_INET);
                 if (i == 0) {                  if (i == 0) {
Line 658  netname(struct sockaddr *sa, struct sock
Line 662  netname(struct sockaddr *sa, struct sock
                 break;                  break;
   
         case AF_LINK:          case AF_LINK:
                 return (link_ntoa((struct sockaddr_dl *)sa));                  return link_ntoa((const struct sockaddr_dl *)sa);
   
 #ifdef INET6  #ifdef INET6
         case AF_INET6:          case AF_INET6:
Line 702  netname(struct sockaddr *sa, struct sock
Line 706  netname(struct sockaddr *sa, struct sock
 #ifndef SMALL  #ifndef SMALL
         case AF_ISO:          case AF_ISO:
                 (void)snprintf(line, sizeof line, "iso %s",                  (void)snprintf(line, sizeof line, "iso %s",
                     iso_ntoa(&((struct sockaddr_iso *)sa)->siso_addr));                      iso_ntoa(&((const struct sockaddr_iso *)sa)->siso_addr));
                 break;                  break;
   
         case AF_APPLETALK:          case AF_APPLETALK:
                 (void)snprintf(line, sizeof(line), "atalk %d.%d",                  (void)snprintf(line, sizeof(line), "atalk %d.%d",
                     ((struct sockaddr_at *)sa)->sat_addr.s_net,                      ((const struct sockaddr_at *)sa)->sat_addr.s_net,
                     ((struct sockaddr_at *)sa)->sat_addr.s_node);                      ((const struct sockaddr_at *)sa)->sat_addr.s_node);
                 break;                  break;
 #endif /* SMALL */  #endif /* SMALL */
   
Line 717  netname(struct sockaddr *sa, struct sock
Line 721  netname(struct sockaddr *sa, struct sock
                         sa->sa_family, any_ntoa(sa));                          sa->sa_family, any_ntoa(sa));
                 break;                  break;
         }          }
         return (line);          return line;
 }  }
   
 static const char *  static const char *
Line 737  route_strerror(int error)
Line 741  route_strerror(int error)
 }  }
   
 static void  static void
 set_metric(char *value, int key)  set_metric(const char *value, int key)
 {  {
         int flag = 0;          int flag = 0;
         u_long noval, *valp = &noval;          u_long noval, *valp = &noval;
Line 758  set_metric(char *value, int key)
Line 762  set_metric(char *value, int key)
                 rt_metrics.rmx_locks |= flag;                  rt_metrics.rmx_locks |= flag;
         if (locking)          if (locking)
                 locking = 0;                  locking = 0;
         *valp = atoi(value);          *valp = strtoul(value, NULL, 0);
 }  }
   
 static int  static int
 newroute(int argc, char **argv)  newroute(int argc, char *const *argv)
 {  {
         const char *cmd, *dest = "", *gateway = "";          const char *cmd, *dest = "", *gateway = "";
         int ishost = 0, ret, attempts, oerrno, flags = RTF_STATIC;          int ishost = 0, ret, attempts, oerrno, flags = RTF_STATIC;
         int key;          int key;
         struct hostent *hp = 0;          struct hostent *hp = 0;
           struct sou sou, *soup = &sou;
   
           memset(&sou, 0, sizeof(sou));
   
         cmd = argv[0];          cmd = argv[0];
         af = AF_UNSPEC;          af = AF_UNSPEC;
Line 866  newroute(int argc, char **argv)
Line 873  newroute(int argc, char **argv)
                         case K_IFA:                          case K_IFA:
                                 if (!--argc)                                  if (!--argc)
                                         usage(1+*argv);                                          usage(1+*argv);
                                 (void)getaddr(RTA_IFA, *++argv, 0);                                  (void)getaddr(RTA_IFA, *++argv, 0, soup);
                                 break;                                  break;
                         case K_IFP:                          case K_IFP:
                                 if (!--argc)                                  if (!--argc)
                                         usage(1+*argv);                                          usage(1+*argv);
                                 (void)getaddr(RTA_IFP, *++argv, 0);                                  (void)getaddr(RTA_IFP, *++argv, 0, soup);
                                 break;                                  break;
                         case K_GENMASK:                          case K_GENMASK:
                                 if (!--argc)                                  if (!--argc)
                                         usage(1+*argv);                                          usage(1+*argv);
                                 (void)getaddr(RTA_GENMASK, *++argv, 0);                                  (void)getaddr(RTA_GENMASK, *++argv, 0, soup);
                                 break;                                  break;
                         case K_GATEWAY:                          case K_GATEWAY:
                                 if (!--argc)                                  if (!--argc)
                                         usage(1+*argv);                                          usage(1+*argv);
                                 (void)getaddr(RTA_GATEWAY, *++argv, 0);                                  (void)getaddr(RTA_GATEWAY, *++argv, 0, soup);
                                 break;                                  break;
                         case K_DST:                          case K_DST:
                                 if (!--argc)                                  if (!--argc)
                                         usage(1+*argv);                                          usage(1+*argv);
                                 ishost = getaddr(RTA_DST, *++argv, &hp);                                  ishost = getaddr(RTA_DST, *++argv, &hp, soup);
                                 dest = *argv;                                  dest = *argv;
                                 break;                                  break;
                         case K_NETMASK:                          case K_NETMASK:
                                 if (!--argc)                                  if (!--argc)
                                         usage(1+*argv);                                          usage(1+*argv);
                                 (void)getaddr(RTA_NETMASK, *++argv, 0);                                  (void)getaddr(RTA_NETMASK, *++argv, 0, soup);
                                 /* FALLTHROUGH */                                  /* FALLTHROUGH */
                         case K_NET:                          case K_NET:
                                 forcenet++;                                  forcenet++;
Line 900  newroute(int argc, char **argv)
Line 907  newroute(int argc, char **argv)
                         case K_PREFIXLEN:                          case K_PREFIXLEN:
                                 if (!--argc)                                  if (!--argc)
                                         usage(1+*argv);                                          usage(1+*argv);
                                 ishost = prefixlen(*++argv);                                  ishost = prefixlen(*++argv, soup);
                                 break;                                  break;
                         case K_MTU:                          case K_MTU:
                         case K_HOPCOUNT:                          case K_HOPCOUNT:
Line 920  newroute(int argc, char **argv)
Line 927  newroute(int argc, char **argv)
                 } else {                  } else {
                         if ((rtm_addrs & RTA_DST) == 0) {                          if ((rtm_addrs & RTA_DST) == 0) {
                                 dest = *argv;                                  dest = *argv;
                                 ishost = getaddr(RTA_DST, *argv, &hp);                                  ishost = getaddr(RTA_DST, *argv, &hp, soup);
                         } else if ((rtm_addrs & RTA_GATEWAY) == 0) {                          } else if ((rtm_addrs & RTA_GATEWAY) == 0) {
                                 gateway = *argv;                                  gateway = *argv;
                                 (void)getaddr(RTA_GATEWAY, *argv, &hp);                                  (void)getaddr(RTA_GATEWAY, *argv, &hp, soup);
                         } else {                          } else {
                                 ret = atoi(*argv);                                  ret = atoi(*argv);
   
Line 947  newroute(int argc, char **argv)
Line 954  newroute(int argc, char **argv)
                                     iflag = 0;                                      iflag = 0;
                                     continue;                                      continue;
                                 }                                  }
                                 (void)getaddr(RTA_NETMASK, *argv, 0);                                  (void)getaddr(RTA_NETMASK, *argv, 0, soup);
                         }                          }
                 }                  }
         }          }
Line 964  newroute(int argc, char **argv)
Line 971  newroute(int argc, char **argv)
                 flags |= RTF_GATEWAY;                  flags |= RTF_GATEWAY;
         for (attempts = 1; ; attempts++) {          for (attempts = 1; ; attempts++) {
                 errno = 0;                  errno = 0;
                 if ((ret = rtmsg(*cmd, flags)) == 0)                  if ((ret = rtmsg(*cmd, flags, soup)) == 0)
                         break;                          break;
                 if (errno != ENETUNREACH && errno != ESRCH)                  if (errno != ENETUNREACH && errno != ESRCH)
                         break;                          break;
                 if (af == AF_INET && *gateway && hp && hp->h_addr_list[1]) {                  if (af == AF_INET && *gateway && hp && hp->h_addr_list[1]) {
                         hp->h_addr_list++;                          hp->h_addr_list++;
                         memmove(&so_gate.sin.sin_addr, hp->h_addr_list[0],                          memmove(&soup->so_gate.sin.sin_addr, hp->h_addr_list[0],
                             hp->h_length);                              hp->h_length);
                 } else                  } else
                         break;                          break;
         }          }
         if (*cmd == 'g')          if (*cmd == 'g')
                 return (ret != 0);                  return ret != 0;
         if (!qflag) {          if (!qflag) {
                 oerrno = errno;                  oerrno = errno;
                 (void)printf("%s %s %s", cmd, ishost? "host" : "net", dest);                  (void)printf("%s %s %s", cmd, ishost? "host" : "net", dest);
Line 984  newroute(int argc, char **argv)
Line 991  newroute(int argc, char **argv)
                         (void)printf(": gateway %s", gateway);                          (void)printf(": gateway %s", gateway);
                         if (attempts > 1 && ret == 0 && af == AF_INET)                          if (attempts > 1 && ret == 0 && af == AF_INET)
                             (void)printf(" (%s)",                              (void)printf(" (%s)",
                                 inet_ntoa(so_gate.sin.sin_addr));                                  inet_ntoa(soup->so_gate.sin.sin_addr));
                 }                  }
                 if (ret == 0)                  if (ret == 0)
                         (void)printf("\n");                          (void)printf("\n");
                 else                  else
                         (void)printf(": %s\n", route_strerror(oerrno));                          (void)printf(": %s\n", route_strerror(oerrno));
         }          }
         return (ret != 0);          return ret != 0;
 }  }
   
 static void  static void
 inet_makenetandmask(u_int32_t net, struct sockaddr_in *isin)  inet_makenetandmask(const u_int32_t net, struct sockaddr_in * const isin,
       struct sou *soup)
 {  {
           struct sockaddr_in *sin;
         u_int32_t addr, mask = 0;          u_int32_t addr, mask = 0;
         char *cp;          char *cp;
   
Line 1042  inet_makenetandmask(u_int32_t net, struc
Line 1051  inet_makenetandmask(u_int32_t net, struc
                         mask = -1;                          mask = -1;
         }          }
         isin->sin_addr.s_addr = htonl(addr);          isin->sin_addr.s_addr = htonl(addr);
         isin = &so_mask.sin;          sin = &soup->so_mask.sin;
         isin->sin_addr.s_addr = htonl(mask);          sin->sin_addr.s_addr = htonl(mask);
         isin->sin_len = 0;          sin->sin_len = 0;
         isin->sin_family = 0;          sin->sin_family = 0;
         cp = (char *)(&isin->sin_addr + 1);          cp = (char *)(&sin->sin_addr + 1);
         while (*--cp == 0 && cp > (char *)isin)          while (*--cp == 0 && cp > (char *)sin)
                 ;                  ;
         isin->sin_len = 1 + cp - (char *)isin;          sin->sin_len = 1 + cp - (char *)sin;
         isin->sin_family = AF_INET;          sin->sin_family = AF_INET;
 }  }
   
 #ifdef INET6  #ifdef INET6
Line 1058  inet_makenetandmask(u_int32_t net, struc
Line 1067  inet_makenetandmask(u_int32_t net, struc
  * XXX the function may need more improvement...   * XXX the function may need more improvement...
  */   */
 static int  static int
 inet6_makenetandmask(struct sockaddr_in6 *sin6)  inet6_makenetandmask(const struct sockaddr_in6 * const sin6, struct sou *soup)
 {  {
         const char *plen;          const char *plen;
         struct in6_addr in6;          struct in6_addr in6;
Line 1078  inet6_makenetandmask(struct sockaddr_in6
Line 1087  inet6_makenetandmask(struct sockaddr_in6
                 return 1;                  return 1;
         else {          else {
                 rtm_addrs |= RTA_NETMASK;                  rtm_addrs |= RTA_NETMASK;
                 (void)prefixlen(plen);                  (void)prefixlen(plen, soup);
                 return 0;                  return 0;
         }          }
 }  }
Line 1089  inet6_makenetandmask(struct sockaddr_in6
Line 1098  inet6_makenetandmask(struct sockaddr_in6
  * returning 1 if a host address, 0 if a network address.   * returning 1 if a host address, 0 if a network address.
  */   */
 static int  static int
 getaddr(int which, char *s, struct hostent **hpp)  getaddr(int which, const char *s, struct hostent **hpp, struct sou *soup)
 {  {
         sup su;          sup su;
         struct hostent *hp;          struct hostent *hp;
Line 1106  getaddr(int which, char *s, struct hoste
Line 1115  getaddr(int which, char *s, struct hoste
         rtm_addrs |= which;          rtm_addrs |= which;
         switch (which) {          switch (which) {
         case RTA_DST:          case RTA_DST:
                 su = &so_dst;                  su = &soup->so_dst;
                 break;                  break;
         case RTA_GATEWAY:          case RTA_GATEWAY:
                 su = &so_gate;                  su = &soup->so_gate;
                 break;                  break;
         case RTA_NETMASK:          case RTA_NETMASK:
                 su = &so_mask;                  su = &soup->so_mask;
                 break;                  break;
         case RTA_GENMASK:          case RTA_GENMASK:
                 su = &so_genmask;                  su = &soup->so_genmask;
                 break;                  break;
         case RTA_IFP:          case RTA_IFP:
                 su = &so_ifp;                  su = &soup->so_ifp;
                 afamily = AF_LINK;                  afamily = AF_LINK;
                 break;                  break;
         case RTA_IFA:          case RTA_IFA:
                 su = &so_ifa;                  su = &soup->so_ifa;
                 su->sa.sa_family = af;                  su->sa.sa_family = af;
                 break;                  break;
         default:          default:
Line 1136  getaddr(int which, char *s, struct hoste
Line 1145  getaddr(int which, char *s, struct hoste
                 switch (which) {                  switch (which) {
                 case RTA_DST:                  case RTA_DST:
                         forcenet++;                          forcenet++;
                         (void)getaddr(RTA_NETMASK, s, 0);                          (void)getaddr(RTA_NETMASK, s, 0, soup);
                         break;                          break;
                 case RTA_NETMASK:                  case RTA_NETMASK:
                 case RTA_GENMASK:                  case RTA_GENMASK:
                         su->sa.sa_len = 0;                          su->sa.sa_len = 0;
                 }                  }
                 return (0);                  return 0;
         }          }
         switch (afamily) {          switch (afamily) {
 #ifdef INET6  #ifdef INET6
Line 1187  getaddr(int which, char *s, struct hoste
Line 1196  getaddr(int which, char *s, struct hoste
 #endif  #endif
                 if (hints.ai_flags == AI_NUMERICHOST) {                  if (hints.ai_flags == AI_NUMERICHOST) {
                         if (slash)                          if (slash)
                                 return (prefixlen(slash + 1));                                  return prefixlen(slash + 1, soup);
                         if (which == RTA_DST)                          if (which == RTA_DST)
                                 return (inet6_makenetandmask(&su->sin6));                                  return inet6_makenetandmask(&su->sin6, soup);
                         return (0);                          return 0;
                 } else                  } else
                         return (1);                          return 1;
             }              }
 #endif  #endif
   
Line 1205  getaddr(int which, char *s, struct hoste
Line 1214  getaddr(int which, char *s, struct hoste
                         do {--cp ;} while ((cp > (char *)su) && (*cp == 0));                          do {--cp ;} while ((cp > (char *)su) && (*cp == 0));
                         su->siso.siso_len = 1 + cp - (char *)su;                          su->siso.siso_len = 1 + cp - (char *)su;
                 }                  }
                 return (1);                  return 1;
 #endif /* SMALL */  #endif /* SMALL */
   
         case PF_ROUTE:          case PF_ROUTE:
                 su->sa.sa_len = sizeof(*su);                  su->sa.sa_len = sizeof(*su);
                 sockaddr(s, &su->sa);                  sockaddr(s, &su->sa);
                 return (1);                  return 1;
   
 #ifndef SMALL  #ifndef SMALL
         case AF_APPLETALK:          case AF_APPLETALK:
Line 1234  badataddr:
Line 1243  badataddr:
   
         case AF_LINK:          case AF_LINK:
                 link_addr(s, &su->sdl);                  link_addr(s, &su->sdl);
                 return (1);                  return 1;
   
         case AF_INET:          case AF_INET:
         default:          default:
Line 1249  badataddr:
Line 1258  badataddr:
                 *t = '\0';                  *t = '\0';
                 if (forcenet == 0) {                  if (forcenet == 0) {
                         if ((val = inet_addr(s)) != INADDR_NONE) {                          if ((val = inet_addr(s)) != INADDR_NONE) {
                                 inet_makenetandmask(htonl(val), &su->sin);                                  inet_makenetandmask(htonl(val), &su->sin, soup);
                                 return prefixlen(&t[1]);                                  return prefixlen(&t[1], soup);
                         }                          }
                 } else {                  } else {
                         if ((val = inet_network(s)) != INADDR_NONE) {                          if ((val = inet_network(s)) != INADDR_NONE) {
                                 inet_makenetandmask(val, &su->sin);                                  inet_makenetandmask(val, &su->sin, soup);
                                 return prefixlen(&t[1]);                                  return prefixlen(&t[1], soup);
                         }                          }
                 }                  }
                 *t = '/';                  *t = '/';
Line 1264  badataddr:
Line 1273  badataddr:
             (which != RTA_DST || forcenet == 0)) {              (which != RTA_DST || forcenet == 0)) {
                 val = su->sin.sin_addr.s_addr;                  val = su->sin.sin_addr.s_addr;
                 if (inet_lnaof(su->sin.sin_addr) != INADDR_ANY)                  if (inet_lnaof(su->sin.sin_addr) != INADDR_ANY)
                         return (1);                          return 1;
                 else {                  else {
                         val = ntohl(val);                          val = ntohl(val);
                         goto netdone;                          goto netdone;
Line 1274  badataddr:
Line 1283  badataddr:
             ((np = getnetbyname(s)) != NULL && (val = np->n_net) != 0)) {              ((np = getnetbyname(s)) != NULL && (val = np->n_net) != 0)) {
 netdone:  netdone:
                 if (which == RTA_DST)                  if (which == RTA_DST)
                         inet_makenetandmask(val, &su->sin);                          inet_makenetandmask(val, &su->sin, soup);
                 return (0);                  return 0;
         }          }
         hp = gethostbyname(s);          hp = gethostbyname(s);
         if (hp) {          if (hp) {
                 *hpp = hp;                  *hpp = hp;
                 su->sin.sin_family = hp->h_addrtype;                  su->sin.sin_family = hp->h_addrtype;
                 memmove(&su->sin.sin_addr, hp->h_addr, hp->h_length);                  memmove(&su->sin.sin_addr, hp->h_addr, hp->h_length);
                 return (1);                  return 1;
         }          }
         errx(EXIT_FAILURE, "%s: bad value", s);          errx(EXIT_FAILURE, "%s: bad value", s);
         /*NOTREACHED*/          /*NOTREACHED*/
 }  }
   
 int  int
 prefixlen(const char *s)  prefixlen(const char *s, struct sou *soup)
 {  {
         int len = atoi(s), q, r;          int len = atoi(s), q, r;
         int max;          int max;
Line 1316  prefixlen(const char *s)
Line 1325  prefixlen(const char *s)
         r = len & 7;          r = len & 7;
         switch (af) {          switch (af) {
         case AF_INET:          case AF_INET:
                 memset(&so_mask, 0, sizeof(so_mask));                  memset(&soup->so_mask, 0, sizeof(soup->so_mask));
                 so_mask.sin.sin_family = AF_INET;                  soup->so_mask.sin.sin_family = AF_INET;
                 so_mask.sin.sin_len = sizeof(struct sockaddr_in);                  soup->so_mask.sin.sin_len = sizeof(struct sockaddr_in);
                 so_mask.sin.sin_addr.s_addr = (len == 0 ? 0                  soup->so_mask.sin.sin_addr.s_addr = (len == 0 ? 0
                                 : htonl(0xffffffff << (32 - len)));                                  : htonl(0xffffffff << (32 - len)));
                 break;                  break;
 #ifdef INET6  #ifdef INET6
         case AF_INET6:          case AF_INET6:
                 so_mask.sin6.sin6_family = AF_INET6;                  soup->so_mask.sin6.sin6_family = AF_INET6;
                 so_mask.sin6.sin6_len = sizeof(struct sockaddr_in6);                  soup->so_mask.sin6.sin6_len = sizeof(struct sockaddr_in6);
                 memset((void *)&so_mask.sin6.sin6_addr, 0,                  memset(&soup->so_mask.sin6.sin6_addr, 0,
                         sizeof(so_mask.sin6.sin6_addr));                          sizeof(soup->so_mask.sin6.sin6_addr));
                 if (q > 0)                  if (q > 0)
                         memset((void *)&so_mask.sin6.sin6_addr, 0xff, q);                          memset(&soup->so_mask.sin6.sin6_addr, 0xff, q);
                 if (r > 0)                  if (r > 0)
                         *((u_char *)&so_mask.sin6.sin6_addr + q) =                          *((u_char *)&soup->so_mask.sin6.sin6_addr + q) =
                             (0xff00 >> r) & 0xff;                              (0xff00 >> r) & 0xff;
                 break;                  break;
 #endif  #endif
         }          }
         return (len == max);          return len == max;
 }  }
   
 #ifndef SMALL  #ifndef SMALL
Line 1376  static void
Line 1385  static void
 monitor(void)  monitor(void)
 {  {
         int n;          int n;
         char msg[2048];          union {
                   char msg[2048];
                   struct rt_msghdr hdr;
           } u;
   
         verbose = 1;          verbose = 1;
         if (debugonly) {          if (debugonly) {
Line 1385  monitor(void)
Line 1397  monitor(void)
         }          }
         for(;;) {          for(;;) {
                 time_t now;                  time_t now;
                 n = read(sock, msg, 2048);                  n = read(sock, &u, sizeof(u));
                 now = time(NULL);                  now = time(NULL);
                 (void)printf("got message of size %d on %s", n, ctime(&now));                  (void)printf("got message of size %d on %s", n, ctime(&now));
                 print_rtmsg((struct rt_msghdr *)msg, n);                  print_rtmsg(&u.hdr, n);
         }          }
 }  }
   
Line 1401  struct {
Line 1413  struct {
 } m_rtmsg;  } m_rtmsg;
   
 static int  static int
 rtmsg(int cmd, int flags)  rtmsg(int cmd, int flags, struct sou *soup)
 {  {
         static int seq;          static int seq;
         int rlen;          int rlen;
Line 1422  rtmsg(int cmd, int flags)
Line 1434  rtmsg(int cmd, int flags)
                 cmd = RTM_CHANGE;                  cmd = RTM_CHANGE;
         else if (cmd == 'g') {          else if (cmd == 'g') {
 #ifdef  SMALL  #ifdef  SMALL
                 return (-1);                  return -1;
 #else   /* SMALL */  #else   /* SMALL */
                 cmd = RTM_GET;                  cmd = RTM_GET;
                 if (so_ifp.sa.sa_family == 0) {                  if (soup->so_ifp.sa.sa_family == AF_UNSPEC) {
                         so_ifp.sa.sa_family = AF_LINK;                          soup->so_ifp.sa.sa_family = AF_LINK;
                         so_ifp.sa.sa_len = sizeof(struct sockaddr_dl);                          soup->so_ifp.sa.sa_len = sizeof(struct sockaddr_dl);
                         rtm_addrs |= RTA_IFP;                          rtm_addrs |= RTA_IFP;
                 }                  }
 #endif  /* SMALL */  #endif  /* SMALL */
Line 1443  rtmsg(int cmd, int flags)
Line 1455  rtmsg(int cmd, int flags)
         rtm.rtm_inits = rtm_inits;          rtm.rtm_inits = rtm_inits;
   
         if (rtm_addrs & RTA_NETMASK)          if (rtm_addrs & RTA_NETMASK)
                 mask_addr();                  mask_addr(soup);
         NEXTADDR(RTA_DST, so_dst);          NEXTADDR(RTA_DST, soup->so_dst);
         NEXTADDR(RTA_GATEWAY, so_gate);          NEXTADDR(RTA_GATEWAY, soup->so_gate);
         NEXTADDR(RTA_NETMASK, so_mask);          NEXTADDR(RTA_NETMASK, soup->so_mask);
         NEXTADDR(RTA_GENMASK, so_genmask);          NEXTADDR(RTA_GENMASK, soup->so_genmask);
         NEXTADDR(RTA_IFP, so_ifp);          NEXTADDR(RTA_IFP, soup->so_ifp);
         NEXTADDR(RTA_IFA, so_ifa);          NEXTADDR(RTA_IFA, soup->so_ifa);
         rtm.rtm_msglen = l = cp - (char *)&m_rtmsg;          rtm.rtm_msglen = l = cp - (char *)&m_rtmsg;
         if (verbose && ! shortoutput) {          if (verbose && ! shortoutput) {
                 if (rtm_addrs)                  if (rtm_addrs)
Line 1457  rtmsg(int cmd, int flags)
Line 1469  rtmsg(int cmd, int flags)
                 print_rtmsg(&rtm, l);                  print_rtmsg(&rtm, l);
         }          }
         if (debugonly)          if (debugonly)
                 return (0);                  return 0;
         if ((rlen = write(sock, (char *)&m_rtmsg, l)) < 0) {          if ((rlen = write(sock, (char *)&m_rtmsg, l)) < 0) {
                 warnx("writing to routing socket: %s", route_strerror(errno));                  warnx("writing to routing socket: %s", route_strerror(errno));
                 return (-1);                  return -1;
         }          }
         if (rlen < l) {          if (rlen < l) {
                 warnx("write to routing socket, got %d for rlen", rlen);                  warnx("write to routing socket, got %d for rlen", rlen);
Line 1474  rtmsg(int cmd, int flags)
Line 1486  rtmsg(int cmd, int flags)
                 if (l < 0)                  if (l < 0)
                         err(EXIT_FAILURE, "read from routing socket");                          err(EXIT_FAILURE, "read from routing socket");
                 else                  else
                         return print_getmsg(&rtm, l);                          return print_getmsg(&rtm, l, soup);
         }          }
 #endif  /* SMALL */  #endif  /* SMALL */
 #undef rtm  #undef rtm
         return (0);          return 0;
 }  }
   
 static void  static void
 mask_addr(void)  mask_addr(struct sou *soup)
 {  {
         int olen = so_mask.sa.sa_len;          int olen = soup->so_mask.sa.sa_len;
         char *cp1 = olen + (char *)&so_mask, *cp2;          char *cp1 = olen + (char *)&soup->so_mask, *cp2;
   
         for (so_mask.sa.sa_len = 0; cp1 > (char *)&so_mask; )          for (soup->so_mask.sa.sa_len = 0; cp1 > (char *)&soup->so_mask; )
                 if (*--cp1 != 0) {                  if (*--cp1 != 0) {
                         so_mask.sa.sa_len = 1 + cp1 - (char *)&so_mask;                          soup->so_mask.sa.sa_len = 1 + cp1 - (char *)&soup->so_mask;
                         break;                          break;
                 }                  }
         if ((rtm_addrs & RTA_DST) == 0)          if ((rtm_addrs & RTA_DST) == 0)
                 return;                  return;
         switch (so_dst.sa.sa_family) {          switch (soup->so_dst.sa.sa_family) {
         case AF_INET:          case AF_INET:
 #ifdef INET6  #ifdef INET6
         case AF_INET6:          case AF_INET6:
Line 1506  mask_addr(void)
Line 1518  mask_addr(void)
                 return;                  return;
 #ifndef SMALL  #ifndef SMALL
         case AF_ISO:          case AF_ISO:
                 olen = MIN(so_dst.siso.siso_nlen,                  olen = MIN(soup->so_dst.siso.siso_nlen,
                            MAX(so_mask.sa.sa_len - 6, 0));                             MAX(soup->so_mask.sa.sa_len - 6, 0));
                 break;                  break;
 #endif /* SMALL */  #endif /* SMALL */
         }          }
         cp1 = so_mask.sa.sa_len + 1 + (char *)&so_dst;          cp1 = soup->so_mask.sa.sa_len + 1 + (char *)&soup->so_dst;
         cp2 = so_dst.sa.sa_len + 1 + (char *)&so_dst;          cp2 = soup->so_dst.sa.sa_len + 1 + (char *)&soup->so_dst;
         while (cp2 > cp1)          while (cp2 > cp1)
                 *--cp2 = 0;                  *--cp2 = 0;
         cp2 = so_mask.sa.sa_len + 1 + (char *)&so_mask;          cp2 = soup->so_mask.sa.sa_len + 1 + (char *)&soup->so_mask;
         while (cp1 > so_dst.sa.sa_data)          while (cp1 > soup->so_dst.sa.sa_data)
                 *--cp1 &= *--cp2;                  *--cp1 &= *--cp2;
 #ifndef SMALL  #ifndef SMALL
         switch (so_dst.sa.sa_family) {          switch (soup->so_dst.sa.sa_family) {
         case AF_ISO:          case AF_ISO:
                 so_dst.siso.siso_nlen = olen;                  soup->so_dst.siso.siso_nlen = olen;
                 break;                  break;
         }          }
 #endif /* SMALL */  #endif /* SMALL */
Line 1719  print_rtmsg(struct rt_msghdr *rtm, int m
Line 1731  print_rtmsg(struct rt_msghdr *rtm, int m
   
 #ifndef SMALL  #ifndef SMALL
 static int  static int
 print_getmsg(struct rt_msghdr *rtm, int msglen)  print_getmsg(struct rt_msghdr *rtm, int msglen, struct sou *soup)
 {  {
         struct sockaddr *dst = NULL, *gate = NULL, *mask = NULL, *ifa = NULL;          struct sockaddr *dst = NULL, *gate = NULL, *mask = NULL, *ifa = NULL;
         struct sockaddr_dl *ifp = NULL;          struct sockaddr_dl *ifp = NULL;
Line 1729  print_getmsg(struct rt_msghdr *rtm, int 
Line 1741  print_getmsg(struct rt_msghdr *rtm, int 
   
         if (! shortoutput)          if (! shortoutput)
                 (void)printf("   route to: %s\n",                  (void)printf("   route to: %s\n",
                     routename((struct sockaddr *) &so_dst, NULL, RTF_HOST));                      routename(&soup->so_dst.sa, NULL, RTF_HOST));
         if (rtm->rtm_version != RTM_VERSION) {          if (rtm->rtm_version != RTM_VERSION) {
                 warnx("routing message version %d not understood",                  warnx("routing message version %d not understood",
                     rtm->rtm_version);                      rtm->rtm_version);
Line 1789  print_getmsg(struct rt_msghdr *rtm, int 
Line 1801  print_getmsg(struct rt_msghdr *rtm, int 
                 name = routename(gate, NULL, RTF_HOST);                  name = routename(gate, NULL, RTF_HOST);
                 if (shortoutput) {                  if (shortoutput) {
                         if (*name == '\0')                          if (*name == '\0')
                                 return (1);                                  return 1;
                         (void)printf("%s\n", name);                          (void)printf("%s\n", name);
                 } else                  } else
                         (void)printf("    gateway: %s\n", name);                          (void)printf("    gateway: %s\n", name);
Line 1827  print_getmsg(struct rt_msghdr *rtm, int 
Line 1839  print_getmsg(struct rt_msghdr *rtm, int 
 #define RTA_IGN (RTA_DST|RTA_GATEWAY|RTA_NETMASK|RTA_IFP|RTA_IFA|RTA_BRD)  #define RTA_IGN (RTA_DST|RTA_GATEWAY|RTA_NETMASK|RTA_IFP|RTA_IFA|RTA_BRD)
   
         if (shortoutput)          if (shortoutput)
                 return ((rtm->rtm_addrs & RTF_GATEWAY) == 0);                  return (rtm->rtm_addrs & RTF_GATEWAY) == 0;
         else if (verbose)          else if (verbose)
                 pmsg_common(rtm);                  pmsg_common(rtm);
         else if (rtm->rtm_addrs &~ RTA_IGN) {          else if (rtm->rtm_addrs &~ RTA_IGN) {
Line 1847  pmsg_common(struct rt_msghdr *rtm)
Line 1859  pmsg_common(struct rt_msghdr *rtm)
         bprintf(stdout, rtm->rtm_rmx.rmx_locks, metricnames);          bprintf(stdout, rtm->rtm_rmx.rmx_locks, metricnames);
         (void)printf(" inits: ");          (void)printf(" inits: ");
         bprintf(stdout, rtm->rtm_inits, metricnames);          bprintf(stdout, rtm->rtm_inits, metricnames);
         pmsg_addrs(((char *)(rtm + 1)), rtm->rtm_addrs);          pmsg_addrs((char *)(rtm + 1), rtm->rtm_addrs);
 }  }
   
 static void  static void
 pmsg_addrs(char *cp, int addrs)  extract_addrs(const char *cp, int addrs, const struct sockaddr *sa[], int *nmfp)
 {  {
         struct sockaddr *sa[RTAX_MAX];          int i, nmf = -1;
   
           for (i = 0; i < RTAX_MAX; i++) {
                   if ((1 << i) & addrs) {
                           sa[i] = (const struct sockaddr *)cp;
                           if ((i == RTAX_DST || i == RTAX_IFA) &&
                               nmf == -1)
                                   nmf = sa[i]->sa_family;
                           ADVANCE(cp, sa[i]);
                   } else
                           sa[i] = NULL;
           }
   
           if (nmfp != NULL)
                   *nmfp = nmf;
   }
   
   static void
   pmsg_addrs(const char *cp, int addrs)
   {
           const struct sockaddr *sa[RTAX_MAX];
         int i, nmf;          int i, nmf;
   
         if (addrs != 0) {          if (addrs != 0) {
                 (void)printf("\nsockaddrs: ");                  (void)printf("\nsockaddrs: ");
                 bprintf(stdout, addrs, addrnames);                  bprintf(stdout, addrs, addrnames);
                 (void)putchar('\n');                  (void)putchar('\n');
                 nmf = -1;                  extract_addrs(cp, addrs, sa, &nmf);
                 for (i = 0; i < RTAX_MAX; i++) {  
                         if ((1 << i) & addrs) {  
                                 sa[i] = (struct sockaddr *)cp;  
                                 if ((i == RTAX_DST || i == RTAX_IFA) &&  
                                     nmf == -1)  
                                         nmf = sa[i]->sa_family;  
                                 ADVANCE(cp, sa[i]);  
                         } else  
                                 sa[i] = NULL;  
                 }  
                 for (i = 0; i < RTAX_MAX; i++) {                  for (i = 0; i < RTAX_MAX; i++) {
                         if (sa[i] != NULL) {                          if (sa[i] == NULL)
                                 if (i == RTAX_NETMASK && sa[i]->sa_len)                                  continue;
                                         (void)printf(" %s",  
                                             netmask_string(sa[i], -1, nmf));                          if (i == RTAX_NETMASK && sa[i]->sa_len)
                                 else                                  (void)printf(" %s",
                                         (void)printf(" %s",                                      netmask_string(sa[i], -1, nmf));
                                             routename(sa[i], NULL, RTF_HOST));                          else
                         }                                  (void)printf(" %s",
                                       routename(sa[i], NULL, RTF_HOST));
                 }                  }
         }          }
         (void)putchar('\n');          (void)putchar('\n');
Line 1914  bprintf(FILE *fp, int b, const char *f)
Line 1937  bprintf(FILE *fp, int b, const char *f)
 }  }
   
 int  int
 keyword(char *cp)  keyword(const char *cp)
 {  {
         struct keytab *kt = keywords;          struct keytab *kt = keywords;
   
Line 1975  sodump(sup su, const char *which)
Line 1998  sodump(sup su, const char *which)
 #define DELIM   (4*2)  #define DELIM   (4*2)
   
 static void  static void
 sockaddr(char *addr, struct sockaddr *sa)  sockaddr(const char *addr, struct sockaddr *sa)
 {  {
         char *cp = (char *)sa;          char *cp = (char *)sa;
         int size = sa->sa_len;          int size = sa->sa_len;

Legend:
Removed from v.1.106  
changed lines
  Added in v.1.106.12.2

CVSweb <webmaster@jp.NetBSD.org>