]>
git.saurik.com Git - apple/network_cmds.git/blob - routed.tproj/trace.c
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
26 * Copyright (c) 1983, 1988, 1993
27 * The Regents of the University of California. All rights reserved.
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
32 * 1. Redistributions of source code must retain the above copyright
33 * notice, this list of conditions and the following disclaimer.
34 * 2. Redistributions in binary form must reproduce the above copyright
35 * notice, this list of conditions and the following disclaimer in the
36 * documentation and/or other materials provided with the distribution.
37 * 3. All advertising materials mentioning features or use of this software
38 * must display the following acknowledgment:
39 * This product includes software developed by the University of
40 * California, Berkeley and its contributors.
41 * 4. Neither the name of the University nor the names of its contributors
42 * may be used to endorse or promote products derived from this software
43 * without specific prior written permission.
45 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
57 * @(#)defs.h 8.1 (Berkeley) 6/5/93
62 * Routing Table Management Daemon
67 #include <sys/signal.h>
70 #include "pathnames.h"
72 #define NRECORDS 50 /* size of circular trace buffer */
74 FILE *ftrace
= stdout
;
77 static struct timeval lastlog
;
78 static char *savetracename
;
81 register struct interface
*ifp
;
83 static int iftraceinit();
85 if (iftraceinit(ifp
, &ifp
->int_input
) &&
86 iftraceinit(ifp
, &ifp
->int_output
))
89 fprintf(stderr
, "traceinit: can't init %s\n", ifp
->int_name
);
94 struct interface
*ifp
;
95 register struct ifdebug
*ifd
;
97 register struct iftrace
*t
;
100 (struct iftrace
*)malloc(NRECORDS
* sizeof (struct iftrace
));
101 if (ifd
->ifd_records
== 0)
103 ifd
->ifd_front
= ifd
->ifd_records
;
105 for (t
= ifd
->ifd_records
; t
< ifd
->ifd_records
+ NRECORDS
; t
++) {
120 if (stat(file
, &stbuf
) >= 0 && (stbuf
.st_mode
& S_IFMT
) != S_IFREG
)
122 savetracename
= file
;
123 (void) gettimeofday(&now
, (struct timezone
*)NULL
);
124 ftrace
= fopen(file
, "a");
127 dup2(fileno(ftrace
), 1);
128 dup2(fileno(ftrace
), 2);
130 fprintf(ftrace
, "Tracing enabled %s\n", ctime((time_t *)&now
.tv_sec
));
137 if (ftrace
!= NULL
) {
138 int fd
= open(_PATH_DEVNULL
, O_RDWR
);
140 fprintf(ftrace
, "Tracing disabled %s\n",
141 ctime((time_t *)&now
.tv_sec
));
162 else if (ftrace
== NULL
&& savetracename
)
163 traceon(savetracename
);
169 * Move to next higher level of tracing when -t option processed or
170 * SIGUSR1 is received. Successive levels are:
172 * traceactions + tracepackets
173 * traceactions + tracehistory (packets and contents after change)
174 * traceactions + tracepackets + tracecontents
179 (void) gettimeofday(&now
, (struct timezone
*)NULL
);
180 if (traceactions
== 0) {
183 fprintf(ftrace
, "Tracing actions started %s\n",
184 ctime((time_t *)&now
.tv_sec
));
185 } else if (tracepackets
== 0) {
190 fprintf(ftrace
, "Tracing packets started %s\n",
191 ctime((time_t *)&now
.tv_sec
));
192 } else if (tracehistory
== 0) {
195 fprintf(ftrace
, "Tracing history started %s\n",
196 ctime((time_t *)&now
.tv_sec
));
202 fprintf(ftrace
, "Tracing packet contents started %s\n",
203 ctime((time_t *)&now
.tv_sec
));
209 trace(ifd
, who
, p
, len
, m
)
210 register struct ifdebug
*ifd
;
211 struct sockaddr
*who
;
215 register struct iftrace
*t
;
217 if (ifd
->ifd_records
== 0)
219 t
= ifd
->ifd_front
++;
220 if (ifd
->ifd_front
>= ifd
->ifd_records
+ NRECORDS
)
221 ifd
->ifd_front
= ifd
->ifd_records
;
222 if (ifd
->ifd_count
< NRECORDS
)
224 if (t
->ift_size
> 0 && t
->ift_size
< len
&& t
->ift_packet
) {
230 if (len
> 0 && t
->ift_packet
== 0) {
231 t
->ift_packet
= malloc(len
);
232 if (t
->ift_packet
== 0)
236 memmove(t
->ift_packet
, p
, len
);
241 traceaction(fd
, action
, rt
)
246 struct sockaddr_in
*dst
, *gate
;
252 { RTF_GATEWAY
, "GATEWAY" },
253 { RTF_HOST
, "HOST" },
256 { RTS_PASSIVE
, "PASSIVE" },
257 { RTS_REMOTE
, "REMOTE" },
258 { RTS_INTERFACE
,"INTERFACE" },
259 { RTS_CHANGED
, "CHANGED" },
260 { RTS_INTERNAL
, "INTERNAL" },
261 { RTS_EXTERNAL
, "EXTERNAL" },
262 { RTS_SUBNET
, "SUBNET" },
265 register struct bits
*p
;
268 struct interface
*ifp
;
272 if (lastlog
.tv_sec
!= now
.tv_sec
|| lastlog
.tv_usec
!= now
.tv_usec
) {
273 fprintf(fd
, "\n%.19s:\n", ctime((time_t *)&now
.tv_sec
));
276 fprintf(fd
, "%s ", action
);
277 dst
= (struct sockaddr_in
*)&rt
->rt_dst
;
278 gate
= (struct sockaddr_in
*)&rt
->rt_router
;
279 fprintf(fd
, "dst %s, ", inet_ntoa(dst
->sin_addr
));
280 fprintf(fd
, "router %s, metric %d, flags",
281 inet_ntoa(gate
->sin_addr
), rt
->rt_metric
);
283 for (first
= 1, p
= flagbits
; p
->t_bits
> 0; p
++) {
284 if ((rt
->rt_flags
& p
->t_bits
) == 0)
286 fprintf(fd
, cp
, p
->t_name
);
292 fprintf(fd
, " state");
294 for (first
= 1, p
= statebits
; p
->t_bits
> 0; p
++) {
295 if ((rt
->rt_state
& p
->t_bits
) == 0)
297 fprintf(fd
, cp
, p
->t_name
);
303 fprintf(fd
, " timer %d\n", rt
->rt_timer
);
304 if (tracehistory
&& !tracepackets
&&
305 (rt
->rt_state
& RTS_PASSIVE
) == 0 && rt
->rt_ifp
)
306 dumpif(fd
, rt
->rt_ifp
);
312 tracenewmetric(fd
, rt
, newmetric
)
317 struct sockaddr_in
*dst
, *gate
;
321 if (lastlog
.tv_sec
!= now
.tv_sec
|| lastlog
.tv_usec
!= now
.tv_usec
) {
322 fprintf(fd
, "\n%.19s:\n", ctime((time_t *)&now
.tv_sec
));
325 dst
= (struct sockaddr_in
*)&rt
->rt_dst
;
326 gate
= (struct sockaddr_in
*)&rt
->rt_router
;
327 fprintf(fd
, "CHANGE metric dst %s, ", inet_ntoa(dst
->sin_addr
));
328 fprintf(fd
, "router %s, from %d to %d\n",
329 inet_ntoa(gate
->sin_addr
), rt
->rt_metric
, newmetric
);
337 register struct interface
*ifp
;
339 if (ifp
->int_input
.ifd_count
|| ifp
->int_output
.ifd_count
) {
340 fprintf(fd
, "*** Packet history for interface %s ***\n",
343 dumptrace(fd
, "to", &ifp
->int_output
);
345 dumptrace(fd
, "from", &ifp
->int_input
);
346 fprintf(fd
, "*** end packet history ***\n");
350 dumptrace(fd
, dir
, ifd
)
353 register struct ifdebug
*ifd
;
355 register struct iftrace
*t
;
356 char *cp
= !strcmp(dir
, "to") ? "Output" : "Input";
358 if (ifd
->ifd_front
== ifd
->ifd_records
&&
359 ifd
->ifd_front
->ift_size
== 0) {
360 fprintf(fd
, "%s: no packets.\n", cp
);
364 fprintf(fd
, "%s trace:\n", cp
);
365 t
= ifd
->ifd_front
- ifd
->ifd_count
;
366 if (t
< ifd
->ifd_records
)
368 for ( ; ifd
->ifd_count
; ifd
->ifd_count
--, t
++) {
369 if (t
>= ifd
->ifd_records
+ NRECORDS
)
370 t
= ifd
->ifd_records
;
371 if (t
->ift_size
== 0)
373 dumppacket(fd
, dir
, &t
->ift_who
, t
->ift_packet
, t
->ift_size
,
378 dumppacket(fd
, dir
, who
, cp
, size
, stamp
)
380 struct sockaddr_in
*who
; /* should be sockaddr */
383 struct timeval
*stamp
;
385 register struct rip
*msg
= (struct rip
*)cp
;
386 register struct netinfo
*n
;
390 if (msg
->rip_cmd
&& msg
->rip_cmd
< RIPCMD_MAX
)
391 fprintf(fd
, "%s %s %s.%d %.19s:\n", ripcmds
[msg
->rip_cmd
],
392 dir
, inet_ntoa(who
->sin_addr
), ntohs(who
->sin_port
),
393 ctime((time_t *)&stamp
->tv_sec
));
395 fprintf(fd
, "Bad cmd 0x%x %s %x.%d %.19s\n", msg
->rip_cmd
,
396 dir
, inet_ntoa(who
->sin_addr
), ntohs(who
->sin_port
));
397 fprintf(fd
, "size=%d cp=%x packet=%x\n", size
, cp
, packet
,
398 ctime((time_t *)&stamp
->tv_sec
));
402 if (tracepackets
&& tracecontents
== 0) {
406 switch (msg
->rip_cmd
) {
409 case RIPCMD_RESPONSE
:
410 size
-= 4 * sizeof (char);
412 for (; size
> 0; n
++, size
-= sizeof (struct netinfo
)) {
413 if (size
< sizeof (struct netinfo
)) {
414 fprintf(fd
, "(truncated record, len %d)\n",
418 if (sizeof(n
->rip_dst
.sa_family
) > 1)
419 n
->rip_dst
.sa_family
= ntohs(n
->rip_dst
.sa_family
);
421 switch ((int)n
->rip_dst
.sa_family
) {
424 fprintf(fd
, "\tdst %s metric %d\n",
425 #define satosin(sa) ((struct sockaddr_in *)&sa)
426 inet_ntoa(satosin(n
->rip_dst
)->sin_addr
),
427 ntohl(n
->rip_metric
));
431 fprintf(fd
, "\taf %d? metric %d\n",
432 n
->rip_dst
.sa_family
,
433 ntohl(n
->rip_metric
));
440 fprintf(fd
, "\tfile=%*s\n", size
, msg
->rip_tracefile
);
443 case RIPCMD_TRACEOFF
: