Annotation of 43BSDReno/sbin/routed/trace.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1983, 1988 Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms are permitted
                      6:  * provided that: (1) source distributions retain this entire copyright
                      7:  * notice and comment, and (2) distributions including binaries display
                      8:  * the following acknowledgement:  ``This product includes software
                      9:  * developed by the University of California, Berkeley and its contributors''
                     10:  * in the documentation or other materials provided with the distribution
                     11:  * and in all advertising materials mentioning features or use of this
                     12:  * software. Neither the name of the University nor the names of its
                     13:  * contributors may be used to endorse or promote products derived
                     14:  * from this software without specific prior written permission.
                     15:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                     16:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                     17:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     18:  */
                     19: 
                     20: #ifndef lint
                     21: static char sccsid[] = "@(#)trace.c    5.10 (Berkeley) 6/1/90";
                     22: #endif /* not lint */
                     23: 
                     24: /*
                     25:  * Routing Table Management Daemon
                     26:  */
                     27: #define        RIPCMDS
                     28: #include "defs.h"
                     29: #include <sys/file.h>
                     30: #include <sys/stat.h>
                     31: #include <sys/signal.h>
                     32: #include "pathnames.h"
                     33: 
                     34: #define        NRECORDS        50              /* size of circular trace buffer */
                     35: #ifdef DEBUG
                     36: FILE   *ftrace = stdout;
                     37: int    traceactions = 0;
                     38: #endif
                     39: static struct timeval lastlog;
                     40: static char *savetracename;
                     41: 
                     42: traceinit(ifp)
                     43:        register struct interface *ifp;
                     44: {
                     45: 
                     46:        if (iftraceinit(ifp, &ifp->int_input) &&
                     47:            iftraceinit(ifp, &ifp->int_output))
                     48:                return;
                     49:        tracehistory = 0;
                     50:        fprintf(stderr, "traceinit: can't init %s\n", ifp->int_name);
                     51: }
                     52: 
                     53: static
                     54: iftraceinit(ifp, ifd)
                     55:        struct interface *ifp;
                     56:        register struct ifdebug *ifd;
                     57: {
                     58:        register struct iftrace *t;
                     59: 
                     60:        ifd->ifd_records =
                     61:          (struct iftrace *)malloc(NRECORDS * sizeof (struct iftrace));
                     62:        if (ifd->ifd_records == 0)
                     63:                return (0);
                     64:        ifd->ifd_front = ifd->ifd_records;
                     65:        ifd->ifd_count = 0;
                     66:        for (t = ifd->ifd_records; t < ifd->ifd_records + NRECORDS; t++) {
                     67:                t->ift_size = 0;
                     68:                t->ift_packet = 0;
                     69:        }
                     70:        ifd->ifd_if = ifp;
                     71:        return (1);
                     72: }
                     73: 
                     74: traceon(file)
                     75:        char *file;
                     76: {
                     77:        struct stat stbuf;
                     78: 
                     79:        if (ftrace != NULL)
                     80:                return;
                     81:        if (stat(file, &stbuf) >= 0 && (stbuf.st_mode & S_IFMT) != S_IFREG)
                     82:                return;
                     83:        savetracename = file;
                     84:        (void) gettimeofday(&now, (struct timezone *)NULL);
                     85:        ftrace = fopen(file, "a");
                     86:        if (ftrace == NULL)
                     87:                return;
                     88:        dup2(fileno(ftrace), 1);
                     89:        dup2(fileno(ftrace), 2);
                     90:        traceactions = 1;
                     91:        fprintf(ftrace, "Tracing enabled %s\n", ctime((time_t *)&now.tv_sec));
                     92: }
                     93: 
                     94: traceoff()
                     95: {
                     96:        if (!traceactions)
                     97:                return;
                     98:        if (ftrace != NULL) {
                     99:                int fd = open(_PATH_DEVNULL, O_RDWR);
                    100: 
                    101:                fprintf(ftrace, "Tracing disabled %s\n",
                    102:                    ctime((time_t *)&now.tv_sec));
                    103:                fflush(ftrace);
                    104:                (void) dup2(fd, 1);
                    105:                (void) dup2(fd, 2);
                    106:                (void) close(fd);
                    107:                fclose(ftrace);
                    108:                ftrace = NULL;
                    109:        }
                    110:        traceactions = 0;
                    111:        tracehistory = 0;
                    112:        tracepackets = 0;
                    113:        tracecontents = 0;
                    114: }
                    115: 
                    116: sigtrace(s)
                    117:        int s;
                    118: {
                    119: 
                    120:        if (s == SIGUSR2)
                    121:                traceoff();
                    122:        else if (ftrace == NULL && savetracename)
                    123:                traceon(savetracename);
                    124:        else
                    125:                bumploglevel();
                    126: }
                    127: 
                    128: /*
                    129:  * Move to next higher level of tracing when -t option processed or
                    130:  * SIGUSR1 is received.  Successive levels are:
                    131:  *     traceactions
                    132:  *     traceactions + tracepackets
                    133:  *     traceactions + tracehistory (packets and contents after change)
                    134:  *     traceactions + tracepackets + tracecontents
                    135:  */
                    136: bumploglevel()
                    137: {
                    138: 
                    139:        (void) gettimeofday(&now, (struct timezone *)NULL);
                    140:        if (traceactions == 0) {
                    141:                traceactions++;
                    142:                if (ftrace)
                    143:                        fprintf(ftrace, "Tracing actions started %s\n",
                    144:                            ctime((time_t *)&now.tv_sec));
                    145:        } else if (tracepackets == 0) {
                    146:                tracepackets++;
                    147:                tracehistory = 0;
                    148:                tracecontents = 0;
                    149:                if (ftrace)
                    150:                        fprintf(ftrace, "Tracing packets started %s\n",
                    151:                            ctime((time_t *)&now.tv_sec));
                    152:        } else if (tracehistory == 0) {
                    153:                tracehistory++;
                    154:                if (ftrace)
                    155:                        fprintf(ftrace, "Tracing history started %s\n",
                    156:                            ctime((time_t *)&now.tv_sec));
                    157:        } else {
                    158:                tracepackets++;
                    159:                tracecontents++;
                    160:                tracehistory = 0;
                    161:                if (ftrace)
                    162:                        fprintf(ftrace, "Tracing packet contents started %s\n",
                    163:                            ctime((time_t *)&now.tv_sec));
                    164:        }
                    165:        if (ftrace)
                    166:                fflush(ftrace);
                    167: }
                    168: 
                    169: trace(ifd, who, p, len, m)
                    170:        register struct ifdebug *ifd;
                    171:        struct sockaddr *who;
                    172:        char *p;
                    173:        int len, m;
                    174: {
                    175:        register struct iftrace *t;
                    176: 
                    177:        if (ifd->ifd_records == 0)
                    178:                return;
                    179:        t = ifd->ifd_front++;
                    180:        if (ifd->ifd_front >= ifd->ifd_records + NRECORDS)
                    181:                ifd->ifd_front = ifd->ifd_records;
                    182:        if (ifd->ifd_count < NRECORDS)
                    183:                ifd->ifd_count++;
                    184:        if (t->ift_size > 0 && t->ift_size < len && t->ift_packet) {
                    185:                free(t->ift_packet);
                    186:                t->ift_packet = 0;
                    187:        }
                    188:        t->ift_stamp = now;
                    189:        t->ift_who = *who;
                    190:        if (len > 0 && t->ift_packet == 0) {
                    191:                t->ift_packet = malloc(len);
                    192:                if (t->ift_packet == 0)
                    193:                        len = 0;
                    194:        }
                    195:        if (len > 0)
                    196:                bcopy(p, t->ift_packet, len);
                    197:        t->ift_size = len;
                    198:        t->ift_metric = m;
                    199: }
                    200: 
                    201: traceaction(fd, action, rt)
                    202:        FILE *fd;
                    203:        char *action;
                    204:        struct rt_entry *rt;
                    205: {
                    206:        struct sockaddr_in *dst, *gate;
                    207:        static struct bits {
                    208:                int     t_bits;
                    209:                char    *t_name;
                    210:        } flagbits[] = {
                    211:                { RTF_UP,       "UP" },
                    212:                { RTF_GATEWAY,  "GATEWAY" },
                    213:                { RTF_HOST,     "HOST" },
                    214:                { 0 }
                    215:        }, statebits[] = {
                    216:                { RTS_PASSIVE,  "PASSIVE" },
                    217:                { RTS_REMOTE,   "REMOTE" },
                    218:                { RTS_INTERFACE,"INTERFACE" },
                    219:                { RTS_CHANGED,  "CHANGED" },
                    220:                { RTS_INTERNAL, "INTERNAL" },
                    221:                { RTS_EXTERNAL, "EXTERNAL" },
                    222:                { RTS_SUBNET,   "SUBNET" },
                    223:                { 0 }
                    224:        };
                    225:        register struct bits *p;
                    226:        register int first;
                    227:        char *cp;
                    228:        struct interface *ifp;
                    229: 
                    230:        if (fd == NULL)
                    231:                return;
                    232:        if (lastlog.tv_sec != now.tv_sec || lastlog.tv_usec != now.tv_usec) {
                    233:                fprintf(fd, "\n%.19s:\n", ctime((time_t *)&now.tv_sec));
                    234:                lastlog = now;
                    235:        }
                    236:        fprintf(fd, "%s ", action);
                    237:        dst = (struct sockaddr_in *)&rt->rt_dst;
                    238:        gate = (struct sockaddr_in *)&rt->rt_router;
                    239:        fprintf(fd, "dst %s, ", inet_ntoa(dst->sin_addr));
                    240:        fprintf(fd, "router %s, metric %d, flags",
                    241:             inet_ntoa(gate->sin_addr), rt->rt_metric);
                    242:        cp = " %s";
                    243:        for (first = 1, p = flagbits; p->t_bits > 0; p++) {
                    244:                if ((rt->rt_flags & p->t_bits) == 0)
                    245:                        continue;
                    246:                fprintf(fd, cp, p->t_name);
                    247:                if (first) {
                    248:                        cp = "|%s";
                    249:                        first = 0;
                    250:                }
                    251:        }
                    252:        fprintf(fd, " state");
                    253:        cp = " %s";
                    254:        for (first = 1, p = statebits; p->t_bits > 0; p++) {
                    255:                if ((rt->rt_state & p->t_bits) == 0)
                    256:                        continue;
                    257:                fprintf(fd, cp, p->t_name);
                    258:                if (first) {
                    259:                        cp = "|%s";
                    260:                        first = 0;
                    261:                }
                    262:        }
                    263:        fprintf(fd, " timer %d\n", rt->rt_timer);
                    264:        if (tracehistory && !tracepackets &&
                    265:            (rt->rt_state & RTS_PASSIVE) == 0 && rt->rt_ifp)
                    266:                dumpif(fd, rt->rt_ifp);
                    267:        fflush(fd);
                    268:        if (ferror(fd))
                    269:                traceoff();
                    270: }
                    271: 
                    272: tracenewmetric(fd, rt, newmetric)
                    273:        FILE *fd;
                    274:        struct rt_entry *rt;
                    275:        int newmetric;
                    276: {
                    277:        struct sockaddr_in *dst, *gate;
                    278: 
                    279:        if (fd == NULL)
                    280:                return;
                    281:        if (lastlog.tv_sec != now.tv_sec || lastlog.tv_usec != now.tv_usec) {
                    282:                fprintf(fd, "\n%.19s:\n", ctime((time_t *)&now.tv_sec));
                    283:                lastlog = now;
                    284:        }
                    285:        dst = (struct sockaddr_in *)&rt->rt_dst;
                    286:        gate = (struct sockaddr_in *)&rt->rt_router;
                    287:        fprintf(fd, "CHANGE metric dst %s, ", inet_ntoa(dst->sin_addr));
                    288:        fprintf(fd, "router %s, from %d to %d\n",
                    289:             inet_ntoa(gate->sin_addr), rt->rt_metric, newmetric);
                    290:        fflush(fd);
                    291:        if (ferror(fd))
                    292:                traceoff();
                    293: }
                    294: 
                    295: dumpif(fd, ifp)
                    296:        FILE *fd;
                    297:        register struct interface *ifp;
                    298: {
                    299:        if (ifp->int_input.ifd_count || ifp->int_output.ifd_count) {
                    300:                fprintf(fd, "*** Packet history for interface %s ***\n",
                    301:                        ifp->int_name);
                    302: #ifdef notneeded
                    303:                dumptrace(fd, "to", &ifp->int_output);
                    304: #endif
                    305:                dumptrace(fd, "from", &ifp->int_input);
                    306:                fprintf(fd, "*** end packet history ***\n");
                    307:        }
                    308: }
                    309: 
                    310: dumptrace(fd, dir, ifd)
                    311:        FILE *fd;
                    312:        char *dir;
                    313:        register struct ifdebug *ifd;
                    314: {
                    315:        register struct iftrace *t;
                    316:        char *cp = !strcmp(dir, "to") ? "Output" : "Input";
                    317: 
                    318:        if (ifd->ifd_front == ifd->ifd_records &&
                    319:            ifd->ifd_front->ift_size == 0) {
                    320:                fprintf(fd, "%s: no packets.\n", cp);
                    321:                fflush(fd);
                    322:                return;
                    323:        }
                    324:        fprintf(fd, "%s trace:\n", cp);
                    325:        t = ifd->ifd_front - ifd->ifd_count;
                    326:        if (t < ifd->ifd_records)
                    327:                t += NRECORDS;
                    328:        for ( ; ifd->ifd_count; ifd->ifd_count--, t++) {
                    329:                if (t >= ifd->ifd_records + NRECORDS)
                    330:                        t = ifd->ifd_records;
                    331:                if (t->ift_size == 0)
                    332:                        continue;
                    333:                dumppacket(fd, dir, &t->ift_who, t->ift_packet, t->ift_size,
                    334:                    &t->ift_stamp);
                    335:        }
                    336: }
                    337: 
                    338: dumppacket(fd, dir, who, cp, size, stamp)
                    339:        FILE *fd;
                    340:        struct sockaddr_in *who;                /* should be sockaddr */
                    341:        char *dir, *cp;
                    342:        register int size;
                    343:        struct timeval *stamp;
                    344: {
                    345:        register struct rip *msg = (struct rip *)cp;
                    346:        register struct netinfo *n;
                    347: 
                    348:        if (fd == NULL)
                    349:                return;
                    350:        if (msg->rip_cmd && msg->rip_cmd < RIPCMD_MAX)
                    351:                fprintf(fd, "%s %s %s.%d %.19s:\n", ripcmds[msg->rip_cmd],
                    352:                    dir, inet_ntoa(who->sin_addr), ntohs(who->sin_port),
                    353:                    ctime((time_t *)&stamp->tv_sec));
                    354:        else {
                    355:                fprintf(fd, "Bad cmd 0x%x %s %x.%d %.19s\n", msg->rip_cmd,
                    356:                    dir, inet_ntoa(who->sin_addr), ntohs(who->sin_port));
                    357:                fprintf(fd, "size=%d cp=%x packet=%x\n", size, cp, packet,
                    358:                    ctime((time_t *)&stamp->tv_sec));
                    359:                fflush(fd);
                    360:                return;
                    361:        }
                    362:        if (tracepackets && tracecontents == 0) {
                    363:                fflush(fd);
                    364:                return;
                    365:        }
                    366:        switch (msg->rip_cmd) {
                    367: 
                    368:        case RIPCMD_REQUEST:
                    369:        case RIPCMD_RESPONSE:
                    370:                size -= 4 * sizeof (char);
                    371:                n = msg->rip_nets;
                    372:                for (; size > 0; n++, size -= sizeof (struct netinfo)) {
                    373:                        if (size < sizeof (struct netinfo)) {
                    374:                                fprintf(fd, "(truncated record, len %d)\n",
                    375:                                    size);
                    376:                                break;
                    377:                        }
                    378:                        if (sizeof(n->rip_dst.sa_family) > 1)
                    379:                            n->rip_dst.sa_family = ntohs(n->rip_dst.sa_family);
                    380: 
                    381:                        switch ((int)n->rip_dst.sa_family) {
                    382: 
                    383:                        case AF_INET:
                    384:                                fprintf(fd, "\tdst %s metric %d\n",
                    385: #define        satosin(sa)     ((struct sockaddr_in *)&sa)
                    386:                                     inet_ntoa(satosin(n->rip_dst)->sin_addr),
                    387:                                     ntohl(n->rip_metric));
                    388:                                break;
                    389: 
                    390:                        default:
                    391:                                fprintf(fd, "\taf %d? metric %d\n",
                    392:                                     n->rip_dst.sa_family,
                    393:                                     ntohl(n->rip_metric));
                    394:                                break;
                    395:                        }
                    396:                }
                    397:                break;
                    398: 
                    399:        case RIPCMD_TRACEON:
                    400:                fprintf(fd, "\tfile=%*s\n", size, msg->rip_tracefile);
                    401:                break;
                    402: 
                    403:        case RIPCMD_TRACEOFF:
                    404:                break;
                    405:        }
                    406:        fflush(fd);
                    407:        if (ferror(fd))
                    408:                traceoff();
                    409: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.