summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/tcpdump/Makefile4
-rw-r--r--usr.sbin/tcpdump/print-radius.c258
-rw-r--r--usr.sbin/tcpdump/print-udp.c12
-rw-r--r--usr.sbin/tcpdump/radius.h84
4 files changed, 355 insertions, 3 deletions
diff --git a/usr.sbin/tcpdump/Makefile b/usr.sbin/tcpdump/Makefile
index e3a4de6c60b..2aa31c189f8 100644
--- a/usr.sbin/tcpdump/Makefile
+++ b/usr.sbin/tcpdump/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.8 1997/07/14 22:23:08 deraadt Exp $
+# $OpenBSD: Makefile,v 1.9 1997/07/31 09:49:13 tqbf Exp $
# $NetBSD: Makefile,v 1.6 1995/03/07 23:18:39 mycroft Exp $
#
# Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994
@@ -41,7 +41,7 @@ SRCS= tcpdump.c addrtoname.c \
print-wb.c print-decnet.c print-isoclns.c print-ipx.c \
print-atm.c print-dvmrp.c print-krb.c print-pim.c print-netbios.c \
util.c bpf_dump.c parsenfsfh.c version.c machdep.c print-igrp.c \
- print-gre.c
+ print-gre.c print-radius.c
AWKS = atime.awk packetdat.awk send-ack.awk stime.awk
diff --git a/usr.sbin/tcpdump/print-radius.c b/usr.sbin/tcpdump/print-radius.c
new file mode 100644
index 00000000000..c665ac92631
--- /dev/null
+++ b/usr.sbin/tcpdump/print-radius.c
@@ -0,0 +1,258 @@
+#include <stdio.h>
+
+#include <sys/types.h>
+#include <netinet/in.h>
+
+/* RADIUS support for tcpdump, Thomas Ptacek <tqbf@enteract.com> */
+
+#include "interface.h"
+#include "radius.h"
+
+static void r_print_att(int code, int len, const u_char *val);
+static void r_print_int(int code, int len, const u_char *val);
+static void r_print_address(int code, int len, const u_char *val);
+static void r_print_string(int code, int len, const u_char *val);
+static void r_print_hex(int code, int len, const u_char *val);
+
+/* --------------------------------------------------------------- */
+
+struct radius_ctable {
+ int code;
+ char *name;
+};
+
+/* map opcodes to strings */
+
+#define DEFINED_OPCODES 11
+
+static struct radius_ctable radius_codes[] = {
+ { -1, NULL },
+ { RADIUS_CODE_ACCESS_REQUEST, "Axs?" },
+ { RADIUS_CODE_ACCESS_ACCEPT, "Axs+" },
+ { RADIUS_CODE_ACCESS_REJECT, "Axs-" },
+ { RADIUS_CODE_ACCOUNT_REQUEST, "Act?" },
+ { RADIUS_CODE_ACCOUNT_RESPONSE, "Act+" },
+ { RADIUS_CODE_ACCOUNT_STATUS, "ActSt" },
+ { RADIUS_CODE_PASSCHG_REQUEST, "Pchg?" },
+ { RADIUS_CODE_PASSCHG_ACCEPT, "Pchg+" },
+ { RADIUS_CODE_PASSCHG_REJECT, "Pchg-" },
+ { RADIUS_CODE_ACCOUNT_MESSAGE, "ActMg" },
+ { RADIUS_CODE_ACCESS_CHALLENGE, "Axs!" },
+ { -1, NULL }
+};
+
+/* --------------------------------------------------------------- */
+
+#define MAX_VALUES 20
+
+struct radius_atable {
+ int code;
+ int encoding;
+ char *name;
+ char *values[MAX_VALUES];
+};
+
+/* map attributes to strings */
+
+/* the right way to do this is probably to read these values out
+ * of the actual RADIUS dictionary; this would require the machine
+ * running tcpdump to have that file installed, and it's not my
+ * program, so I'm not going to introduce new dependancies. Oh well.
+ */
+
+static struct radius_atable radius_atts[] = {
+
+{ RADIUS_ATT_USER_NAME, RD_STRING, "Name", NULL },
+{ RADIUS_ATT_PASSWORD, RD_HEX, "Pass", NULL },
+{ RADIUS_ATT_CHAP_PASS, RD_HEX, "CPass", NULL },
+{ RADIUS_ATT_NAS_IP, RD_ADDRESS, "NAS-IP", NULL },
+{ RADIUS_ATT_NAS_PORT, RD_INT, "NAS-Pt", NULL },
+
+{ RADIUS_ATT_USER_SERVICE, RD_INT, "USvc",
+{ "", "Login", "Framed", "DB-Lgn", "DB-Frm", "Out", "Shell", NULL } },
+
+{ RADIUS_ATT_PROTOCOL, RD_INT, "FProt",
+{ "", "PPP", "SLIP", NULL } },
+
+{ RADIUS_ATT_FRAMED_ADDRESS, RD_ADDRESS, "F-IP", NULL },
+{ RADIUS_ATT_NETMASK, RD_ADDRESS, "F-Msk", NULL },
+{ RADIUS_ATT_ROUTING, RD_INT, "F-Rtg", NULL },
+{ RADIUS_ATT_FILTER, RD_STRING, "FltID", NULL },
+{ RADIUS_ATT_MTU, RD_INT, "F-MTU", NULL },
+{ RADIUS_ATT_COMPRESSION, RD_INT, "F-Comp", NULL },
+{ RADIUS_ATT_LOGIN_HOST, RD_ADDRESS, "L-Hst", NULL },
+
+{ RADIUS_ATT_LOGIN_SERVICE, RD_INT, "L-Svc",
+{ "", "Telnt", "Rlog", "Clear", "PortM", NULL } },
+
+{ RADIUS_ATT_LOGIN_TCP_PORT, RD_INT, "L-Pt", NULL },
+{ RADIUS_ATT_OLD_PASSWORD, RD_HEX, "OPass", NULL },
+{ RADIUS_ATT_PORT_MESSAGE, RD_STRING, "PMsg", NULL },
+{ RADIUS_ATT_DIALBACK_NO, RD_STRING, "DB#", NULL },
+{ RADIUS_ATT_DIALBACK_NAME, RD_STRING, "DBNm", NULL },
+{ RADIUS_ATT_EXPIRATION, RD_DATE, "PExp", NULL },
+{ RADIUS_ATT_FRAMED_ROUTE, RD_STRING, "F-Rt", NULL },
+{ RADIUS_ATT_FRAMED_IPX, RD_ADDRESS, "F-IPX", NULL },
+{ RADIUS_ATT_CHALLENGE_STATE, RD_STRING, "CState", NULL },
+{ RADIUS_ATT_CLASS, RD_STRING, "Class", NULL },
+{ RADIUS_ATT_VENDOR_SPECIFIC, RD_HEX, "Vendor", NULL },
+{ RADIUS_ATT_SESSION_TIMEOUT, RD_INT, "S-TO", NULL },
+{ RADIUS_ATT_IDLE_TIMEOUT, RD_INT, "I-TO", NULL },
+{ RADIUS_ATT_TERMINATE_ACTION, RD_INT, "TermAct", NULL },
+{ RADIUS_ATT_CALLED_ID, RD_STRING, "Callee", NULL },
+{ RADIUS_ATT_CALLER_ID, RD_STRING, "Caller", NULL },
+
+{ RADIUS_ATT_STATUS_TYPE, RD_INT, "Stat",
+{ "", "Start", "Stop", NULL } },
+
+{ -1, -1, NULL, NULL }
+
+};
+
+typedef void (*aselector)(int code, int len, const u_char *data);
+aselector atselector[] = {
+ r_print_hex,
+ r_print_int,
+ r_print_int,
+ r_print_address,
+ r_print_string,
+ r_print_hex
+};
+
+static void r_print_att(int code, int len, const u_char *data) {
+ struct radius_atable *atp;
+ int i;
+
+ for(atp = radius_atts; atp->code != -1; atp++)
+ if(atp->code == code)
+ break;
+
+ if(atp->code == -1) {
+ if(vflag > 1) {
+ fprintf(stdout, " %d =", code);
+ atselector[RD_HEX](code, len, data);
+ } else
+ fprintf(stdout, " %d", code);
+
+ return;
+ }
+
+ fprintf(stdout, " %s =", atp->name);
+
+ if(atp->encoding == RD_INT && *atp->values) {
+ int k = ntohl((*(int *)data));
+
+ for(i = 0; atp->values[i] != NULL; i++)
+ /* SHOOT ME */ ;
+
+ if(k < i) {
+ fprintf(stdout, " %s",
+ atp->values[k]);
+ return;
+ }
+ }
+
+ atselector[atp->encoding](code, len, data);
+}
+
+static void r_print_int(int code, int len, const u_char *data) {
+ if(len < 4) {
+ fputs(" ?", stdout);
+ return;
+ }
+
+ fprintf(stdout, " %d", ntohl((*(int *)data)));
+}
+
+static void r_print_address(int code, int len, const u_char *data) {
+ if(len < 4) {
+ fputs(" ?", stdout);
+ return;
+ }
+
+ fprintf(stdout, " %s", inet_ntoa((*(struct in_addr *)data)));
+}
+
+static void r_print_string(int code, int len, const u_char *data) {
+ char string[128];
+ const char *cp;
+ char *sp;
+
+ if(!len) {
+ fputs(" ?", stdout);
+ return;
+ }
+
+ if(len > 127)
+ len = 127;
+
+ memset(string, 0, 128);
+ memcpy(string, data, len);
+
+ fprintf(stdout, " %s", string);
+}
+
+static void r_print_hex(int code, int len, const u_char *data) {
+ int i;
+
+ /* excuse me */
+
+ fputs(" [", stdout);
+
+ for(i = 0; i < len; i++)
+ fprintf(stdout, "%x", data[i]);
+
+ fputc(']', stdout);
+}
+
+void radius_print(register const u_char *data, u_int len) {
+ const struct radius_header *rhp;
+ const u_char *pp;
+ const char *cp;
+ int i, l, ac, al;
+
+ if(len < sizeof(struct radius_header)) {
+ fputs(" [|radius]", stdout);
+ return;
+ }
+
+ rhp = (struct radius_header *) data;
+
+ if(rhp->code > DEFINED_OPCODES ||
+ rhp->code < 1)
+ fprintf(stdout, " Code:%d id:%x [%d]",
+ rhp->code, rhp->id, ntohs(rhp->len));
+ else
+ fprintf(stdout, " %s id:%x [%d]",
+ radius_codes[rhp->code].name,
+ rhp->id, ntohs(rhp->len));
+
+ if(ntohs(rhp->len) > len) {
+ fputs(" [|radius]", stdout);
+ return;
+ }
+
+ l = len - RADFIXEDSZ;
+ if(!l)
+ return;
+ else
+ pp = data + RADFIXEDSZ;
+
+ while(l) {
+ if(!i) fputc(',', stdout); i = 0;
+
+ ac = *pp++;
+ al = *pp++;
+
+ if(al > l || al < 2) {
+ fputs(" [|radius]", stdout);
+ return;
+ }
+
+ al -= 2;
+
+ r_print_att(ac, al, pp);
+
+ pp += al; l -= al + 2;
+ }
+}
diff --git a/usr.sbin/tcpdump/print-udp.c b/usr.sbin/tcpdump/print-udp.c
index 753fa5e9558..c315fa34e81 100644
--- a/usr.sbin/tcpdump/print-udp.c
+++ b/usr.sbin/tcpdump/print-udp.c
@@ -21,7 +21,7 @@
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /cvs/OpenBSD/src/usr.sbin/tcpdump/print-udp.c,v 1.6 1997/07/23 02:59:02 denny Exp $ (LBL)";
+ "@(#) $Header: /cvs/OpenBSD/src/usr.sbin/tcpdump/print-udp.c,v 1.7 1997/07/31 09:49:13 tqbf Exp $ (LBL)";
#endif
#include <sys/param.h>
@@ -286,6 +286,11 @@ rtcp_print(const u_char *hdr, const u_char *ep)
#define SNMPTRAP_PORT 162 /*XXX*/
#define RIP_PORT 520 /*XXX*/
#define KERBEROS_SEC_PORT 750 /*XXX*/
+#define OLD_RADIUS_AUTH_PORT 1645
+#define OLD_RADIUS_ACCT_PORT 1646
+#define RADIUS_AUTH_PORT 1812
+#define RADIUS_ACCT_PORT 1813
+
void
udp_print(register const u_char *bp, u_int length, register const u_char *bp2)
@@ -425,6 +430,11 @@ udp_print(register const u_char *bp, u_int length, register const u_char *bp2)
ntp_print((const u_char *)(up + 1), length);
else if (ISPORT(KERBEROS_PORT) || ISPORT(KERBEROS_SEC_PORT))
krb_print((const void *)(up + 1), length);
+ else if (ISPORT(OLD_RADIUS_AUTH_PORT) ||
+ ISPORT(OLD_RADIUS_ACCT_PORT) ||
+ ISPORT(RADIUS_AUTH_PORT) ||
+ ISPORT(RADIUS_ACCT_PORT))
+ radius_print((const u_char *)(up + 1), length);
else if (dport == 3456)
vat_print((const void *)(up + 1), length, up);
/*
diff --git a/usr.sbin/tcpdump/radius.h b/usr.sbin/tcpdump/radius.h
new file mode 100644
index 00000000000..d8f9d3c96f2
--- /dev/null
+++ b/usr.sbin/tcpdump/radius.h
@@ -0,0 +1,84 @@
+/* RADIUS support for tcpdump, Thomas Ptacek <tqbf@enteract.com> */
+
+/* ------------------------------------------------------------ */
+
+/* RADIUS attribute encoding types */
+
+#define RD_INT 1
+#define RD_DATE 2
+#define RD_ADDRESS 3
+#define RD_STRING 4
+#define RD_HEX 5
+
+/* ------------------------------------------------------------ */
+
+/* RADIUS packet opcodes */
+
+#define RADIUS_CODE_ACCESS_REQUEST 1
+#define RADIUS_CODE_ACCESS_ACCEPT 2
+#define RADIUS_CODE_ACCESS_REJECT 3
+#define RADIUS_CODE_ACCOUNT_REQUEST 4
+#define RADIUS_CODE_ACCOUNT_RESPONSE 5
+#define RADIUS_CODE_ACCOUNT_STATUS 6
+#define RADIUS_CODE_PASSCHG_REQUEST 7
+#define RADIUS_CODE_PASSCHG_ACCEPT 8
+#define RADIUS_CODE_PASSCHG_REJECT 9
+#define RADIUS_CODE_ACCOUNT_MESSAGE 10
+#define RADIUS_CODE_ACCESS_CHALLENGE 11
+
+/* ------------------------------------------------------------ */
+
+/* slew o' attributes */
+
+#define RADIUS_ATT_USER_NAME 1
+#define RADIUS_ATT_PASSWORD 2
+#define RADIUS_ATT_CHAP_PASS 3
+#define RADIUS_ATT_NAS_IP 4
+#define RADIUS_ATT_NAS_PORT 5
+#define RADIUS_ATT_USER_SERVICE 6
+#define RADIUS_ATT_PROTOCOL 7
+#define RADIUS_ATT_FRAMED_ADDRESS 8
+#define RADIUS_ATT_NETMASK 9
+#define RADIUS_ATT_ROUTING 10
+#define RADIUS_ATT_FILTER 11
+#define RADIUS_ATT_MTU 12
+#define RADIUS_ATT_COMPRESSION 13
+#define RADIUS_ATT_LOGIN_HOST 14
+#define RADIUS_ATT_LOGIN_SERVICE 15
+#define RADIUS_ATT_LOGIN_TCP_PORT 16
+#define RADIUS_ATT_OLD_PASSWORD 17
+#define RADIUS_ATT_PORT_MESSAGE 18
+#define RADIUS_ATT_DIALBACK_NO 19
+#define RADIUS_ATT_DIALBACK_NAME 20
+#define RADIUS_ATT_EXPIRATION 21
+#define RADIUS_ATT_FRAMED_ROUTE 22
+#define RADIUS_ATT_FRAMED_IPX 23
+#define RADIUS_ATT_CHALLENGE_STATE 24
+#define RADIUS_ATT_CLASS 25
+#define RADIUS_ATT_VENDOR_SPECIFIC 26
+#define RADIUS_ATT_SESSION_TIMEOUT 27
+#define RADIUS_ATT_IDLE_TIMEOUT 28
+#define RADIUS_ATT_TERMINATE_ACTION 29
+#define RADIUS_ATT_CALLED_ID 30
+#define RADIUS_ATT_CALLER_ID 31
+
+#define RADIUS_ATT_STATUS_TYPE 40
+
+/* the accounting attributes change way too much
+ * for me to want to hardcode them in.
+ */
+
+/* ------------------------------------------------------------ */
+
+/* RADIUS packet header */
+
+#define RADFIXEDSZ 20
+
+struct radius_header {
+ u_char code;
+ u_char id;
+ u_short len;
+ u_char auth[16];
+};
+
+/* ------------------------------------------------------------ */