diff options
-rw-r--r-- | usr.sbin/tcpdump/Makefile | 4 | ||||
-rw-r--r-- | usr.sbin/tcpdump/print-radius.c | 258 | ||||
-rw-r--r-- | usr.sbin/tcpdump/print-udp.c | 12 | ||||
-rw-r--r-- | usr.sbin/tcpdump/radius.h | 84 |
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]; +}; + +/* ------------------------------------------------------------ */ |