summaryrefslogtreecommitdiffstats
path: root/mdk-stage1/rp-pppoe/src/debug.c
blob: 052dca6c7462e4c6166c33d0fa11bddb34fba65e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/***********************************************************************
*
* debug.c
*
* Implementation of user-space PPPoE redirector for Linux.
*
* Functions for printing debugging information
*
* Copyright (C) 2000 by Roaring Penguin Software Inc.
*
* This program may be distributed according to the terms of the GNU
* General Public License, version 2 or (at your option) any later version.
*
***********************************************************************/

static char const RCSID[] =
"$Id$";

#include "pppoe.h"
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
#include <ctype.h>

/**********************************************************************
*%FUNCTION: dumpHex
*%ARGUMENTS:
* fp -- file to dump to
* buf -- buffer to dump
* len -- length of data
*%RETURNS:
* Nothing
*%DESCRIPTION:
* Dumps buffer to fp in an easy-to-read format
***********************************************************************/
void
dumpHex(FILE *fp, unsigned char const *buf, int len)
{
    int i;
    int base;

    if (!fp) return;

    /* do NOT dump PAP packets */
    if (len >= 2 && buf[0] == 0xC0 && buf[1] == 0x23) {
	fprintf(fp, "(PAP Authentication Frame -- Contents not dumped)\n");
	return;
    }

    for (base=0; base<len; base += 16) {
	for (i=base; i<base+16; i++) {
	    if (i < len) {
		fprintf(fp, "%02x ", (unsigned) buf[i]);
	    } else {
		fprintf(fp, "   ");
	    }
	}
	fprintf(fp, "  ");
	for (i=base; i<base+16; i++) {
	    if (i < len) {
		if (isprint(buf[i])) {
		    fprintf(fp, "%c", buf[i]);
		} else {
		    fprintf(fp, ".");
		}
	    } else {
		break;
	    }
	}
	fprintf(fp, "\n");
    }
}

/**********************************************************************
*%FUNCTION: dumpPacket
*%ARGUMENTS:
* fp -- file to dump to
* packet -- a PPPoE packet
* dir -- either SENT or RCVD
*%RETURNS:
* Nothing
*%DESCRIPTION:
* Dumps the PPPoE packet to fp in an easy-to-read format
***********************************************************************/
void
dumpPacket(FILE *fp, PPPoEPacket *packet, char const *dir)
{
    int len = ntohs(packet->length);

    /* Sheesh... printing times is a pain... */
    struct timeval tv;
    time_t now;
    int millisec;
    struct tm *lt;
    char timebuf[256];

    UINT16_t type = etherType(packet);
    if (!fp) return;
    gettimeofday(&tv, NULL);
    now = (time_t) tv.tv_sec;
    millisec = tv.tv_usec / 1000;
    lt = localtime(&now);
    strftime(timebuf, 256, "%H:%M:%S", lt);
    fprintf(fp, "%s.%03d %s PPPoE ", timebuf, millisec, dir);
    if (type == Eth_PPPOE_Discovery) {
	fprintf(fp, "Discovery (%x) ", (unsigned) type);
    } else if (type == Eth_PPPOE_Session) {
	fprintf(fp, "Session (%x) ", (unsigned) type);
    } else {
	fprintf(fp, "Unknown (%x) ", (unsigned) type);
    }

    switch(packet->code) {
    case CODE_PADI: fprintf(fp, "PADI "); break;
    case CODE_PADO: fprintf(fp, "PADO "); break;
    case CODE_PADR: fprintf(fp, "PADR "); break;
    case CODE_PADS: fprintf(fp, "PADS "); break;
    case CODE_PADT: fprintf(fp, "PADT "); break;
    case CODE_SESS: fprintf(fp, "SESS "); break;
    }

    fprintf(fp, "sess-id %d length %d\n",
	    (int) ntohs(packet->session),
	    len);

    /* Ugly... I apologize... */
    fprintf(fp,
	    "SourceAddr %02x:%02x:%02x:%02x:%02x:%02x "
	    "DestAddr %02x:%02x:%02x:%02x:%02x:%02x\n",
	    (unsigned) packet->ethHdr.h_source[0],
	    (unsigned) packet->ethHdr.h_source[1],
	    (unsigned) packet->ethHdr.h_source[2],
	    (unsigned) packet->ethHdr.h_source[3],
	    (unsigned) packet->ethHdr.h_source[4],
	    (unsigned) packet->ethHdr.h_source[5],
	    (unsigned) packet->ethHdr.h_dest[0],
	    (unsigned) packet->ethHdr.h_dest[1],
	    (unsigned) packet->ethHdr.h_dest[2],
	    (unsigned) packet->ethHdr.h_dest[3],
	    (unsigned) packet->ethHdr.h_dest[4],
	    (unsigned) packet->ethHdr.h_dest[5]);
    dumpHex(fp, packet->payload, ntohs(packet->length));
}