1/***********************************************************************
2*
3* debug.c
4*
5* Implementation of user-space PPPoE redirector for Linux.
6*
7* Functions for printing debugging information
8*
9* Copyright (C) 2000 by Roaring Penguin Software Inc.
10*
11* This program may be distributed according to the terms of the GNU
12* General Public License, version 2 or (at your option) any later version.
13*
14* LIC: GPL
15*
16***********************************************************************/
17
18static char const RCSID[] =
19"$Id: debug.c,v 1.1.1.1 2008/10/15 03:30:51 james26_jang Exp $";
20
21#include "pppoe.h"
22#include <sys/time.h>
23#include <time.h>
24#include <unistd.h>
25#include <ctype.h>
26
27/**********************************************************************
28*%FUNCTION: dumpHex
29*%ARGUMENTS:
30* fp -- file to dump to
31* buf -- buffer to dump
32* len -- length of data
33*%RETURNS:
34* Nothing
35*%DESCRIPTION:
36* Dumps buffer to fp in an easy-to-read format
37***********************************************************************/
38void
39dumpHex(FILE *fp, unsigned char const *buf, int len)
40{
41    int i;
42    int base;
43
44    if (!fp) return;
45
46    /* do NOT dump PAP packets */
47    if (len >= 2 && buf[0] == 0xC0 && buf[1] == 0x23) {
48	fprintf(fp, "(PAP Authentication Frame -- Contents not dumped)\n");
49	return;
50    }
51
52    for (base=0; base<len; base += 16) {
53	for (i=base; i<base+16; i++) {
54	    if (i < len) {
55		fprintf(fp, "%02x ", (unsigned) buf[i]);
56	    } else {
57		fprintf(fp, "   ");
58	    }
59	}
60	fprintf(fp, "  ");
61	for (i=base; i<base+16; i++) {
62	    if (i < len) {
63		if (isprint(buf[i])) {
64		    fprintf(fp, "%c", buf[i]);
65		} else {
66		    fprintf(fp, ".");
67		}
68	    } else {
69		break;
70	    }
71	}
72	fprintf(fp, "\n");
73    }
74}
75
76/**********************************************************************
77*%FUNCTION: dumpPacket
78*%ARGUMENTS:
79* fp -- file to dump to
80* packet -- a PPPoE packet
81* dir -- either SENT or RCVD
82*%RETURNS:
83* Nothing
84*%DESCRIPTION:
85* Dumps the PPPoE packet to fp in an easy-to-read format
86***********************************************************************/
87void
88dumpPacket(FILE *fp, PPPoEPacket *packet, char const *dir)
89{
90    int len = ntohs(packet->length);
91
92    /* Sheesh... printing times is a pain... */
93    struct timeval tv;
94    time_t now;
95    int millisec;
96    struct tm *lt;
97    char timebuf[256];
98
99    UINT16_t type = etherType(packet);
100    if (!fp) return;
101    gettimeofday(&tv, NULL);
102    now = (time_t) tv.tv_sec;
103    millisec = tv.tv_usec / 1000;
104    lt = localtime(&now);
105    strftime(timebuf, 256, "%H:%M:%S", lt);
106    fprintf(fp, "%s.%03d %s PPPoE ", timebuf, millisec, dir);
107    if (type == Eth_PPPOE_Discovery) {
108	fprintf(fp, "Discovery (%x) ", (unsigned) type);
109    } else if (type == Eth_PPPOE_Session) {
110	fprintf(fp, "Session (%x) ", (unsigned) type);
111    } else {
112	fprintf(fp, "Unknown (%x) ", (unsigned) type);
113    }
114
115    switch(packet->code) {
116    case CODE_PADI: fprintf(fp, "PADI "); break;
117    case CODE_PADO: fprintf(fp, "PADO "); break;
118    case CODE_PADR: fprintf(fp, "PADR "); break;
119    case CODE_PADS: fprintf(fp, "PADS "); break;
120    case CODE_PADT: fprintf(fp, "PADT "); break;
121    case CODE_PADM: fprintf(fp, "PADM "); break;
122    case CODE_PADN: fprintf(fp, "PADN "); break;
123    case CODE_SESS: fprintf(fp, "SESS "); break;
124    }
125
126    fprintf(fp, "sess-id %d length %d\n",
127	    (int) ntohs(packet->session),
128	    len);
129
130    /* Ugly... I apologize... */
131    fprintf(fp,
132	    "SourceAddr %02x:%02x:%02x:%02x:%02x:%02x "
133	    "DestAddr %02x:%02x:%02x:%02x:%02x:%02x\n",
134	    (unsigned) packet->ethHdr.h_source[0],
135	    (unsigned) packet->ethHdr.h_source[1],
136	    (unsigned) packet->ethHdr.h_source[2],
137	    (unsigned) packet->ethHdr.h_source[3],
138	    (unsigned) packet->ethHdr.h_source[4],
139	    (unsigned) packet->ethHdr.h_source[5],
140	    (unsigned) packet->ethHdr.h_dest[0],
141	    (unsigned) packet->ethHdr.h_dest[1],
142	    (unsigned) packet->ethHdr.h_dest[2],
143	    (unsigned) packet->ethHdr.h_dest[3],
144	    (unsigned) packet->ethHdr.h_dest[4],
145	    (unsigned) packet->ethHdr.h_dest[5]);
146    dumpHex(fp, packet->payload, ntohs(packet->length));
147}
148