diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/cmd-inet/usr.lib/in.ripngd/trace.c	Tue Jun 02 18:56:50 2009 +0900
@@ -0,0 +1,264 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
+/*	  All Rights Reserved  	*/
+
+/*
+ * Portions of this source code were derived from Berkeley 4.3 BSD
+ * under license from the Regents of the University of California.
+ */
+
+#pragma ident	"@(#)trace.c	1.5	05/06/08 SMI"	/* SVr4.0 1.1	*/
+
+/*
+ * Routing Table Management Daemon
+ */
+#include "defs.h"
+
+#define	NRECORDS	50		/* size of circular trace buffer */
+
+boolean_t	tracepackets;		/* watch packets as they go by */
+int		tracing;		/* bitmask: */
+FILE		*ftrace;		/* output trace file */
+
+static int	iftraceinit(struct interface *ifp, struct ifdebug *ifd);
+static void	dumpif(FILE *fp, struct interface *ifp);
+static void	dumptrace(FILE *fp, char *dir, struct ifdebug *ifd);
+
+void
+traceinit(struct interface *ifp)
+{
+	if (iftraceinit(ifp, &ifp->int_input) &&
+	    iftraceinit(ifp, &ifp->int_output))
+		return;
+	tracing = 0;
+	(void) fprintf(stderr, "traceinit: can't init %s\n",
+	    (ifp->int_name != NULL) ? ifp->int_name : "(noname)");
+}
+
+static int
+iftraceinit(struct interface *ifp, struct ifdebug *ifd)
+{
+	struct iftrace *t;
+
+	ifd->ifd_records = (struct iftrace *)
+	    malloc((size_t)NRECORDS * sizeof (struct iftrace));
+	if (ifd->ifd_records == NULL)
+		return (0);
+	ifd->ifd_front = ifd->ifd_records;
+	ifd->ifd_count = 0;
+	for (t = ifd->ifd_records; t < ifd->ifd_records + NRECORDS; t++) {
+		t->ift_size = 0;
+		t->ift_packet = NULL;
+	}
+	ifd->ifd_if = ifp;
+	return (1);
+}
+
+void
+traceon(char *file)
+{
+	struct stat stbuf;
+
+	if (ftrace != NULL)
+		return;
+	if (stat(file, &stbuf) >= 0 && (stbuf.st_mode & S_IFMT) != S_IFREG)
+		return;
+	ftrace = fopen(file, "a");
+	if (ftrace == NULL)
+		return;
+	(void) dup2(fileno(ftrace), 1);
+	(void) dup2(fileno(ftrace), 2);
+}
+
+void
+traceonfp(FILE *fp)
+{
+	if (ftrace != NULL)
+		return;
+	ftrace = fp;
+	if (ftrace == NULL)
+		return;
+	(void) dup2(fileno(ftrace), 1);
+	(void) dup2(fileno(ftrace), 2);
+}
+
+void
+trace(struct ifdebug *ifd, struct sockaddr_in6 *who, char *p, int len, int m)
+{
+	struct iftrace *t;
+
+	if (ifd->ifd_records == 0)
+		return;
+	t = ifd->ifd_front++;
+	if (ifd->ifd_front >= ifd->ifd_records + NRECORDS)
+		ifd->ifd_front = ifd->ifd_records;
+	if (ifd->ifd_count < NRECORDS)
+		ifd->ifd_count++;
+	if (t->ift_size > 0 && t->ift_size < len && t->ift_packet != NULL) {
+		free(t->ift_packet);
+		t->ift_packet = NULL;
+	}
+	(void) time(&t->ift_stamp);
+	t->ift_who = *who;
+	if (len > 0 && t->ift_packet == NULL) {
+		t->ift_packet = (char *)malloc((size_t)len);
+		if (t->ift_packet == NULL)
+			len = 0;
+	}
+	if (len > 0)
+		bcopy(p, t->ift_packet, len);
+	t->ift_size = len;
+	t->ift_metric = m;
+}
+
+void
+traceaction(FILE *fp, char *action, struct rt_entry *rt)
+{
+	static struct bits {
+		ulong_t	t_bits;
+		char	*t_name;
+	} flagbits[] = {
+		/* BEGIN CSTYLED */
+		{ RTF_UP,		"UP" },
+		{ RTF_GATEWAY,		"GATEWAY" },
+		{ RTF_HOST,		"HOST" },
+		{ 0,			NULL }
+		/* END CSTYLED */
+	}, statebits[] = {
+		/* BEGIN CSTYLED */
+		{ RTS_INTERFACE,	"INTERFACE" },
+		{ RTS_CHANGED,		"CHANGED" },
+		{ RTS_PRIVATE,		"PRIVATE" },
+		{ 0,			NULL }
+		/* END CSTYLED */
+	};
+	struct bits *p;
+	boolean_t first;
+	char c;
+	time_t t;
+
+	if (fp == NULL)
+		return;
+	(void) time(&t);
+	(void) fprintf(fp, "%.15s %s ", ctime(&t) + 4, action);
+	if (rt != NULL) {
+		char buf1[INET6_ADDRSTRLEN];
+
+		(void) fprintf(fp, "prefix %s/%d ",
+		    inet_ntop(AF_INET6, (void *)&rt->rt_dst, buf1,
+			sizeof (buf1)),
+		    rt->rt_prefix_length);
+		(void) fprintf(fp, "via %s metric %d",
+		    inet_ntop(AF_INET6, (void *)&rt->rt_router, buf1,
+			sizeof (buf1)),
+		    rt->rt_metric);
+		if (rt->rt_ifp != NULL) {
+			(void) fprintf(fp, " if %s",
+			    (rt->rt_ifp->int_name != NULL) ?
+				rt->rt_ifp->int_name : "(noname)");
+		}
+		(void) fprintf(fp, " state");
+		c = ' ';
+		for (first = _B_TRUE, p = statebits; p->t_bits > 0; p++) {
+			if ((rt->rt_state & p->t_bits) == 0)
+				continue;
+			(void) fprintf(fp, "%c%s", c, p->t_name);
+			if (first) {
+				c = '|';
+				first = _B_FALSE;
+			}
+		}
+		if (first)
+			(void) fprintf(fp, " 0");
+		if (rt->rt_flags & (RTF_UP | RTF_GATEWAY)) {
+			c = ' ';
+			for (first = _B_TRUE, p = flagbits; p->t_bits > 0;
+			    p++) {
+				if ((rt->rt_flags & p->t_bits) == 0)
+					continue;
+				(void) fprintf(fp, "%c%s", c, p->t_name);
+				if (first) {
+					c = '|';
+					first = _B_FALSE;
+				}
+			}
+		}
+	}
+	(void) putc('\n', fp);
+	if (!tracepackets && rt != NULL && rt->rt_ifp != NULL)
+		dumpif(fp, rt->rt_ifp);
+	(void) fflush(fp);
+}
+
+static void
+dumpif(FILE *fp, struct interface *ifp)
+{
+	if (ifp->int_input.ifd_count != 0 || ifp->int_output.ifd_count != 0) {
+		(void) fprintf(fp, "*** Packet history for interface %s ***\n",
+		    (ifp->int_name != NULL) ? ifp->int_name : "(noname)");
+		dumptrace(fp, "to", &ifp->int_output);
+		dumptrace(fp, "from", &ifp->int_input);
+		(void) fprintf(fp, "*** end packet history ***\n");
+	}
+	(void) fflush(fp);
+}
+
+static void
+dumptrace(FILE *fp, char *dir, struct ifdebug *ifd)
+{
+	struct iftrace *t;
+	char *cp = (strcmp(dir, "to") != 0) ? "Output" : "Input";
+
+	if (ifd->ifd_front == ifd->ifd_records &&
+	    ifd->ifd_front->ift_size == 0) {
+		(void) fprintf(fp, "%s: no packets.\n", cp);
+		(void) fflush(fp);
+		return;
+	}
+	(void) fprintf(fp, "%s trace:\n", cp);
+	t = ifd->ifd_front - ifd->ifd_count;
+	if (t < ifd->ifd_records)
+		t += NRECORDS;
+	for (; ifd->ifd_count; ifd->ifd_count--, t++) {
+		if (t >= ifd->ifd_records + NRECORDS)
+			t = ifd->ifd_records;
+		if (t->ift_size == 0)
+			continue;
+		(void) fprintf(fp, "%.24s: metric=%d\n", ctime(&t->ift_stamp),
+		    t->ift_metric);
+		dumppacket(fp, dir, (struct sockaddr_in6 *)&t->ift_who,
+		    t->ift_packet, t->ift_size);
+	}
+}
+
+/*ARGSUSED*/
+void
+dumppacket(FILE *fp, char *dir, struct sockaddr_in6 *who, char *cp, int size)
+{
+	/* XXX Output contents of the RIP packet */
+}