Mercurial > illumos > onarm
comparison usr/src/cmd/cmd-inet/usr.lib/in.ripngd/trace.c @ 0:c9caec207d52 b86
Initial porting based on b86
author | Koji Uno <koji.uno@sun.com> |
---|---|
date | Tue, 02 Jun 2009 18:56:50 +0900 |
parents | |
children | 1a15d5aaf794 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:c9caec207d52 |
---|---|
1 /* | |
2 * CDDL HEADER START | |
3 * | |
4 * The contents of this file are subject to the terms of the | |
5 * Common Development and Distribution License, Version 1.0 only | |
6 * (the "License"). You may not use this file except in compliance | |
7 * with the License. | |
8 * | |
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE | |
10 * or http://www.opensolaris.org/os/licensing. | |
11 * See the License for the specific language governing permissions | |
12 * and limitations under the License. | |
13 * | |
14 * When distributing Covered Code, include this CDDL HEADER in each | |
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. | |
16 * If applicable, add the following below this CDDL HEADER, with the | |
17 * fields enclosed by brackets "[]" replaced with your own identifying | |
18 * information: Portions Copyright [yyyy] [name of copyright owner] | |
19 * | |
20 * CDDL HEADER END | |
21 */ | |
22 /* | |
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. | |
24 * Use is subject to license terms. | |
25 */ | |
26 | |
27 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ | |
28 /* All Rights Reserved */ | |
29 | |
30 /* | |
31 * Portions of this source code were derived from Berkeley 4.3 BSD | |
32 * under license from the Regents of the University of California. | |
33 */ | |
34 | |
35 #pragma ident "@(#)trace.c 1.5 05/06/08 SMI" /* SVr4.0 1.1 */ | |
36 | |
37 /* | |
38 * Routing Table Management Daemon | |
39 */ | |
40 #include "defs.h" | |
41 | |
42 #define NRECORDS 50 /* size of circular trace buffer */ | |
43 | |
44 boolean_t tracepackets; /* watch packets as they go by */ | |
45 int tracing; /* bitmask: */ | |
46 FILE *ftrace; /* output trace file */ | |
47 | |
48 static int iftraceinit(struct interface *ifp, struct ifdebug *ifd); | |
49 static void dumpif(FILE *fp, struct interface *ifp); | |
50 static void dumptrace(FILE *fp, char *dir, struct ifdebug *ifd); | |
51 | |
52 void | |
53 traceinit(struct interface *ifp) | |
54 { | |
55 if (iftraceinit(ifp, &ifp->int_input) && | |
56 iftraceinit(ifp, &ifp->int_output)) | |
57 return; | |
58 tracing = 0; | |
59 (void) fprintf(stderr, "traceinit: can't init %s\n", | |
60 (ifp->int_name != NULL) ? ifp->int_name : "(noname)"); | |
61 } | |
62 | |
63 static int | |
64 iftraceinit(struct interface *ifp, struct ifdebug *ifd) | |
65 { | |
66 struct iftrace *t; | |
67 | |
68 ifd->ifd_records = (struct iftrace *) | |
69 malloc((size_t)NRECORDS * sizeof (struct iftrace)); | |
70 if (ifd->ifd_records == NULL) | |
71 return (0); | |
72 ifd->ifd_front = ifd->ifd_records; | |
73 ifd->ifd_count = 0; | |
74 for (t = ifd->ifd_records; t < ifd->ifd_records + NRECORDS; t++) { | |
75 t->ift_size = 0; | |
76 t->ift_packet = NULL; | |
77 } | |
78 ifd->ifd_if = ifp; | |
79 return (1); | |
80 } | |
81 | |
82 void | |
83 traceon(char *file) | |
84 { | |
85 struct stat stbuf; | |
86 | |
87 if (ftrace != NULL) | |
88 return; | |
89 if (stat(file, &stbuf) >= 0 && (stbuf.st_mode & S_IFMT) != S_IFREG) | |
90 return; | |
91 ftrace = fopen(file, "a"); | |
92 if (ftrace == NULL) | |
93 return; | |
94 (void) dup2(fileno(ftrace), 1); | |
95 (void) dup2(fileno(ftrace), 2); | |
96 } | |
97 | |
98 void | |
99 traceonfp(FILE *fp) | |
100 { | |
101 if (ftrace != NULL) | |
102 return; | |
103 ftrace = fp; | |
104 if (ftrace == NULL) | |
105 return; | |
106 (void) dup2(fileno(ftrace), 1); | |
107 (void) dup2(fileno(ftrace), 2); | |
108 } | |
109 | |
110 void | |
111 trace(struct ifdebug *ifd, struct sockaddr_in6 *who, char *p, int len, int m) | |
112 { | |
113 struct iftrace *t; | |
114 | |
115 if (ifd->ifd_records == 0) | |
116 return; | |
117 t = ifd->ifd_front++; | |
118 if (ifd->ifd_front >= ifd->ifd_records + NRECORDS) | |
119 ifd->ifd_front = ifd->ifd_records; | |
120 if (ifd->ifd_count < NRECORDS) | |
121 ifd->ifd_count++; | |
122 if (t->ift_size > 0 && t->ift_size < len && t->ift_packet != NULL) { | |
123 free(t->ift_packet); | |
124 t->ift_packet = NULL; | |
125 } | |
126 (void) time(&t->ift_stamp); | |
127 t->ift_who = *who; | |
128 if (len > 0 && t->ift_packet == NULL) { | |
129 t->ift_packet = (char *)malloc((size_t)len); | |
130 if (t->ift_packet == NULL) | |
131 len = 0; | |
132 } | |
133 if (len > 0) | |
134 bcopy(p, t->ift_packet, len); | |
135 t->ift_size = len; | |
136 t->ift_metric = m; | |
137 } | |
138 | |
139 void | |
140 traceaction(FILE *fp, char *action, struct rt_entry *rt) | |
141 { | |
142 static struct bits { | |
143 ulong_t t_bits; | |
144 char *t_name; | |
145 } flagbits[] = { | |
146 /* BEGIN CSTYLED */ | |
147 { RTF_UP, "UP" }, | |
148 { RTF_GATEWAY, "GATEWAY" }, | |
149 { RTF_HOST, "HOST" }, | |
150 { 0, NULL } | |
151 /* END CSTYLED */ | |
152 }, statebits[] = { | |
153 /* BEGIN CSTYLED */ | |
154 { RTS_INTERFACE, "INTERFACE" }, | |
155 { RTS_CHANGED, "CHANGED" }, | |
156 { RTS_PRIVATE, "PRIVATE" }, | |
157 { 0, NULL } | |
158 /* END CSTYLED */ | |
159 }; | |
160 struct bits *p; | |
161 boolean_t first; | |
162 char c; | |
163 time_t t; | |
164 | |
165 if (fp == NULL) | |
166 return; | |
167 (void) time(&t); | |
168 (void) fprintf(fp, "%.15s %s ", ctime(&t) + 4, action); | |
169 if (rt != NULL) { | |
170 char buf1[INET6_ADDRSTRLEN]; | |
171 | |
172 (void) fprintf(fp, "prefix %s/%d ", | |
173 inet_ntop(AF_INET6, (void *)&rt->rt_dst, buf1, | |
174 sizeof (buf1)), | |
175 rt->rt_prefix_length); | |
176 (void) fprintf(fp, "via %s metric %d", | |
177 inet_ntop(AF_INET6, (void *)&rt->rt_router, buf1, | |
178 sizeof (buf1)), | |
179 rt->rt_metric); | |
180 if (rt->rt_ifp != NULL) { | |
181 (void) fprintf(fp, " if %s", | |
182 (rt->rt_ifp->int_name != NULL) ? | |
183 rt->rt_ifp->int_name : "(noname)"); | |
184 } | |
185 (void) fprintf(fp, " state"); | |
186 c = ' '; | |
187 for (first = _B_TRUE, p = statebits; p->t_bits > 0; p++) { | |
188 if ((rt->rt_state & p->t_bits) == 0) | |
189 continue; | |
190 (void) fprintf(fp, "%c%s", c, p->t_name); | |
191 if (first) { | |
192 c = '|'; | |
193 first = _B_FALSE; | |
194 } | |
195 } | |
196 if (first) | |
197 (void) fprintf(fp, " 0"); | |
198 if (rt->rt_flags & (RTF_UP | RTF_GATEWAY)) { | |
199 c = ' '; | |
200 for (first = _B_TRUE, p = flagbits; p->t_bits > 0; | |
201 p++) { | |
202 if ((rt->rt_flags & p->t_bits) == 0) | |
203 continue; | |
204 (void) fprintf(fp, "%c%s", c, p->t_name); | |
205 if (first) { | |
206 c = '|'; | |
207 first = _B_FALSE; | |
208 } | |
209 } | |
210 } | |
211 } | |
212 (void) putc('\n', fp); | |
213 if (!tracepackets && rt != NULL && rt->rt_ifp != NULL) | |
214 dumpif(fp, rt->rt_ifp); | |
215 (void) fflush(fp); | |
216 } | |
217 | |
218 static void | |
219 dumpif(FILE *fp, struct interface *ifp) | |
220 { | |
221 if (ifp->int_input.ifd_count != 0 || ifp->int_output.ifd_count != 0) { | |
222 (void) fprintf(fp, "*** Packet history for interface %s ***\n", | |
223 (ifp->int_name != NULL) ? ifp->int_name : "(noname)"); | |
224 dumptrace(fp, "to", &ifp->int_output); | |
225 dumptrace(fp, "from", &ifp->int_input); | |
226 (void) fprintf(fp, "*** end packet history ***\n"); | |
227 } | |
228 (void) fflush(fp); | |
229 } | |
230 | |
231 static void | |
232 dumptrace(FILE *fp, char *dir, struct ifdebug *ifd) | |
233 { | |
234 struct iftrace *t; | |
235 char *cp = (strcmp(dir, "to") != 0) ? "Output" : "Input"; | |
236 | |
237 if (ifd->ifd_front == ifd->ifd_records && | |
238 ifd->ifd_front->ift_size == 0) { | |
239 (void) fprintf(fp, "%s: no packets.\n", cp); | |
240 (void) fflush(fp); | |
241 return; | |
242 } | |
243 (void) fprintf(fp, "%s trace:\n", cp); | |
244 t = ifd->ifd_front - ifd->ifd_count; | |
245 if (t < ifd->ifd_records) | |
246 t += NRECORDS; | |
247 for (; ifd->ifd_count; ifd->ifd_count--, t++) { | |
248 if (t >= ifd->ifd_records + NRECORDS) | |
249 t = ifd->ifd_records; | |
250 if (t->ift_size == 0) | |
251 continue; | |
252 (void) fprintf(fp, "%.24s: metric=%d\n", ctime(&t->ift_stamp), | |
253 t->ift_metric); | |
254 dumppacket(fp, dir, (struct sockaddr_in6 *)&t->ift_who, | |
255 t->ift_packet, t->ift_size); | |
256 } | |
257 } | |
258 | |
259 /*ARGSUSED*/ | |
260 void | |
261 dumppacket(FILE *fp, char *dir, struct sockaddr_in6 *who, char *cp, int size) | |
262 { | |
263 /* XXX Output contents of the RIP packet */ | |
264 } |