Annotation of embedaddon/libpdel/net/route_msg.c, revision 1.1

1.1     ! misho       1: 
        !             2: /*
        !             3:  * Copyright (c) 2001-2002 Packet Design, LLC.
        !             4:  * All rights reserved.
        !             5:  * 
        !             6:  * Subject to the following obligations and disclaimer of warranty,
        !             7:  * use and redistribution of this software, in source or object code
        !             8:  * forms, with or without modifications are expressly permitted by
        !             9:  * Packet Design; provided, however, that:
        !            10:  * 
        !            11:  *    (i)  Any and all reproductions of the source or object code
        !            12:  *         must include the copyright notice above and the following
        !            13:  *         disclaimer of warranties; and
        !            14:  *    (ii) No rights are granted, in any manner or form, to use
        !            15:  *         Packet Design trademarks, including the mark "PACKET DESIGN"
        !            16:  *         on advertising, endorsements, or otherwise except as such
        !            17:  *         appears in the above copyright notice or in the software.
        !            18:  * 
        !            19:  * THIS SOFTWARE IS BEING PROVIDED BY PACKET DESIGN "AS IS", AND
        !            20:  * TO THE MAXIMUM EXTENT PERMITTED BY LAW, PACKET DESIGN MAKES NO
        !            21:  * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING
        !            22:  * THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED
        !            23:  * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
        !            24:  * OR NON-INFRINGEMENT.  PACKET DESIGN DOES NOT WARRANT, GUARANTEE,
        !            25:  * OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS
        !            26:  * OF THE USE OF THIS SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY,
        !            27:  * RELIABILITY OR OTHERWISE.  IN NO EVENT SHALL PACKET DESIGN BE
        !            28:  * LIABLE FOR ANY DAMAGES RESULTING FROM OR ARISING OUT OF ANY USE
        !            29:  * OF THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY DIRECT,
        !            30:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE, OR CONSEQUENTIAL
        !            31:  * DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF
        !            32:  * USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY THEORY OF
        !            33:  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            34:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
        !            35:  * THE USE OF THIS SOFTWARE, EVEN IF PACKET DESIGN IS ADVISED OF
        !            36:  * THE POSSIBILITY OF SUCH DAMAGE.
        !            37:  *
        !            38:  * Author: Archie Cobbs <archie@freebsd.org>
        !            39:  */
        !            40: 
        !            41: #include <sys/types.h>
        !            42: #include <sys/param.h>
        !            43: #include <sys/socket.h>
        !            44: #include <sys/sysctl.h>
        !            45: #include <sys/sockio.h>
        !            46: #include <sys/ioctl.h>
        !            47: 
        !            48: #include <net/if.h>
        !            49: #include <net/if_dl.h>
        !            50: #include <net/if_types.h>
        !            51: #include <net/route.h>
        !            52: 
        !            53: #include <netinet/in.h>
        !            54: #include <arpa/inet.h>
        !            55: 
        !            56: #include <stdio.h>
        !            57: #include <stdlib.h>
        !            58: #include <stddef.h>
        !            59: #include <stdarg.h>
        !            60: #include <unistd.h>
        !            61: #include <string.h>
        !            62: #include <assert.h>
        !            63: #include <errno.h>
        !            64: #include <time.h>
        !            65: 
        !            66: #include "structs/structs.h"
        !            67: #include "structs/type/array.h"
        !            68: 
        !            69: #include "util/typed_mem.h"
        !            70: #include "net/route_msg.h"
        !            71: 
        !            72: #define ROUNDUP(a) \
        !            73:        ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
        !            74: #define ADVANCE(x, n)  ((x) += ROUNDUP((n)->sa_len))
        !            75: 
        !            76: struct route_msg {
        !            77:        int             type;           /* message type */
        !            78:        int             index;          /* index for associated ifp */
        !            79:        int             flags;          /* flags, incl. kern & msg, e.g. DONE */
        !            80:        pid_t           pid;            /* for sender to identify action */
        !            81:        int             seq;            /* for sender to identify action */
        !            82:        int             error;          /* why failed */
        !            83:        struct sockaddr *dest;          /* destination sockaddr */
        !            84:        struct sockaddr *gateway;       /* gateway sockaddr */
        !            85:        struct sockaddr *netmask;       /* netmask sockaddr */
        !            86:        struct sockaddr *genmask;       /* genmask sockaddr */
        !            87:        struct sockaddr *ifp;           /* interface name sockaddr */
        !            88:        struct sockaddr *ifa;           /* interface addr sockaddr */
        !            89:        struct sockaddr *author;        /* author of redirect sockaddr */
        !            90:        struct sockaddr *brd;           /* for NEWADDR, broadcast or p2p dest */
        !            91: };
        !            92: 
        !            93: /*
        !            94:  * Internal variables
        !            95:  */
        !            96: 
        !            97: /* List of sockaddr's in a route message from the kernel */
        !            98: struct msg_sock {
        !            99:        const char      *name;
        !           100:        u_int           offset;
        !           101: };
        !           102: 
        !           103: static const   struct msg_sock msg_socks[] = {
        !           104:        { "dest",       offsetof(struct route_msg, dest)        },
        !           105:        { "gateway",    offsetof(struct route_msg, gateway)     },
        !           106:        { "netmask",    offsetof(struct route_msg, netmask)     },
        !           107:        { "genmask",    offsetof(struct route_msg, genmask)     },
        !           108:        { "ifp",        offsetof(struct route_msg, ifp)         },
        !           109:        { "ifa",        offsetof(struct route_msg, ifa)         },
        !           110:        { "author",     offsetof(struct route_msg, author)      },
        !           111:        { "brd",        offsetof(struct route_msg, brd)         },
        !           112:        { NULL, 0 }
        !           113: };
        !           114: 
        !           115: static int     prev_seq;               /* last used sequence number */
        !           116: 
        !           117: /*
        !           118:  * Internal functions
        !           119:  */
        !           120: static int     route_msg_set_sa(struct route_msg *msg,
        !           121:                        const char *name, const struct sockaddr *sa);
        !           122: 
        !           123: /*
        !           124:  * Create a new route message.
        !           125:  */
        !           126: struct route_msg *
        !           127: route_msg_create(void)
        !           128: {
        !           129:        struct route_msg *msg;
        !           130: 
        !           131:        if ((msg = MALLOC("route_msg", sizeof(*msg))) == NULL)
        !           132:                return (NULL);
        !           133:        memset(msg, 0, sizeof(*msg));
        !           134:        msg->seq = ++prev_seq;                          /* XXX not atomic */
        !           135:        msg->pid = getpid();
        !           136:        return (msg);
        !           137: }
        !           138: 
        !           139: /*
        !           140:  * Destroy a routing message.
        !           141:  */
        !           142: void
        !           143: route_msg_destroy(struct route_msg **msgp)
        !           144: {
        !           145:        struct route_msg *const msg = *msgp;
        !           146: 
        !           147:        if (msg == NULL)
        !           148:                return;
        !           149:        FREE("route_msg.dest", msg->dest);
        !           150:        FREE("route_msg.gateway", msg->gateway);
        !           151:        FREE("route_msg.netmask", msg->netmask);
        !           152:        FREE("route_msg.genmask", msg->genmask);
        !           153:        FREE("route_msg.ifp", msg->ifp);
        !           154:        FREE("route_msg.ifa", msg->ifa);
        !           155:        FREE("route_msg.author", msg->author);
        !           156:        FREE("route_msg.brd", msg->brd);
        !           157:        FREE("route_msg", msg);
        !           158:        *msgp = NULL;
        !           159: }
        !           160: 
        !           161: /*
        !           162:  * Get message type.
        !           163:  */
        !           164: int
        !           165: route_msg_get_type(struct route_msg *msg)
        !           166: {
        !           167:        return (msg->type);
        !           168: }
        !           169: 
        !           170: /*
        !           171:  * Set message type.
        !           172:  */
        !           173: void
        !           174: route_msg_set_type(struct route_msg *msg, int type)
        !           175: {
        !           176:        msg->type = type;
        !           177: }
        !           178: 
        !           179: /*
        !           180:  * Get message index.
        !           181:  */
        !           182: int
        !           183: route_msg_get_index(struct route_msg *msg)
        !           184: {
        !           185:        return (msg->index);
        !           186: }
        !           187: 
        !           188: /*
        !           189:  * Set message index.
        !           190:  */
        !           191: void
        !           192: route_msg_set_index(struct route_msg *msg, int index)
        !           193: {
        !           194:        msg->index = index;
        !           195: }
        !           196: 
        !           197: /*
        !           198:  * Get message flags.
        !           199:  */
        !           200: int
        !           201: route_msg_get_flags(struct route_msg *msg)
        !           202: {
        !           203:        return (msg->flags);
        !           204: }
        !           205: 
        !           206: /*
        !           207:  * Set message flags.
        !           208:  */
        !           209: void
        !           210: route_msg_set_flags(struct route_msg *msg, int flags)
        !           211: {
        !           212:        msg->flags = flags;
        !           213: }
        !           214: 
        !           215: /*
        !           216:  * Get message error code.
        !           217:  */
        !           218: int
        !           219: route_msg_get_error(struct route_msg *msg)
        !           220: {
        !           221:        return (msg->error);
        !           222: }
        !           223: 
        !           224: /*
        !           225:  * Get message process ID.
        !           226:  */
        !           227: pid_t
        !           228: route_msg_get_pid(struct route_msg *msg)
        !           229: {
        !           230:        return (msg->pid);
        !           231: }
        !           232: 
        !           233: /*
        !           234:  * Get message sequence number.
        !           235:  */
        !           236: int
        !           237: route_msg_get_seq(struct route_msg *msg)
        !           238: {
        !           239:        return (msg->seq);
        !           240: }
        !           241: 
        !           242: /*
        !           243:  * Get message destination.
        !           244:  */
        !           245: const struct sockaddr *
        !           246: route_msg_get_dest(struct route_msg *msg)
        !           247: {
        !           248:        return (msg->dest);
        !           249: }
        !           250: 
        !           251: /*
        !           252:  * Set message destination.
        !           253:  */
        !           254: int
        !           255: route_msg_set_dest(struct route_msg *msg, const struct sockaddr *dest)
        !           256: {
        !           257:        return (route_msg_set_sa(msg, "dest", dest));
        !           258: }
        !           259: 
        !           260: /*
        !           261:  * Get message gateway.
        !           262:  */
        !           263: const struct sockaddr *
        !           264: route_msg_get_gateway(struct route_msg *msg)
        !           265: {
        !           266:        return (msg->gateway);
        !           267: }
        !           268: 
        !           269: /*
        !           270:  * Set message gateway.
        !           271:  */
        !           272: int
        !           273: route_msg_set_gateway(struct route_msg *msg, const struct sockaddr *gateway)
        !           274: {
        !           275:        return (route_msg_set_sa(msg, "gateway", gateway));
        !           276: }
        !           277: 
        !           278: /*
        !           279:  * Get message netmask.
        !           280:  */
        !           281: const struct sockaddr *
        !           282: route_msg_get_netmask(struct route_msg *msg)
        !           283: {
        !           284:        return (msg->netmask);
        !           285: }
        !           286: 
        !           287: /*
        !           288:  * Set message netmask.
        !           289:  */
        !           290: int
        !           291: route_msg_set_netmask(struct route_msg *msg, const struct sockaddr *netmask)
        !           292: {
        !           293:        return (route_msg_set_sa(msg, "netmask", netmask));
        !           294: }
        !           295: 
        !           296: /*
        !           297:  * Get message cloning netmask.
        !           298:  */
        !           299: const struct sockaddr *
        !           300: route_msg_get_genmask(struct route_msg *msg)
        !           301: {
        !           302:        return (msg->genmask);
        !           303: }
        !           304: 
        !           305: /*
        !           306:  * Set message cloning netmask.
        !           307:  */
        !           308: int
        !           309: route_msg_set_genmask(struct route_msg *msg, const struct sockaddr *genmask)
        !           310: {
        !           311:        return (route_msg_set_sa(msg, "genmask", genmask));
        !           312: }
        !           313: 
        !           314: /*
        !           315:  * Get message interface name.
        !           316:  */
        !           317: const struct sockaddr *
        !           318: route_msg_get_ifp(struct route_msg *msg)
        !           319: {
        !           320:        return (msg->ifp);
        !           321: }
        !           322: 
        !           323: /*
        !           324:  * Set message interface name.
        !           325:  */
        !           326: int
        !           327: route_msg_set_ifp(struct route_msg *msg, const struct sockaddr *ifp)
        !           328: {
        !           329:        return (route_msg_set_sa(msg, "ifp", ifp));
        !           330: }
        !           331: 
        !           332: /*
        !           333:  * Get message interface address.
        !           334:  */
        !           335: const struct sockaddr *
        !           336: route_msg_get_ifa(struct route_msg *msg)
        !           337: {
        !           338:        return (msg->ifa);
        !           339: }
        !           340: 
        !           341: /*
        !           342:  * Set message interface address.
        !           343:  */
        !           344: int
        !           345: route_msg_set_ifa(struct route_msg *msg, const struct sockaddr *ifa)
        !           346: {
        !           347:        return (route_msg_set_sa(msg, "ifa", ifa));
        !           348: }
        !           349: 
        !           350: /*
        !           351:  * Get message author of the redirect message.
        !           352:  */
        !           353: const struct sockaddr *
        !           354: route_msg_get_author(struct route_msg *msg)
        !           355: {
        !           356:        return (msg->author);
        !           357: }
        !           358: 
        !           359: /*
        !           360:  * Set message author of the redirect message.
        !           361:  */
        !           362: int
        !           363: route_msg_set_author(struct route_msg *msg, const struct sockaddr *author)
        !           364: {
        !           365:        return (route_msg_set_sa(msg, "author", author));
        !           366: }
        !           367: 
        !           368: /*
        !           369:  * Get message broadcast or point-to-point destination address.
        !           370:  */
        !           371: const struct sockaddr *
        !           372: route_msg_get_brd(struct route_msg *msg)
        !           373: {
        !           374:        return (msg->brd);
        !           375: }
        !           376: 
        !           377: /*
        !           378:  * Set message broadcast or point-to-point destination address.
        !           379:  */
        !           380: int
        !           381: route_msg_set_brd(struct route_msg *msg, const struct sockaddr *brd)
        !           382: {
        !           383:        return (route_msg_set_sa(msg, "brd", brd));
        !           384: }
        !           385: 
        !           386: /*
        !           387:  * Set one of the struct sockaddr fields.
        !           388:  */
        !           389: static int
        !           390: route_msg_set_sa(struct route_msg *msg,
        !           391:        const char *name, const struct sockaddr *sa)
        !           392: {
        !           393:        struct sockaddr *copy;
        !           394:        struct sockaddr **sp;
        !           395:        char buf[32];
        !           396:        int i;
        !           397: 
        !           398:        for (i = 0; msg_socks[i].name != NULL
        !           399:            && strcmp(name, msg_socks[i].name) != 0; i++);
        !           400:        assert(msg_socks[i].name != NULL);
        !           401:        sp = (struct sockaddr **)(void *)((u_char *)msg + msg_socks[i].offset);
        !           402:        snprintf(buf, sizeof(buf), "route_msg.%s", name);
        !           403:        if (sa != NULL) {
        !           404:                if ((copy = MALLOC(buf, sa->sa_len)) == NULL)
        !           405:                        return (-1);
        !           406:                memcpy(copy, sa, sa->sa_len);
        !           407:        } else
        !           408:                copy = NULL;
        !           409:        FREE(buf, *sp);
        !           410:        *sp = copy;
        !           411:        return (0);
        !           412: }
        !           413: 
        !           414: /*
        !           415:  * Decode one or more routing messages from raw socket data.
        !           416:  *
        !           417:  * Returns the number of decoded messages, or -1 for error.
        !           418:  * The array of struct route_msg pointers is returned in *listp,
        !           419:  * in an array allocated with memory type 'mtype'.
        !           420:  */
        !           421: int
        !           422: route_msg_decode(const u_char *data, size_t dlen,
        !           423:        struct route_msg ***listp, const char *mtype)
        !           424: {
        !           425:        struct route_msg **list;
        !           426:        struct rt_msghdr rtm;
        !           427:        int posn;
        !           428:        int num;
        !           429:        int i;
        !           430: 
        !           431:        /* Count number of messages */
        !           432:        for (num = posn = 0; posn < dlen; num++, posn += rtm.rtm_msglen) {
        !           433:                if (dlen - posn < sizeof(rtm)) {
        !           434:                        errno = EINVAL;
        !           435:                        return (-1);
        !           436:                }
        !           437:                memcpy(&rtm, data + posn, sizeof(rtm.rtm_msglen));
        !           438:                if (rtm.rtm_msglen < sizeof(rtm)) {
        !           439:                        errno = EINVAL;
        !           440:                        return (-1);
        !           441:                }
        !           442:        }
        !           443: 
        !           444:        /* Allocate list */
        !           445:        if ((list = MALLOC(mtype, num * sizeof(*list))) == NULL)
        !           446:                return (-1);
        !           447:        memset(list, 0, num * sizeof(*list));
        !           448: 
        !           449:        /* Decode each message */
        !           450:        for (i = posn = 0; i < num; i++, posn += rtm.rtm_msglen) {
        !           451:                int posn2;
        !           452:                int j;
        !           453: 
        !           454:                /* Create new route_msg object */
        !           455:                if ((list[i] = route_msg_create()) == NULL)
        !           456:                        goto fail;
        !           457: 
        !           458:                /* Copy fields from route message header */
        !           459:                memcpy(&rtm, data + posn, sizeof(rtm));
        !           460:                list[i]->type = rtm.rtm_type;
        !           461:                list[i]->index = rtm.rtm_index;
        !           462:                list[i]->flags = rtm.rtm_flags;
        !           463:                list[i]->pid = rtm.rtm_pid;
        !           464:                list[i]->seq = rtm.rtm_seq;
        !           465:                list[i]->error = rtm.rtm_errno;
        !           466: 
        !           467:                /* Create struct sockaddr's from each appended sockaddr */
        !           468:                for (posn2 = posn + sizeof(rtm), j = 0;
        !           469:                    msg_socks[j].name != NULL; j++) {
        !           470:                        const struct sockaddr *const sa
        !           471:                            = (struct sockaddr *)(data + posn2);
        !           472: 
        !           473:                        if ((rtm.rtm_addrs & (1 << j)) == 0)
        !           474:                                continue;
        !           475:                        if (sa->sa_len != 0) {
        !           476:                                if (route_msg_set_sa(list[i],
        !           477:                                    msg_socks[j].name, sa) == -1)
        !           478:                                        goto fail;
        !           479:                        }
        !           480:                        ADVANCE(posn2, sa);
        !           481:                }
        !           482:        }
        !           483: 
        !           484:        /* Done */
        !           485:        *listp = list;
        !           486:        return (num);
        !           487: 
        !           488: fail:
        !           489:        /* Cleanup after failure */
        !           490:        for (i = 0; i < num; i++)
        !           491:                route_msg_destroy(&list[i]);
        !           492:        FREE(mtype, list);
        !           493:        return (-1);
        !           494: }
        !           495: 
        !           496: /*
        !           497:  * Encode a route message into raw binary form.
        !           498:  *
        !           499:  * Returns the total encoded length, or -1 for error.
        !           500:  */
        !           501: int
        !           502: route_msg_encode(const struct route_msg *msg, u_char *data, size_t dlen)
        !           503: {
        !           504:        struct rt_msghdr rtm;
        !           505:        int totalLen;
        !           506:        int i;
        !           507: 
        !           508:        /* Prepare header */
        !           509:        if ((totalLen = sizeof(rtm)) > dlen) {
        !           510:                errno = EMSGSIZE;
        !           511:                return (-1);
        !           512:        }
        !           513:        memset(&rtm, 0, sizeof(rtm));
        !           514:        rtm.rtm_version = RTM_VERSION;
        !           515:        rtm.rtm_type = msg->type;
        !           516:        rtm.rtm_index = msg->index;
        !           517:        rtm.rtm_flags = msg->flags;
        !           518:        rtm.rtm_pid = msg->pid;
        !           519:        rtm.rtm_seq = msg->seq;
        !           520:        rtm.rtm_errno = msg->error;
        !           521: 
        !           522:        /* Append struct sockaddr's */
        !           523:        for (i = 0; msg_socks[i].name != NULL; i++) {
        !           524:                struct sockaddr *const sa = *((struct sockaddr **)(void *)
        !           525:                    ((u_char *)msg + msg_socks[i].offset));
        !           526:                int len;
        !           527: 
        !           528:                if (sa == NULL)
        !           529:                        continue;
        !           530:                rtm.rtm_addrs |= (1 << i);
        !           531:                len = ROUNDUP(sa->sa_len);
        !           532:                if (totalLen + len > dlen) {
        !           533:                        errno = EMSGSIZE;
        !           534:                        return (-1);
        !           535:                }
        !           536:                memcpy(data + totalLen, sa, sa->sa_len);
        !           537:                memset(data + totalLen + sa->sa_len, 0, len - sa->sa_len);
        !           538:                totalLen += len;
        !           539:        }
        !           540: 
        !           541:        /* Copy in completed header */
        !           542:        rtm.rtm_msglen = totalLen;
        !           543:        memcpy(data, &rtm, sizeof(rtm));
        !           544: 
        !           545:        /* Done */
        !           546:        return (totalLen);
        !           547: }
        !           548: 
        !           549: /*
        !           550:  * Send a route message to a socket.
        !           551:  */
        !           552: int
        !           553: route_msg_send(struct route_msg *msg, int sock)
        !           554: {
        !           555:        u_char buf[512];
        !           556:        int count;
        !           557:        int elen;
        !           558:        int r;
        !           559: 
        !           560:        if ((elen = route_msg_encode(msg, buf, sizeof(buf))) == -1)
        !           561:                return (-1);
        !           562:        for (count = 0; count < 32; count++) {
        !           563:                if ((r = send(sock, buf, elen, 0)) >= 0)
        !           564:                        return (0);
        !           565:                switch (errno) {
        !           566:                case ENETUNREACH:
        !           567:                case ESRCH:
        !           568:                        break;
        !           569:                default:
        !           570:                        return (-1);
        !           571:                }
        !           572:        }
        !           573:        return (-1);
        !           574: }
        !           575: 
        !           576: /*
        !           577:  * Receive route messages from a socket.
        !           578:  */
        !           579: int
        !           580: route_msg_recv(struct route_msg ***listp, int sock, const char *mtype)
        !           581: {
        !           582:        u_char buf[512];
        !           583:        int r;
        !           584: 
        !           585:        /* Read next raw message array */
        !           586:        if ((r = recv(sock, buf, sizeof(buf), 0)) < 0)
        !           587:                return (-1);
        !           588: 
        !           589:        /* Decode it */
        !           590:        return (route_msg_decode(buf, r, listp, mtype));
        !           591: }
        !           592: 
        !           593: /*
        !           594:  * Print route message as a string.
        !           595:  */
        !           596: void
        !           597: route_msg_print(struct route_msg *msg, FILE *fp)
        !           598: {
        !           599:        const char *typestr = NULL;
        !           600: 
        !           601:        fprintf(fp, "type=");
        !           602:        switch (msg->type) {
        !           603:        case RTM_ADD:           typestr = "ADD"; break;
        !           604:        case RTM_DELETE:        typestr = "DELETE"; break;
        !           605:        case RTM_CHANGE:        typestr = "CHANGE"; break;
        !           606:        case RTM_GET:           typestr = "GET"; break;
        !           607:        case RTM_LOSING:        typestr = "LOSING"; break;
        !           608:        case RTM_REDIRECT:      typestr = "REDIRECT"; break;
        !           609:        case RTM_MISS:          typestr = "MISS"; break;
        !           610:        case RTM_LOCK:          typestr = "LOCK"; break;
        !           611:        case RTM_OLDADD:        typestr = "OLDADD"; break;
        !           612:        case RTM_OLDDEL:        typestr = "OLDDEL"; break;
        !           613:        case RTM_RESOLVE:       typestr = "RESOLVE"; break;
        !           614:        case RTM_NEWADDR:       typestr = "NEWADDR"; break;
        !           615:        case RTM_DELADDR:       typestr = "DELADDR"; break;
        !           616:        case RTM_IFINFO:        typestr = "IFINFO"; break;
        !           617:        case RTM_NEWMADDR:      typestr = "NEWMADDR"; break;
        !           618:        case RTM_DELMADDR:      typestr = "DELMADDR"; break;
        !           619:        default:
        !           620:                fprintf(fp, "%d", msg->type);
        !           621:                break;
        !           622:        }
        !           623:        if (typestr != NULL)
        !           624:                fprintf(fp, "%s", typestr);
        !           625:        fprintf(fp, " index=%d flags=0x%x pid=%lu seq=%d errno=%d",
        !           626:            msg->index, msg->flags, (u_long)msg->pid, msg->seq, msg->error);
        !           627:        if (msg->dest != NULL)
        !           628:                fprintf(fp, " dest=%p", msg->dest);
        !           629:        if (msg->gateway != NULL)
        !           630:                fprintf(fp, " gateway=%p", msg->gateway);
        !           631:        if (msg->netmask != NULL)
        !           632:                fprintf(fp, " netmask=%p", msg->netmask);
        !           633:        if (msg->genmask != NULL)
        !           634:                fprintf(fp, " genmask=%p", msg->genmask);
        !           635:        if (msg->ifp != NULL)
        !           636:                fprintf(fp, " ifp=%p", msg->ifp);
        !           637:        if (msg->ifa != NULL)
        !           638:                fprintf(fp, " ifa=%p", msg->ifa);
        !           639:        if (msg->author != NULL)
        !           640:                fprintf(fp, " author=%p", msg->author);
        !           641:        if (msg->brd != NULL)
        !           642:                fprintf(fp, " brd=%p", msg->brd);
        !           643:        fflush(fp);
        !           644: }
        !           645: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>