Changeset 2a08d43 in rtems-libbsd


Ignore:
Timestamp:
Oct 15, 2013, 2:39:53 PM (6 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
4.11, 5283630d2c9d40deb0183696d278e02644fe4326, freebsd-9.3, bc2ba9a9cdc7381c2a4f2ae6ee303be636f31368
Children:
dfc416e
Parents:
ffcd542
git-author:
Sebastian Huber <sebastian.huber@…> (10/15/13 14:39:53)
git-committer:
Sebastian Huber <sebastian.huber@…> (10/31/13 12:18:48)
Message:

ROUTE(8): Add and use context

There is no point in aiming for long term FreeBSD compatibility here.
The issues must be fixed upstream and then move back to the RTEMS port.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • freebsd/sbin/route/route.c

    rffcd542 r2a08d43  
    7373#include <ifaddrs.h>
    7474
    75 struct keytab {
     75static const struct keytab {
    7676        char    *kt_cp;
    7777        int     kt_i;
     
    8181};
    8282
    83 struct  ortentry route;
    84 union   sockunion {
    85         struct  sockaddr sa;
    86         struct  sockaddr_in sin;
     83struct rt_ctx {
     84        struct  ortentry route;
     85        union   sockunion {
     86                struct  sockaddr sa;
     87                struct  sockaddr_in sin;
    8788#ifdef INET6
    88         struct  sockaddr_in6 sin6;
     89                struct  sockaddr_in6 sin6;
    8990#endif
    90         struct  sockaddr_at sat;
    91         struct  sockaddr_dl sdl;
    92         struct  sockaddr_inarp sinarp;
    93         struct  sockaddr_storage ss; /* added to avoid memory overrun */
    94 } so_dst, so_gate, so_mask, so_genmask, so_ifa, so_ifp;
     91                struct  sockaddr_at sat;
     92                struct  sockaddr_dl sdl;
     93                struct  sockaddr_inarp sinarp;
     94                struct  sockaddr_storage ss; /* added to avoid memory overrun */
     95        } so_dst, so_gate, so_mask, so_genmask, so_ifa, so_ifp;
     96
     97        int     pid, rtm_addrs;
     98        int     s;
     99        int     forcehost, forcenet, nflag, af, qflag, tflag;
     100        int     iflag, verbose, aflen;
     101        int     locking, lockrest, debugonly;
     102        struct  rt_metrics rt_metrics;
     103        u_long  rtm_inits;
     104        uid_t   uid;
     105        char    domain[MAXHOSTNAMELEN + 1];
     106        int     domain_initialized;
     107        int     rtm_seq;
     108        char    rt_line[MAXHOSTNAMELEN + 1];
     109        char    net_line[MAXHOSTNAMELEN + 1];
     110        struct {
     111                struct  rt_msghdr m_rtm;
     112                char    m_space[512];
     113        } m_rtmsg;
     114};
     115
     116struct rt_ctx rt_ctx;
    95117
    96118typedef union sockunion *sup;
    97 int     pid, rtm_addrs;
    98 int     s;
    99 int     forcehost, forcenet, doflush, nflag, af, qflag, tflag, keyword();
    100 int     iflag, verbose, aflen = sizeof (struct sockaddr_in);
    101 int     locking, lockrest, debugonly;
    102 struct  rt_metrics rt_metrics;
    103 u_long  rtm_inits;
    104 uid_t   uid;
    105 int     atalk_aton(const char *, struct at_addr *);
    106 char    *atalk_ntoa(struct at_addr);
    107 const char      *routename(), *netname();
    108 void    flushroutes(), newroute(), monitor(), sockaddr(), sodump(), bprintf();
    109 void    print_getmsg(), print_rtmsg(), pmsg_common(), pmsg_addrs(), mask_addr();
     119
     120static int      keyword();
     121static int      atalk_aton(const char *, struct at_addr *);
     122static char     *atalk_ntoa(struct at_addr, char [20]);
     123static const char       *routename(), *netname();
     124static void     interfaces(struct rt_ctx *c);
     125static void     set_metric();
     126static void     flushroutes(), newroute(), monitor(), sockaddr(), sodump(), bprintf();
     127static void     print_getmsg(), print_rtmsg(), pmsg_common(), pmsg_addrs(), mask_addr();
     128static void     inet_makenetandmask();
    110129#ifdef INET6
    111 static int inet6_makenetandmask(struct sockaddr_in6 *, char *);
     130static int      inet6_makenetandmask(struct sockaddr_in6 *, char *);
    112131#endif
    113 int     getaddr(), rtmsg(), x25_makemask();
    114 int     prefixlen();
    115 extern  char *iso_ntoa();
    116 
    117 void usage(const char *) __dead2;
     132static int      getaddr(), rtmsg();
     133static int      prefixlen();
     134extern char     *iso_ntoa();
     135
     136static void usage(const char *) __dead2;
    118137
    119138void
     
    145164        char **argv;
    146165{
     166        struct rt_ctx *c;
    147167        int ch;
    148168#ifdef __rtems__
     
    156176#endif /* __rtems__ */
    157177
     178        c = &rt_ctx;
     179        c->aflen = sizeof (struct sockaddr_in);
     180
    158181        if (argc < 2)
    159182                usage((char *)NULL);
     
    162185                switch(ch) {
    163186                case 'n':
    164                         nflag = 1;
     187                        c->nflag = 1;
    165188                        break;
    166189                case 'q':
    167                         qflag = 1;
     190                        c->qflag = 1;
    168191                        break;
    169192                case 'v':
    170                         verbose = 1;
     193                        c->verbose = 1;
    171194                        break;
    172195                case 't':
    173                         tflag = 1;
     196                        c->tflag = 1;
    174197                        break;
    175198                case 'd':
    176                         debugonly = 1;
     199                        c->debugonly = 1;
    177200                        break;
    178201                case '?':
     
    183206        argv += optind;
    184207
    185         pid = getpid();
    186         uid = geteuid();
    187         if (tflag)
    188                 s = open(_PATH_DEVNULL, O_WRONLY, 0);
     208        c->pid = getpid();
     209        c->uid = geteuid();
     210        if (c->tflag)
     211                c->s = open(_PATH_DEVNULL, O_WRONLY, 0);
    189212        else
    190                 s = socket(PF_ROUTE, SOCK_RAW, 0);
    191         if (s < 0)
     213                c->s = socket(PF_ROUTE, SOCK_RAW, 0);
     214        if (c->s < 0)
    192215                err(EX_OSERR, "socket");
    193216        if (*argv)
     
    195218                case K_GET:
    196219                case K_SHOW:
    197                         uid = 0;
     220                        c->uid = 0;
    198221                        /* FALLTHROUGH */
    199222
     
    202225                case K_DEL:
    203226                case K_DELETE:
    204                         newroute(argc, argv);
     227                        newroute(c, argc, argv);
    205228                        /* NOTREACHED */
    206229
    207230                case K_MONITOR:
    208                         monitor();
     231                        monitor(c);
    209232                        /* NOTREACHED */
    210233
    211234                case K_FLUSH:
    212                         flushroutes(argc, argv);
     235                        flushroutes(c, argc, argv);
    213236                        exit(0);
    214237                        /* NOTREACHED */
     
    223246 */
    224247void
    225 flushroutes(argc, argv)
     248flushroutes(c, argc, argv)
     249        struct rt_ctx *c;
    226250        int argc;
    227251        char *argv[];
     
    232256        struct rt_msghdr *rtm;
    233257
    234         if (uid && !debugonly) {
     258        if (c->uid && !c->debugonly) {
    235259                errx(EX_NOPERM, "must be root to alter routing table");
    236260        }
    237         shutdown(s, SHUT_RD); /* Don't want to read back our messages */
     261        shutdown(c->s, SHUT_RD); /* Don't want to read back our messages */
    238262        if (argc > 1) {
    239263                argv++;
     
    241265                    switch (keyword(*argv + 1)) {
    242266                        case K_INET:
    243                                 af = AF_INET;
     267                                c->af = AF_INET;
    244268                                break;
    245269#ifdef INET6
    246270                        case K_INET6:
    247                                 af = AF_INET6;
     271                                c->af = AF_INET6;
    248272                                break;
    249273#endif
    250274                        case K_ATALK:
    251                                 af = AF_APPLETALK;
     275                                c->af = AF_APPLETALK;
    252276                                break;
    253277                        case K_LINK:
    254                                 af = AF_LINK;
     278                                c->af = AF_LINK;
    255279                                break;
    256280                        default:
     
    280304        }
    281305        lim = buf + needed;
    282         if (verbose)
     306        if (c->verbose)
    283307                (void) printf("Examining routing table from sysctl\n");
    284308        seqno = 0;              /* ??? */
    285309        for (next = buf; next < lim; next += rtm->rtm_msglen) {
    286310                rtm = (struct rt_msghdr *)next;
    287                 if (verbose)
    288                         print_rtmsg(rtm, rtm->rtm_msglen);
     311                if (c->verbose)
     312                        print_rtmsg(c, rtm, rtm->rtm_msglen);
    289313                if ((rtm->rtm_flags & RTF_GATEWAY) == 0)
    290314                        continue;
    291                 if (af) {
     315                if (c->af) {
    292316                        struct sockaddr *sa = (struct sockaddr *)(rtm + 1);
    293317
    294                         if (sa->sa_family != af)
     318                        if (sa->sa_family != c->af)
    295319                                continue;
    296320                }
    297                 if (debugonly)
     321                if (c->debugonly)
    298322                        continue;
    299323                rtm->rtm_type = RTM_DELETE;
    300324                rtm->rtm_seq = seqno;
    301                 rlen = write(s, next, rtm->rtm_msglen);
     325                rlen = write(c->s, next, rtm->rtm_msglen);
    302326                if (rlen < 0 && errno == EPERM)
    303327                        err(1, "write to routing socket");
     
    310334                }
    311335                seqno++;
    312                 if (qflag)
     336                if (c->qflag)
    313337                        continue;
    314                 if (verbose)
    315                         print_rtmsg(rtm, rlen);
     338                if (c->verbose)
     339                        print_rtmsg(c, rtm, rlen);
    316340                else {
    317341                        struct sockaddr *sa = (struct sockaddr *)(rtm + 1);
    318342                        (void) printf("%-20.20s ", rtm->rtm_flags & RTF_HOST ?
    319                             routename(sa) : netname(sa));
     343                            routename(sa) : netname(c, sa));
    320344                        sa = (struct sockaddr *)(SA_SIZE(sa) + (char *)sa);
    321345                        (void) printf("%-20.20s ", routename(sa));
     
    326350
    327351const char *
    328 routename(sa)
     352routename(c, sa)
     353        struct rt_ctx *c;
    329354        struct sockaddr *sa;
    330355{
    331356        char *cp;
    332         static char line[MAXHOSTNAMELEN + 1];
     357        char atalk_buf[20];
    333358        struct hostent *hp;
    334         static char domain[MAXHOSTNAMELEN + 1];
    335         static int first = 1, n;
    336 
    337         if (first) {
    338                 first = 0;
    339                 if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
    340                     (cp = strchr(domain, '.'))) {
    341                         domain[MAXHOSTNAMELEN] = '\0';
    342                         (void) strcpy(domain, cp + 1);
     359        int n;
     360
     361        if (c->domain_initialized) {
     362                c->domain_initialized = 1;
     363                if (gethostname(c->domain, MAXHOSTNAMELEN) == 0 &&
     364                    (cp = strchr(c->domain, '.'))) {
     365                        c->domain[MAXHOSTNAMELEN] = '\0';
     366                        (void) strcpy(c->domain, cp + 1);
    343367                } else
    344                         domain[0] = 0;
     368                        c->domain[0] = 0;
    345369        }
    346370
    347371        if (sa->sa_len == 0)
    348                 strcpy(line, "default");
     372                strcpy(c->rt_line, "default");
    349373        else switch (sa->sa_family) {
    350374
     
    356380                if (in.s_addr == INADDR_ANY || sa->sa_len < 4)
    357381                        cp = "default";
    358                 if (cp == 0 && !nflag) {
     382                if (cp == 0 && !c->nflag) {
    359383                        hp = gethostbyaddr((char *)&in, sizeof (struct in_addr),
    360384                                AF_INET);
    361385                        if (hp) {
    362386                                if ((cp = strchr(hp->h_name, '.')) &&
    363                                     !strcmp(cp + 1, domain))
     387                                    !strcmp(cp + 1, c->domain))
    364388                                        *cp = 0;
    365389                                cp = hp->h_name;
     
    367391                }
    368392                if (cp) {
    369                         strncpy(line, cp, sizeof(line) - 1);
    370                         line[sizeof(line) - 1] = '\0';
     393                        strncpy(c->rt_line, cp, sizeof(c->rt_line) - 1);
     394                        c->rt_line[sizeof(c->rt_line) - 1] = '\0';
    371395                } else
    372                         (void) sprintf(line, "%s", inet_ntoa(in));
     396                        (void) sprintf(c->rt_line, "%s", inet_ntoa(in));
    373397                break;
    374398            }
     
    395419                }
    396420#endif
    397                 if (nflag)
     421                if (c->nflag)
    398422                        niflags |= NI_NUMERICHOST;
    399423                if (getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len,
    400                     line, sizeof(line), NULL, 0, niflags) != 0)
    401                         strncpy(line, "invalid", sizeof(line));
    402 
    403                 return(line);
     424                    c->rt_line, sizeof(c->rt_line), NULL, 0, niflags) != 0)
     425                        strncpy(c->rt_line, "invalid", sizeof(c->rt_line));
     426
     427                return(c->rt_line);
    404428        }
    405429#endif
    406430
    407431        case AF_APPLETALK:
    408                 (void) snprintf(line, sizeof(line), "atalk %s",
    409                         atalk_ntoa(((struct sockaddr_at *)sa)->sat_addr));
     432                (void) snprintf(c->rt_line, sizeof(c->rt_line), "atalk %s",
     433                        atalk_ntoa(((struct sockaddr_at *)sa)->sat_addr, atalk_buf));
    410434                break;
    411435
     
    416440            {   u_short *s = (u_short *)sa;
    417441                u_short *slim = s + ((sa->sa_len + 1) >> 1);
    418                 char *cp = line + sprintf(line, "(%d)", sa->sa_family);
    419                 char *cpe = line + sizeof(line);
     442                char *cp = c->rt_line + sprintf(c->rt_line, "(%d)", sa->sa_family);
     443                char *cpe = c->rt_line + sizeof(c->rt_line);
    420444
    421445                while (++s < slim && cp < cpe) /* start with sa->sa_data */
     
    427451            }
    428452        }
    429         return (line);
     453        return (c->rt_line);
    430454}
    431455
     
    435459 */
    436460const char *
    437 netname(sa)
     461netname(c, sa)
     462        struct rt_ctx *c;
    438463        struct sockaddr *sa;
    439464{
    440465        char *cp = 0;
    441         static char line[MAXHOSTNAMELEN + 1];
     466        char atalk_buf[20];
    442467        struct netent *np = 0;
    443468        u_long net, mask;
     
    454479                if (in.s_addr == 0)
    455480                        cp = "default";
    456                 else if (!nflag) {
     481                else if (!c->nflag) {
    457482                        if (IN_CLASSA(i)) {
    458483                                mask = IN_CLASSA_NET;
     
    482507#define C(x)    (unsigned)((x) & 0xff)
    483508                if (cp)
    484                         strncpy(line, cp, sizeof(line));
     509                        strncpy(c->net_line, cp, sizeof(c->net_line));
    485510                else if ((in.s_addr & 0xffffff) == 0)
    486                         (void) sprintf(line, "%u", C(in.s_addr >> 24));
     511                        (void) sprintf(c->net_line, "%u", C(in.s_addr >> 24));
    487512                else if ((in.s_addr & 0xffff) == 0)
    488                         (void) sprintf(line, "%u.%u", C(in.s_addr >> 24),
     513                        (void) sprintf(c->net_line, "%u.%u", C(in.s_addr >> 24),
    489514                            C(in.s_addr >> 16));
    490515                else if ((in.s_addr & 0xff) == 0)
    491                         (void) sprintf(line, "%u.%u.%u", C(in.s_addr >> 24),
     516                        (void) sprintf(c->net_line, "%u.%u.%u", C(in.s_addr >> 24),
    492517                            C(in.s_addr >> 16), C(in.s_addr >> 8));
    493518                else
    494                         (void) sprintf(line, "%u.%u.%u.%u", C(in.s_addr >> 24),
     519                        (void) sprintf(c->net_line, "%u.%u.%u.%u", C(in.s_addr >> 24),
    495520                            C(in.s_addr >> 16), C(in.s_addr >> 8),
    496521                            C(in.s_addr));
     
    520545                }
    521546#endif
    522                 if (nflag)
     547                if (c->nflag)
    523548                        niflags |= NI_NUMERICHOST;
    524549                if (getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len,
    525                     line, sizeof(line), NULL, 0, niflags) != 0)
    526                         strncpy(line, "invalid", sizeof(line));
    527 
    528                 return(line);
     550                    c->net_line, sizeof(c->net_line), NULL, 0, niflags) != 0)
     551                        strncpy(c->net_line, "invalid", sizeof(c->net_line));
     552
     553                return(c->net_line);
    529554        }
    530555#endif
    531556
    532557        case AF_APPLETALK:
    533                 (void) snprintf(line, sizeof(line), "atalk %s",
    534                         atalk_ntoa(((struct sockaddr_at *)sa)->sat_addr));
     558                (void) snprintf(c->net_line, sizeof(c->net_line), "atalk %s",
     559                        atalk_ntoa(((struct sockaddr_at *)sa)->sat_addr, atalk_buf));
    535560                break;
    536561
     
    542567            {   u_short *s = (u_short *)sa->sa_data;
    543568                u_short *slim = s + ((sa->sa_len + 1)>>1);
    544                 char *cp = line + sprintf(line, "af %d:", sa->sa_family);
    545                 char *cpe = line + sizeof(line);
     569                char *cp = c->net_line + sprintf(c->net_line, "af %d:", sa->sa_family);
     570                char *cpe = c->net_line + sizeof(c->net_line);
    546571
    547572                while (s < slim && cp < cpe)
     
    553578            }
    554579        }
    555         return (line);
     580        return (c->net_line);
    556581}
    557582
    558583void
    559 set_metric(value, key)
     584set_metric(c, value, key)
     585        struct rt_ctx *c;
    560586        char *value;
    561587        int key;
     
    565591
    566592        switch (key) {
    567 #define caseof(x, y, z) case x: valp = &rt_metrics.z; flag = y; break
     593#define caseof(x, y, z) case x: valp = &c->rt_metrics.z; flag = y; break
    568594        caseof(K_MTU, RTV_MTU, rmx_mtu);
    569595        caseof(K_HOPCOUNT, RTV_HOPCOUNT, rmx_hopcount);
     
    576602        caseof(K_WEIGHT, RTV_WEIGHT, rmx_weight);
    577603        }
    578         rtm_inits |= flag;
    579         if (lockrest || locking)
    580                 rt_metrics.rmx_locks |= flag;
    581         if (locking)
    582                 locking = 0;
     604        c->rtm_inits |= flag;
     605        if (c->lockrest || c->locking)
     606                c->rt_metrics.rmx_locks |= flag;
     607        if (c->locking)
     608                c->locking = 0;
    583609        *valp = atoi(value);
    584610}
    585611
    586612void
    587 newroute(argc, argv)
     613newroute(c, argc, argv)
     614        struct rt_ctx *c;
    588615        int argc;
    589616        char **argv;
     
    594621        struct hostent *hp = 0;
    595622
    596         if (uid) {
     623        if (c->uid) {
    597624                errx(EX_NOPERM, "must be root to alter routing table");
    598625        }
    599626        cmd = argv[0];
    600627        if (*cmd != 'g' && *cmd != 's')
    601                 shutdown(s, SHUT_RD); /* Don't want to read back our messages */
     628                shutdown(c->s, SHUT_RD); /* Don't want to read back our messages */
    602629
    603630        while (--argc > 0) {
     
    605632                        switch (key = keyword(1 + *argv)) {
    606633                        case K_LINK:
    607                                 af = AF_LINK;
    608                                 aflen = sizeof(struct sockaddr_dl);
     634                                c->af = AF_LINK;
     635                                c->aflen = sizeof(struct sockaddr_dl);
    609636                                break;
    610637                        case K_INET:
    611                                 af = AF_INET;
    612                                 aflen = sizeof(struct sockaddr_in);
     638                                c->af = AF_INET;
     639                                c->aflen = sizeof(struct sockaddr_in);
    613640                                break;
    614641#ifdef INET6
    615642                        case K_INET6:
    616                                 af = AF_INET6;
    617                                 aflen = sizeof(struct sockaddr_in6);
     643                                c->af = AF_INET6;
     644                                c->aflen = sizeof(struct sockaddr_in6);
    618645                                break;
    619646#endif
    620647                        case K_ATALK:
    621                                 af = AF_APPLETALK;
    622                                 aflen = sizeof(struct sockaddr_at);
     648                                c->af = AF_APPLETALK;
     649                                c->aflen = sizeof(struct sockaddr_at);
    623650                                break;
    624651                        case K_SA:
    625                                 af = PF_ROUTE;
    626                                 aflen = sizeof(union sockunion);
     652                                c->af = PF_ROUTE;
     653                                c->aflen = sizeof(union sockunion);
    627654                                break;
    628655                        case K_IFACE:
    629656                        case K_INTERFACE:
    630                                 iflag++;
     657                                c->iflag++;
    631658                                break;
    632659                        case K_NOSTATIC:
     
    634661                                break;
    635662                        case K_LOCK:
    636                                 locking = 1;
     663                                c->locking = 1;
    637664                                break;
    638665                        case K_LOCKREST:
    639                                 lockrest = 1;
     666                                c->lockrest = 1;
    640667                                break;
    641668                        case K_HOST:
    642                                 forcehost++;
     669                                c->forcehost++;
    643670                                break;
    644671                        case K_REJECT:
     
    672699                                if (!--argc)
    673700                                        usage((char *)NULL);
    674                                 (void) getaddr(RTA_IFA, *++argv, 0);
     701                                (void) getaddr(c, RTA_IFA, *++argv, 0);
    675702                                break;
    676703                        case K_IFP:
    677704                                if (!--argc)
    678705                                        usage((char *)NULL);
    679                                 (void) getaddr(RTA_IFP, *++argv, 0);
     706                                (void) getaddr(c, RTA_IFP, *++argv, 0);
    680707                                break;
    681708                        case K_GENMASK:
    682709                                if (!--argc)
    683710                                        usage((char *)NULL);
    684                                 (void) getaddr(RTA_GENMASK, *++argv, 0);
     711                                (void) getaddr(c, RTA_GENMASK, *++argv, 0);
    685712                                break;
    686713                        case K_GATEWAY:
    687714                                if (!--argc)
    688715                                        usage((char *)NULL);
    689                                 (void) getaddr(RTA_GATEWAY, *++argv, 0);
     716                                (void) getaddr(c, RTA_GATEWAY, *++argv, 0);
    690717                                break;
    691718                        case K_DST:
    692719                                if (!--argc)
    693720                                        usage((char *)NULL);
    694                                 ishost = getaddr(RTA_DST, *++argv, &hp);
     721                                ishost = getaddr(c, RTA_DST, *++argv, &hp);
    695722                                dest = *argv;
    696723                                break;
     
    698725                                if (!--argc)
    699726                                        usage((char *)NULL);
    700                                 (void) getaddr(RTA_NETMASK, *++argv, 0);
     727                                (void) getaddr(c, RTA_NETMASK, *++argv, 0);
    701728                                /* FALLTHROUGH */
    702729                        case K_NET:
    703                                 forcenet++;
     730                                c->forcenet++;
    704731                                break;
    705732                        case K_PREFIXLEN:
    706733                                if (!--argc)
    707734                                        usage((char *)NULL);
    708                                 if (prefixlen(*++argv) == -1) {
    709                                         forcenet = 0;
     735                                if (prefixlen(c, *++argv) == -1) {
     736                                        c->forcenet = 0;
    710737                                        ishost = 1;
    711738                                } else {
    712                                         forcenet = 1;
     739                                        c->forcenet = 1;
    713740                                        ishost = 0;
    714741                                }
     
    725752                                if (!--argc)
    726753                                        usage((char *)NULL);
    727                                 set_metric(*++argv, key);
     754                                set_metric(c, *++argv, key);
    728755                                break;
    729756                        default:
     
    731758                        }
    732759                } else {
    733                         if ((rtm_addrs & RTA_DST) == 0) {
     760                        if ((c->rtm_addrs & RTA_DST) == 0) {
    734761                                dest = *argv;
    735                                 ishost = getaddr(RTA_DST, *argv, &hp);
    736                         } else if ((rtm_addrs & RTA_GATEWAY) == 0) {
     762                                ishost = getaddr(c, RTA_DST, *argv, &hp);
     763                        } else if ((c->rtm_addrs & RTA_GATEWAY) == 0) {
    737764                                gateway = *argv;
    738                                 (void) getaddr(RTA_GATEWAY, *argv, &hp);
     765                                (void) getaddr(c, RTA_GATEWAY, *argv, &hp);
    739766                        } else {
    740                                 (void) getaddr(RTA_NETMASK, *argv, 0);
    741                                 forcenet = 1;
     767                                (void) getaddr(c, RTA_NETMASK, *argv, 0);
     768                                c->forcenet = 1;
    742769                        }
    743770                }
    744771        }
    745         if (forcehost) {
     772        if (c->forcehost) {
    746773                ishost = 1;
    747774#ifdef INET6
    748                 if (af == AF_INET6) {
    749                         rtm_addrs &= ~RTA_NETMASK;
    750                                 memset((void *)&so_mask, 0, sizeof(so_mask));
     775                if (c->af == AF_INET6) {
     776                        c->rtm_addrs &= ~RTA_NETMASK;
     777                                memset((void *)&c->so_mask, 0, sizeof(c->so_mask));
    751778                }
    752779#endif
    753780        }
    754         if (forcenet)
     781        if (c->forcenet)
    755782                ishost = 0;
    756783        flags |= RTF_UP;
    757784        if (ishost)
    758785                flags |= RTF_HOST;
    759         if (iflag == 0)
     786        if (c->iflag == 0)
    760787                flags |= RTF_GATEWAY;
    761788        if (proxy) {
    762                 so_dst.sinarp.sin_other = SIN_PROXY;
     789                c->so_dst.sinarp.sin_other = SIN_PROXY;
    763790                flags |= RTF_ANNOUNCE;
    764791        }
    765792        for (attempts = 1; ; attempts++) {
    766793                errno = 0;
    767                 if ((ret = rtmsg(*cmd, flags)) == 0)
     794                if ((ret = rtmsg(c, *cmd, flags)) == 0)
    768795                        break;
    769796                if (errno != ENETUNREACH && errno != ESRCH)
    770797                        break;
    771                 if (af == AF_INET && *gateway && hp && hp->h_addr_list[1]) {
     798                if (c->af == AF_INET && *gateway && hp && hp->h_addr_list[1]) {
    772799                        hp->h_addr_list++;
    773                         memmove(&so_gate.sin.sin_addr, hp->h_addr_list[0],
    774                             MIN(hp->h_length, sizeof(so_gate.sin.sin_addr)));
     800                        memmove(&c->so_gate.sin.sin_addr, hp->h_addr_list[0],
     801                            MIN(hp->h_length, sizeof(c->so_gate.sin.sin_addr)));
    775802                } else
    776803                        break;
     
    778805        if (*cmd == 'g' || *cmd == 's')
    779806                exit(ret != 0);
    780         if (!qflag) {
     807        if (!c->qflag) {
    781808                oerrno = errno;
    782809                (void) printf("%s %s %s", cmd, ishost? "host" : "net", dest);
    783810                if (*gateway) {
    784811                        (void) printf(": gateway %s", gateway);
    785                         if (attempts > 1 && ret == 0 && af == AF_INET)
     812                        if (attempts > 1 && ret == 0 && c->af == AF_INET)
    786813                            (void) printf(" (%s)",
    787                                 inet_ntoa(((struct sockaddr_in *)&route.rt_gateway)->sin_addr));
     814                                inet_ntoa(((struct sockaddr_in *)&c->route.rt_gateway)->sin_addr));
    788815                }
    789816                if (ret == 0) {
     
    818845
    819846void
    820 inet_makenetandmask(net, sin, bits)
     847inet_makenetandmask(c, net, sin, bits)
     848        struct rt_ctx *c;
    821849        u_long net, bits;
    822850        struct sockaddr_in *sin;
     
    825853        char *cp;
    826854
    827         rtm_addrs |= RTA_NETMASK;
     855        c->rtm_addrs |= RTA_NETMASK;
    828856        /*
    829857         * XXX: This approach unable to handle 0.0.0.1/32 correctly
     
    857885
    858886        sin->sin_addr.s_addr = htonl(addr);
    859         sin = &so_mask.sin;
     887        sin = &c->so_mask.sin;
    860888        sin->sin_addr.s_addr = htonl(mask);
    861889        sin->sin_len = 0;
     
    893921        if (!plen || strcmp(plen, "128") == 0)
    894922                return 1;
    895         rtm_addrs |= RTA_NETMASK;
    896         (void)prefixlen(plen);
     923        c->rtm_addrs |= RTA_NETMASK;
     924        (void)prefixlen(c, plen);
    897925        return 0;
    898926}
     
    904932 */
    905933int
    906 getaddr(which, s, hpp)
     934getaddr(c, which, s, hpp)
     935        struct rt_ctx *c;
    907936        int which;
    908937        char *s;
     
    916945        int afamily;  /* local copy of af so we can change it */
    917946
    918         if (af == 0) {
    919                 af = AF_INET;
    920                 aflen = sizeof(struct sockaddr_in);
    921         }
    922         afamily = af;
    923         rtm_addrs |= which;
     947        if (c->af == 0) {
     948                c->af = AF_INET;
     949                c->aflen = sizeof(struct sockaddr_in);
     950        }
     951        afamily = c->af;
     952        c->rtm_addrs |= which;
    924953        switch (which) {
    925954        case RTA_DST:
    926                 su = &so_dst;
     955                su = &c->so_dst;
    927956                break;
    928957        case RTA_GATEWAY:
    929                 su = &so_gate;
    930                 if (iflag) {
     958                su = &c->so_gate;
     959                if (c->iflag) {
    931960                        struct ifaddrs *ifap, *ifa;
    932961                        struct sockaddr_dl *sdl = NULL;
     
    960989                break;
    961990        case RTA_NETMASK:
    962                 su = &so_mask;
     991                su = &c->so_mask;
    963992                break;
    964993        case RTA_GENMASK:
    965                 su = &so_genmask;
     994                su = &c->so_genmask;
    966995                break;
    967996        case RTA_IFP:
    968                 su = &so_ifp;
     997                su = &c->so_ifp;
    969998                afamily = AF_LINK;
    970999                break;
    9711000        case RTA_IFA:
    972                 su = &so_ifa;
     1001                su = &c->so_ifa;
    9731002                break;
    9741003        default:
     
    9761005                /*NOTREACHED*/
    9771006        }
    978         su->sa.sa_len = aflen;
     1007        su->sa.sa_len = c->aflen;
    9791008        su->sa.sa_family = afamily; /* cases that don't want it have left already */
    9801009        if (strcmp(s, "default") == 0) {
     
    9841013                switch (which) {
    9851014                case RTA_DST:
    986                         forcenet++;
     1015                        c->forcenet++;
    9871016#if 0
    9881017                        bzero(su, sizeof(*su)); /* for readability */
    9891018#endif
    990                         (void) getaddr(RTA_NETMASK, s, 0);
     1019                        (void) getaddr(c, RTA_NETMASK, s, 0);
    9911020                        break;
    9921021#if 0
     
    10401069                if (!atalk_aton(s, &su->sat.sat_addr))
    10411070                        errx(EX_NOHOST, "bad address: %s", s);
    1042                 rtm_addrs |= RTA_NETMASK;
    1043                 return(forcehost || su->sat.sat_addr.s_node != 0);
     1071                c->rtm_addrs |= RTA_NETMASK;
     1072                return(c->forcehost || su->sat.sat_addr.s_node != 0);
    10441073
    10451074        case AF_LINK:
     
    10671096                if ((val = inet_network(s)) != INADDR_NONE) {
    10681097                        inet_makenetandmask(
    1069                                 val, &su->sin, strtoul(q+1, 0, 0));
     1098                                c, val, &su->sin, strtoul(q+1, 0, 0));
    10701099                        return (0);
    10711100                }
    10721101                *q = '/';
    10731102        }
    1074         if ((which != RTA_DST || forcenet == 0) &&
     1103        if ((which != RTA_DST || c->forcenet == 0) &&
    10751104            inet_aton(s, &su->sin.sin_addr)) {
    10761105                val = su->sin.sin_addr.s_addr;
    1077                 if (which != RTA_DST || forcehost ||
     1106                if (which != RTA_DST || c->forcehost ||
    10781107                    inet_lnaof(su->sin.sin_addr) != INADDR_ANY)
    10791108                        return (1);
     
    10831112                }
    10841113        }
    1085         if (which == RTA_DST && forcehost == 0 &&
     1114        if (which == RTA_DST && c->forcehost == 0 &&
    10861115            ((val = inet_network(s)) != INADDR_NONE ||
    10871116            ((np = getnetbyname(s)) != NULL && (val = np->n_net) != 0))) {
    10881117netdone:
    1089                 inet_makenetandmask(val, &su->sin, 0);
     1118                inet_makenetandmask(c, val, &su->sin, 0);
    10901119                return (0);
    10911120        }
     
    11021131
    11031132int
    1104 prefixlen(s)
     1133prefixlen(c, s)
     1134        struct rt_ctx *c;
    11051135        char *s;
    11061136{
     
    11091139        char *p;
    11101140
    1111         rtm_addrs |= RTA_NETMASK;       
    1112         switch (af) {
     1141        c->rtm_addrs |= RTA_NETMASK;   
     1142        switch (c->af) {
    11131143#ifdef INET6
    11141144        case AF_INET6:
    11151145                max = 128;
    1116                 p = (char *)&so_mask.sin6.sin6_addr;
     1146                p = (char *)&c->so_mask.sin6.sin6_addr;
    11171147                break;
    11181148#endif
    11191149        case AF_INET:
    11201150                max = 32;
    1121                 p = (char *)&so_mask.sin.sin_addr;
     1151                p = (char *)&c->so_mask.sin.sin_addr;
    11221152                break;
    11231153        default:
     
    11341164        q = len >> 3;
    11351165        r = len & 7;
    1136         so_mask.sa.sa_family = af;
    1137         so_mask.sa.sa_len = aflen;
     1166        c->so_mask.sa.sa_family = c->af;
     1167        c->so_mask.sa.sa_len = c->aflen;
    11381168        memset((void *)p, 0, max / 8);
    11391169        if (q > 0)
     
    11481178
    11491179void
    1150 interfaces()
     1180interfaces(struct rt_ctx *c)
    11511181{
    11521182        size_t needed;
     
    11781208        for (next = buf; next < lim; next += rtm->rtm_msglen) {
    11791209                rtm = (struct rt_msghdr *)next;
    1180                 print_rtmsg(rtm, rtm->rtm_msglen);
     1210                print_rtmsg(c, rtm, rtm->rtm_msglen);
    11811211        }
    11821212}
    11831213
    11841214void
    1185 monitor()
     1215monitor(struct rt_ctx *c)
    11861216{
    11871217        int n;
    11881218        char msg[2048];
    11891219
    1190         verbose = 1;
    1191         if (debugonly) {
    1192                 interfaces();
     1220        c->verbose = 1;
     1221        if (c->debugonly) {
     1222                interfaces(c);
    11931223                exit(0);
    11941224        }
    11951225        for(;;) {
    11961226                time_t now;
    1197                 n = read(s, msg, 2048);
     1227                n = read(c->s, msg, 2048);
    11981228                now = time(NULL);
    11991229                (void) printf("\ngot message of size %d on %s", n, ctime(&now));
    1200                 print_rtmsg((struct rt_msghdr *)msg, n);
    1201         }
    1202 }
    1203 
    1204 struct {
    1205         struct  rt_msghdr m_rtm;
    1206         char    m_space[512];
    1207 } m_rtmsg;
     1230                print_rtmsg(c, (struct rt_msghdr *)msg, n);
     1231        }
     1232}
    12081233
    12091234int
    1210 rtmsg(cmd, flags)
     1235rtmsg(c, cmd, flags)
     1236        struct rt_ctx *c;
    12111237        int cmd, flags;
    12121238{
    1213         static int seq;
    12141239        int rlen;
    1215         char *cp = m_rtmsg.m_space;
     1240        char *cp = c->m_rtmsg.m_space;
    12161241        int l;
    12171242
    12181243#define NEXTADDR(w, u) \
    1219         if (rtm_addrs & (w)) {\
     1244        if (c->rtm_addrs & (w)) {\
    12201245            l = SA_SIZE(&(u.sa)); memmove(cp, &(u), l); cp += l;\
    1221             if (verbose) sodump(&(u),#u);\
     1246            if (c->verbose) sodump(&(u),#u);\
    12221247        }
    12231248
    12241249        errno = 0;
    1225         memset(&m_rtmsg, 0, sizeof(m_rtmsg));
     1250        memset(&c->m_rtmsg, 0, sizeof(c->m_rtmsg));
    12261251        if (cmd == 'a')
    12271252                cmd = RTM_ADD;
     
    12301255        else if (cmd == 'g' || cmd == 's') {
    12311256                cmd = RTM_GET;
    1232                 if (so_ifp.sa.sa_family == 0) {
    1233                         so_ifp.sa.sa_family = AF_LINK;
    1234                         so_ifp.sa.sa_len = sizeof(struct sockaddr_dl);
    1235                         rtm_addrs |= RTA_IFP;
     1257                if (c->so_ifp.sa.sa_family == 0) {
     1258                        c->so_ifp.sa.sa_family = AF_LINK;
     1259                        c->so_ifp.sa.sa_len = sizeof(struct sockaddr_dl);
     1260                        c->rtm_addrs |= RTA_IFP;
    12361261                }
    12371262        } else
    12381263                cmd = RTM_DELETE;
    1239 #define rtm m_rtmsg.m_rtm
     1264#define rtm c->m_rtmsg.m_rtm
    12401265        rtm.rtm_type = cmd;
    12411266        rtm.rtm_flags = flags;
    12421267        rtm.rtm_version = RTM_VERSION;
    1243         rtm.rtm_seq = ++seq;
    1244         rtm.rtm_addrs = rtm_addrs;
    1245         rtm.rtm_rmx = rt_metrics;
    1246         rtm.rtm_inits = rtm_inits;
    1247 
    1248         if (rtm_addrs & RTA_NETMASK)
    1249                 mask_addr();
    1250         NEXTADDR(RTA_DST, so_dst);
    1251         NEXTADDR(RTA_GATEWAY, so_gate);
    1252         NEXTADDR(RTA_NETMASK, so_mask);
    1253         NEXTADDR(RTA_GENMASK, so_genmask);
    1254         NEXTADDR(RTA_IFP, so_ifp);
    1255         NEXTADDR(RTA_IFA, so_ifa);
    1256         rtm.rtm_msglen = l = cp - (char *)&m_rtmsg;
    1257         if (verbose)
    1258                 print_rtmsg(&rtm, l);
    1259         if (debugonly)
     1268        rtm.rtm_seq = ++c->rtm_seq;
     1269        rtm.rtm_addrs = c->rtm_addrs;
     1270        rtm.rtm_rmx = c->rt_metrics;
     1271        rtm.rtm_inits = c->rtm_inits;
     1272
     1273        if (c->rtm_addrs & RTA_NETMASK)
     1274                mask_addr(c);
     1275        NEXTADDR(RTA_DST, c->so_dst);
     1276        NEXTADDR(RTA_GATEWAY, c->so_gate);
     1277        NEXTADDR(RTA_NETMASK, c->so_mask);
     1278        NEXTADDR(RTA_GENMASK, c->so_genmask);
     1279        NEXTADDR(RTA_IFP, c->so_ifp);
     1280        NEXTADDR(RTA_IFA, c->so_ifa);
     1281        rtm.rtm_msglen = l = cp - (char *)&c->m_rtmsg;
     1282        if (c->verbose)
     1283                print_rtmsg(c, &rtm, l);
     1284        if (c->debugonly)
    12601285                return (0);
    1261         if ((rlen = write(s, (char *)&m_rtmsg, l)) < 0) {
     1286        if ((rlen = write(c->s, (char *)&c->m_rtmsg, l)) < 0) {
    12621287                if (errno == EPERM)
    12631288                        err(1, "writing to routing socket");
     
    12671292        if (cmd == RTM_GET) {
    12681293                do {
    1269                         l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg));
    1270                 } while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid));
     1294                        l = read(c->s, (char *)&c->m_rtmsg, sizeof(c->m_rtmsg));
     1295                } while (l > 0 && (rtm.rtm_seq != c->rtm_seq || rtm.rtm_pid != c->pid));
    12711296                if (l < 0)
    12721297                        warn("read from routing socket");
    12731298                else
    1274                         print_getmsg(&rtm, l);
     1299                        print_getmsg(c, &rtm, l);
    12751300        }
    12761301#undef rtm
     
    12791304
    12801305void
    1281 mask_addr()
    1282 {
    1283         int olen = so_mask.sa.sa_len;
    1284         char *cp1 = olen + (char *)&so_mask, *cp2;
    1285 
    1286         for (so_mask.sa.sa_len = 0; cp1 > (char *)&so_mask; )
     1306mask_addr(c)
     1307        struct rt_ctx *c;
     1308{
     1309        int olen = c->so_mask.sa.sa_len;
     1310        char *cp1 = olen + (char *)&c->so_mask, *cp2;
     1311
     1312        for (c->so_mask.sa.sa_len = 0; cp1 > (char *)&c->so_mask; )
    12871313                if (*--cp1 != 0) {
    1288                         so_mask.sa.sa_len = 1 + cp1 - (char *)&so_mask;
     1314                        c->so_mask.sa.sa_len = 1 + cp1 - (char *)&c->so_mask;
    12891315                        break;
    12901316                }
    1291         if ((rtm_addrs & RTA_DST) == 0)
     1317        if ((c->rtm_addrs & RTA_DST) == 0)
    12921318                return;
    1293         switch (so_dst.sa.sa_family) {
     1319        switch (c->so_dst.sa.sa_family) {
    12941320        case AF_INET:
    12951321#ifdef INET6
     
    13001326                return;
    13011327        }
    1302         cp1 = so_mask.sa.sa_len + 1 + (char *)&so_dst;
    1303         cp2 = so_dst.sa.sa_len + 1 + (char *)&so_dst;
     1328        cp1 = c->so_mask.sa.sa_len + 1 + (char *)&c->so_dst;
     1329        cp2 = c->so_dst.sa.sa_len + 1 + (char *)&c->so_dst;
    13041330        while (cp2 > cp1)
    13051331                *--cp2 = 0;
    1306         cp2 = so_mask.sa.sa_len + 1 + (char *)&so_mask;
    1307         while (cp1 > so_dst.sa.sa_data)
     1332        cp2 = c->so_mask.sa.sa_len + 1 + (char *)&c->so_mask;
     1333        while (cp1 > c->so_dst.sa.sa_data)
    13081334                *--cp1 &= *--cp2;
    13091335}
    13101336
    1311 char *msgtypes[] = {
     1337static const char *const msgtypes[] = {
    13121338        "",
    13131339        "RTM_ADD: Add Route",
     
    13311357};
    13321358
    1333 char metricnames[] =
     1359static const char metricnames[] =
    13341360"\011weight\010rttvar\7rtt\6ssthresh\5sendpipe\4recvpipe\3expire"
    13351361"\1mtu";
    1336 char routeflags[] =
     1362static const char routeflags[] =
    13371363"\1UP\2GATEWAY\3HOST\4REJECT\5DYNAMIC\6MODIFIED\7DONE"
    13381364"\012XRESOLVE\013LLINFO\014STATIC\015BLACKHOLE"
    13391365"\017PROTO2\020PROTO1\021PRCLONING\022WASCLONED\023PROTO3"
    13401366"\025PINNED\026LOCAL\027BROADCAST\030MULTICAST\035STICKY";
    1341 char ifnetflags[] =
     1367static const char ifnetflags[] =
    13421368"\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5PTP\6b6\7RUNNING\010NOARP"
    13431369"\011PPROMISC\012ALLMULTI\013OACTIVE\014SIMPLEX\015LINK0\016LINK1"
    13441370"\017LINK2\020MULTICAST";
    1345 char addrnames[] =
     1371static const char addrnames[] =
    13461372"\1DST\2GATEWAY\3NETMASK\4GENMASK\5IFP\6IFA\7AUTHOR\010BRD";
    13471373
    13481374void
    1349 print_rtmsg(rtm, msglen)
     1375print_rtmsg(c, rtm, msglen)
     1376        struct rt_ctx *c;
    13501377        struct rt_msghdr *rtm;
    13511378        int msglen;
     
    13591386        char *state;
    13601387
    1361         if (verbose == 0)
     1388        if (c->verbose == 0)
    13621389                return;
    13631390        if (rtm->rtm_version != RTM_VERSION) {
     
    14301457
    14311458void
    1432 print_getmsg(rtm, msglen)
     1459print_getmsg(c, rtm, msglen)
     1460        struct rt_ctx *c;
    14331461        struct rt_msghdr *rtm;
    14341462        int msglen;
     
    14401468        int i;
    14411469
    1442         (void) printf("   route to: %s\n", routename(&so_dst));
     1470        (void) printf("   route to: %s\n", routename(&c->so_dst));
    14431471        if (rtm->rtm_version != RTM_VERSION) {
    14441472                warnx("routing message version %d not understood",
     
    14831511                (void)printf("destination: %s\n", routename(dst));
    14841512        if (mask) {
    1485                 int savenflag = nflag;
    1486 
    1487                 nflag = 1;
     1513                int savenflag = c->nflag;
     1514
     1515                c->nflag = 1;
    14881516                (void)printf("       mask: %s\n", routename(mask));
    1489                 nflag = savenflag;
     1517                c->nflag = savenflag;
    14901518        }
    14911519        if (gate && rtm->rtm_flags & RTF_GATEWAY)
     
    15141542#undef msec
    15151543#define RTA_IGN (RTA_DST|RTA_GATEWAY|RTA_NETMASK|RTA_IFP|RTA_IFA|RTA_BRD)
    1516         if (verbose)
     1544        if (c->verbose)
    15171545                pmsg_common(rtm);
    15181546        else if (rtm->rtm_addrs &~ RTA_IGN) {
     
    15931621        char *cp;
    15941622{
    1595         struct keytab *kt = keywords;
     1623        const struct keytab *kt = keywords;
    15961624
    15971625        while (kt->kt_cp && strcmp(kt->kt_cp, cp))
     
    16051633        char *which;
    16061634{
     1635        char atalk_buf[20];
     1636
    16071637        switch (su->sa.sa_family) {
    16081638        case AF_LINK:
     
    16161646        case AF_APPLETALK:
    16171647                (void) printf("%s: atalk %s; ",
    1618                     which, atalk_ntoa(su->sat.sat_addr));
     1648                    which, atalk_ntoa(su->sat.sat_addr, atalk_buf));
    16191649                break;
    16201650        }
     
    16891719
    16901720char *
    1691 atalk_ntoa(struct at_addr at)
    1692 {
    1693         static char buf[20];
    1694 
     1721atalk_ntoa(struct at_addr at, char buf[20])
     1722{
    16951723        (void) snprintf(buf, sizeof(buf), "%u.%u", ntohs(at.s_net), at.s_node);
    16961724        return(buf);
Note: See TracChangeset for help on using the changeset viewer.