]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/IPXrouted/trace.c
o Wording and spelling fixes for security menu description.
[FreeBSD/FreeBSD.git] / usr.sbin / IPXrouted / trace.c
1 /*
2  * Copyright (c) 1985, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * Copyright (c) 1995 John Hay.  All rights reserved.
6  *
7  * This file includes significant work done at Cornell University by
8  * Bill Nesheim.  That work included by permission.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *      This product includes software developed by the University of
21  *      California, Berkeley and its contributors.
22  * 4. Neither the name of the University nor the names of its contributors
23  *    may be used to endorse or promote products derived from this software
24  *    without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36  * SUCH DAMAGE.
37  *
38  * $FreeBSD$
39  */
40
41 #ifndef lint
42 static char sccsid[] = "@(#)trace.c     8.1 (Berkeley) 6/5/93";
43 #endif /* not lint */
44
45 /*
46  * Routing Table Management Daemon
47  */
48 #define RIPCMDS
49 #define SAPCMDS
50 #include <stdlib.h>
51 #include <unistd.h>
52 #include <sys/types.h>
53 #include <time.h>
54 #include "defs.h"
55
56 #define NRECORDS        50              /* size of circular trace buffer */
57 #ifdef DEBUG
58 FILE    *ftrace = stdout;
59 int     tracing = 1;
60 #else DEBUG
61 FILE    *ftrace = NULL;
62 int     tracing = 0;
63 #endif
64
65 void dumpif(FILE *fd, struct interface *ifp);
66 void dumptrace(FILE *fd, char *dir, struct ifdebug *ifd);
67
68 void
69 traceinit(ifp)
70         register struct interface *ifp;
71 {
72         static int iftraceinit();
73
74         if (iftraceinit(ifp, &ifp->int_input) &&
75             iftraceinit(ifp, &ifp->int_output))
76                 return;
77         tracing = 0;
78         syslog(LOG_ERR, "traceinit: can't init %s\n", ifp->int_name);
79 }
80
81 static int
82 iftraceinit(ifp, ifd)
83         struct interface *ifp;
84         register struct ifdebug *ifd;
85 {
86         register struct iftrace *t;
87
88         ifd->ifd_records =
89           (struct iftrace *)malloc(NRECORDS * sizeof (struct iftrace));
90         if (ifd->ifd_records == 0)
91                 return (0);
92         ifd->ifd_front = ifd->ifd_records;
93         ifd->ifd_count = 0;
94         for (t = ifd->ifd_records; t < ifd->ifd_records + NRECORDS; t++) {
95                 t->ift_size = 0;
96                 t->ift_packet = 0;
97         }
98         ifd->ifd_if = ifp;
99         return (1);
100 }
101
102 void
103 traceon(file)
104         char *file;
105 {
106
107         if (ftrace != NULL)
108                 return;
109         ftrace = fopen(file, "a");
110         if (ftrace == NULL)
111                 return;
112         dup2(fileno(ftrace), 1);
113         dup2(fileno(ftrace), 2);
114         tracing = 1;
115 }
116
117 void
118 traceoff(void)
119 {
120         if (!tracing)
121                 return;
122         if (ftrace != NULL)
123                 fclose(ftrace);
124         ftrace = NULL;
125         tracing = 0;
126 }
127
128 void
129 trace(ifd, who, p, len, m)
130         register struct ifdebug *ifd;
131         struct sockaddr *who;
132         char *p;
133         int len, m;
134 {
135         register struct iftrace *t;
136
137         if (ifd->ifd_records == 0)
138                 return;
139         t = ifd->ifd_front++;
140         if (ifd->ifd_front >= ifd->ifd_records + NRECORDS)
141                 ifd->ifd_front = ifd->ifd_records;
142         if (ifd->ifd_count < NRECORDS)
143                 ifd->ifd_count++;
144         if (t->ift_size > 0 && t->ift_packet)
145                 free(t->ift_packet);
146         t->ift_packet = 0;
147         t->ift_stamp = time(0);
148         t->ift_who = *who;
149         if (len > 0) {
150                 t->ift_packet = malloc(len);
151                 if (t->ift_packet)
152                         bcopy(p, t->ift_packet, len);
153                 else
154                         len = 0;
155         }
156         t->ift_size = len;
157         t->ift_metric = m;
158 }
159
160 void
161 traceaction(fd, action, rt)
162         FILE *fd;
163         char *action;
164         struct rt_entry *rt;
165 {
166         struct sockaddr_ipx *dst, *gate;
167         static struct bits {
168                 int     t_bits;
169                 char    *t_name;
170         } flagbits[] = {
171                 { RTF_UP,       "UP" },
172                 { RTF_GATEWAY,  "GATEWAY" },
173                 { RTF_HOST,     "HOST" },
174                 { 0 }
175         }, statebits[] = {
176                 { RTS_PASSIVE,  "PASSIVE" },
177                 { RTS_REMOTE,   "REMOTE" },
178                 { RTS_INTERFACE,"INTERFACE" },
179                 { RTS_CHANGED,  "CHANGED" },
180                 { 0 }
181         };
182         register struct bits *p;
183         register int first;
184         char *cp;
185
186         if (fd == NULL)
187                 return;
188         fprintf(fd, "%s ", action);
189         dst = (struct sockaddr_ipx *)&rt->rt_dst;
190         gate = (struct sockaddr_ipx *)&rt->rt_router;
191         fprintf(fd, "dst %s, ", ipxdp_ntoa(&dst->sipx_addr));
192         fprintf(fd, "router %s, metric %d, ticks %d, flags",
193              ipxdp_ntoa(&gate->sipx_addr), rt->rt_metric, rt->rt_ticks);
194         cp = " %s";
195         for (first = 1, p = flagbits; p->t_bits > 0; p++) {
196                 if ((rt->rt_flags & p->t_bits) == 0)
197                         continue;
198                 fprintf(fd, cp, p->t_name);
199                 if (first) {
200                         cp = "|%s";
201                         first = 0;
202                 }
203         }
204         fprintf(fd, " state");
205         cp = " %s";
206         for (first = 1, p = statebits; p->t_bits > 0; p++) {
207                 if ((rt->rt_state & p->t_bits) == 0)
208                         continue;
209                 fprintf(fd, cp, p->t_name);
210                 if (first) {
211                         cp = "|%s";
212                         first = 0;
213                 }
214         }
215         putc('\n', fd);
216         if (!tracepackets && (rt->rt_state & RTS_PASSIVE) == 0 && rt->rt_ifp)
217                 dumpif(fd, rt->rt_ifp);
218         fflush(fd);
219 }
220
221 void
222 traceactionlog(action, rt)
223         char *action;
224         struct rt_entry *rt;
225 {
226         struct sockaddr_ipx *dst, *gate;
227         static struct bits {
228                 int     t_bits;
229                 char    *t_name;
230         } flagbits[] = {
231                 { RTF_UP,       "UP" },
232                 { RTF_GATEWAY,  "GATEWAY" },
233                 { RTF_HOST,     "HOST" },
234                 { 0 }
235         }, statebits[] = {
236                 { RTS_PASSIVE,  "PASSIVE" },
237                 { RTS_REMOTE,   "REMOTE" },
238                 { RTS_INTERFACE,"INTERFACE" },
239                 { RTS_CHANGED,  "CHANGED" },
240                 { 0 }
241         };
242         register struct bits *p;
243         register int first;
244         char *cp;
245         char *lstr, *olstr;
246
247         dst = (struct sockaddr_ipx *)&rt->rt_dst;
248         gate = (struct sockaddr_ipx *)&rt->rt_router;
249         asprintf(&lstr, "%s dst %s,", action, ipxdp_ntoa(&dst->sipx_addr));
250         olstr = lstr;
251         asprintf(&lstr, "%s router %s, metric %d, ticks %d, flags",
252              olstr, ipxdp_ntoa(&gate->sipx_addr), rt->rt_metric, rt->rt_ticks);
253         free(olstr);
254         olstr = lstr;
255         cp = "%s %s";
256         for (first = 1, p = flagbits; p->t_bits > 0; p++) {
257                 if ((rt->rt_flags & p->t_bits) == 0)
258                         continue;
259                 asprintf(&lstr, cp, olstr, p->t_name);
260                 free(olstr);
261                 olstr = lstr;
262                 if (first) {
263                         cp = "%s|%s";
264                         first = 0;
265                 }
266         }
267         asprintf(&lstr, "%s state", olstr);
268         free(olstr);
269         olstr = lstr;
270         cp = "%s %s";
271         for (first = 1, p = statebits; p->t_bits > 0; p++) {
272                 if ((rt->rt_state & p->t_bits) == 0)
273                         continue;
274                 asprintf(&lstr, cp, olstr, p->t_name);
275                 free(olstr);
276                 olstr = lstr;
277                 if (first) {
278                         cp = "%s|%s";
279                         first = 0;
280                 }
281         }
282         syslog(LOG_DEBUG, "%s", lstr);
283         free(lstr);
284 }
285
286 void
287 tracesapactionlog(action, sap)
288         char *action;
289         struct sap_entry *sap;
290 {
291         syslog(LOG_DEBUG, "%-12.12s  service %04X %-20.20s "
292                     "addr %s.%04X %c metric %d\n",
293                      action,
294                      ntohs(sap->sap.ServType),
295                      sap->sap.ServName,
296                      ipxdp_ntoa(&sap->sap.ipx),
297                      ntohs(sap->sap.ipx.x_port),
298                      (sap->clone ? 'C' : ' '),
299                      ntohs(sap->sap.hops));
300 }
301
302 void
303 dumpif(fd, ifp)
304         register struct interface *ifp;
305         FILE *fd;
306 {
307         if (ifp->int_input.ifd_count || ifp->int_output.ifd_count) {
308                 fprintf(fd, "*** Packet history for interface %s ***\n",
309                         ifp->int_name);
310                 dumptrace(fd, "to", &ifp->int_output);
311                 dumptrace(fd, "from", &ifp->int_input);
312                 fprintf(fd, "*** end packet history ***\n");
313         }
314 }
315
316 void
317 dumptrace(fd, dir, ifd)
318         FILE *fd;
319         char *dir;
320         register struct ifdebug *ifd;
321 {
322         register struct iftrace *t;
323         char *cp = !strcmp(dir, "to") ? "Output" : "Input";
324
325         if (ifd->ifd_front == ifd->ifd_records &&
326             ifd->ifd_front->ift_size == 0) {
327                 fprintf(fd, "%s: no packets.\n", cp);
328                 return;
329         }
330         fprintf(fd, "%s trace:\n", cp);
331         t = ifd->ifd_front - ifd->ifd_count;
332         if (t < ifd->ifd_records)
333                 t += NRECORDS;
334         for ( ; ifd->ifd_count; ifd->ifd_count--, t++) {
335                 if (t >= ifd->ifd_records + NRECORDS)
336                         t = ifd->ifd_records;
337                 if (t->ift_size == 0)
338                         continue;
339                 fprintf(fd, "%.24s: metric=%d\n", ctime(&t->ift_stamp),
340                         t->ift_metric);
341                 dumppacket(fd, dir, &t->ift_who, t->ift_packet, t->ift_size);
342         }
343 }
344
345 void
346 dumppacket(fd, dir, source, cp, size)
347         FILE *fd;
348         char *dir;
349         struct sockaddr *source;
350         char *cp;
351         register int size;
352 {
353         register struct rip *msg = (struct rip *)cp;
354         register struct netinfo *n;
355         struct sockaddr_ipx *who = (struct sockaddr_ipx *)source;
356
357         if (msg->rip_cmd && ntohs(msg->rip_cmd) < RIPCMD_MAX)
358                 fprintf(fd, "%s %s %s#%x", ripcmds[ntohs(msg->rip_cmd)],
359                     dir, ipxdp_ntoa(&who->sipx_addr), 
360                     ntohs(who->sipx_addr.x_port));
361         else {
362                 fprintf(fd, "Bad cmd 0x%x %s %s#%x\n", ntohs(msg->rip_cmd),
363                     dir, ipxdp_ntoa(&who->sipx_addr), 
364                     ntohs(who->sipx_addr.x_port));
365                 fprintf(fd, "size=%d cp=%x packet=%x\n", size, 
366                         (u_int)cp, (u_int)packet);
367                 return;
368         }
369         switch (ntohs(msg->rip_cmd)) {
370
371         case RIPCMD_REQUEST:
372         case RIPCMD_RESPONSE:
373                 fprintf(fd, ":\n");
374                 size -= sizeof (u_short);
375                 n = msg->rip_nets;
376                 for (; size > 0; n++, size -= sizeof (struct netinfo)) {
377                         if (size < sizeof (struct netinfo))
378                                 break;
379                         fprintf(fd, "\tnet %s metric %d ticks %d\n",
380                              ipxdp_nettoa(n->rip_dst),
381                              ntohs(n->rip_metric),
382                              ntohs(n->rip_ticks));
383                 }
384                 break;
385
386         }
387 }
388
389 void
390 dumpsappacket(fd, dir, source, cp, size)
391         FILE *fd;
392         char *dir;
393         struct sockaddr *source;
394         char *cp;
395         register int size;
396 {
397         register struct sap_packet *msg = (struct sap_packet *)cp;
398         register struct sap_info *n;
399         struct sockaddr_ipx *who = (struct sockaddr_ipx *)source;
400
401         if (msg->sap_cmd && ntohs(msg->sap_cmd) < SAPCMD_MAX)
402                 fprintf(fd, "%s %s %s#%x", sapcmds[ntohs(msg->sap_cmd)],
403                     dir, ipxdp_ntoa(&who->sipx_addr), 
404                     ntohs(who->sipx_addr.x_port));
405         else {
406                 fprintf(fd, "Bad cmd 0x%x %s %s#%x\n", ntohs(msg->sap_cmd),
407                     dir, ipxdp_ntoa(&who->sipx_addr), 
408                     ntohs(who->sipx_addr.x_port));
409                 fprintf(fd, "size=%d cp=%x packet=%x\n", size, 
410                         (u_int)cp, (u_int)packet);
411                 return;
412         }
413         switch (ntohs(msg->sap_cmd)) {
414
415         case SAP_REQ:
416         case SAP_RESP:
417         case SAP_REQ_NEAR:
418         case SAP_RESP_NEAR:
419                 fprintf(fd, ":\n");
420                 size -= sizeof (u_short);
421                 n = msg->sap;
422                 for (; size > 0; n++, size -= sizeof (struct sap_info)) {
423                         if (size < sizeof (struct sap_info))
424                                 break;
425                         fprintf(fd, "  service %04X %-20.20s "
426                                     "addr %s.%04X metric %d\n",
427                              ntohs(n->ServType),
428                              n->ServName,
429                              ipxdp_ntoa(&n->ipx),
430                              ntohs(n->ipx.x_port),
431                              ntohs(n->hops));
432                 }
433                 break;
434
435         }
436 }
437
438 void
439 dumpsaptable(fd, sh)
440         FILE *fd;
441         struct sap_hash *sh;
442 {
443         register struct sap_entry *sap;
444         struct sap_hash *hash;
445         int x = 0;
446
447         fprintf(fd, "------- SAP table dump. -------\n");
448         for (hash = sh; hash < &sh[SAPHASHSIZ]; hash++, x++) {
449                 fprintf(fd, "HASH %d\n", x);
450                 sap = hash->forw;
451                 for (; sap != (struct sap_entry *)hash; sap = sap->forw) {
452                         fprintf(fd, "  service %04X %-20.20s "
453                                     "addr %s.%04X %c metric %d\n",
454                                      ntohs(sap->sap.ServType),
455                                      sap->sap.ServName,
456                                      ipxdp_ntoa(&sap->sap.ipx),
457                                      ntohs(sap->sap.ipx.x_port),
458                                      (sap->clone ? 'C' : ' '),
459                                      ntohs(sap->sap.hops));
460                 }
461         }
462         fprintf(fd, "\n");
463 }
464
465 void
466 dumpriptable(fd)
467         FILE *fd;
468 {
469         register struct rt_entry *rip;
470         struct rthash *hash;
471         int x;
472         struct rthash *rh = nethash;
473
474         fprintf(fd, "------- RIP table dump. -------\n");
475         x = 0;
476         fprintf(fd, "Network table.\n");
477
478         for (hash = rh; hash < &rh[ROUTEHASHSIZ]; hash++, x++) {
479                 fprintf(fd, "HASH %d\n", x);
480                 rip = hash->rt_forw;
481                 for (; rip != (struct rt_entry *)hash; rip = rip->rt_forw) {
482                         fprintf(fd, "  dest %s\t", 
483                                 ipxdp_ntoa(&satoipx_addr(rip->rt_dst)));
484                         fprintf(fd, "%s metric %d, ticks %d\n",
485                                 ipxdp_ntoa(&satoipx_addr(rip->rt_router)),
486                                 rip->rt_metric,
487                                 rip->rt_ticks);
488                 }
489         }
490         fprintf(fd, "\n");
491 }
492
493 union ipx_net_u net;
494
495 char *
496 ipxdp_nettoa(val)
497 union ipx_net val;
498 {
499         static char buf[100];
500         net.net_e = val;
501         (void)sprintf(buf, "%lx", ntohl(net.long_e));
502         return (buf);
503 }
504
505
506 char *
507 ipxdp_ntoa(addr)
508 struct ipx_addr *addr;
509 {
510     static char buf[100];
511
512     (void)sprintf(buf, "%s#%x:%x:%x:%x:%x:%x",
513         ipxdp_nettoa(addr->x_net),
514         addr->x_host.c_host[0], addr->x_host.c_host[1], 
515         addr->x_host.c_host[2], addr->x_host.c_host[3], 
516         addr->x_host.c_host[4], addr->x_host.c_host[5]);
517         
518     return(buf);
519 }