------------11ljg0ndczntgxns4ymzg0lmj4dnljbxzzymfaymn0zwwubmv0
Content-Type: text/enriched
[ Note: Mailed to both the tcpdump maintainers and the Livingston RADIUS
mailing list. ]
Hello folx,
I have some patches which you will find included below which allow
tcpdump 3.2.1 to decode RADIUS packets. There is a new command line
option "-R <<directory>" to specify a directory in which the RADIUS
"dictionary" can be found. This makes the tcpdump binary more portable
to each vendors' NAS/RADIUS implementation.
The code contributed below references some source files from the Ascend
modified Livingston reference port of RADIUS for reading and retrieving
dictionary attributues but does not contain any Livingston code itself.
The Ascend port of RADIUS looks like it is based on Livingston 1.16, but
a quick look at a diff of the files I use leads me to believe that
Ascend's changes are non-consequential.
If one wants to include RADIUS decode in their binary one has to have
the RADIUS source code available. I did this so that I don't have to
try and figure out what I have to do to actually include Livingston code
as well as making it easy to use other implementations of RADIUS that
might do things contained in the non-included Livingston files
differently.
I also hard coded some variables into configure.in, which would probably
be better suited to a "--with-RADIUS" type option to configure, however
I know little to nothing about getting configure/autoconf et. al. to do
this. Could probably, with time figure it out, but...
b.
BTW for portmaster-radius readers: I am not on the portmaster-radius
list, so you'll have to mail me directly to contact me.
------------11ljg0ndczntgxns4ymzg0lmj4dnljbxzzymfaymn0zwwubmv0
Content-Type: text/plain
Content-Description: RADIUS decode diffs for tcpdump-3.2.1
Content-Disposition: attachment;
filename=diffs
diff -N -c -r dist/Makefile.in mine/Makefile.in
*** dist/Makefile.in Tue Jul 16 23:52:20 1996
--- mine/Makefile.in Mon Oct 7 17:18:26 1996
***************
*** 31,44 ****
# Pathname of directory to install the man page
MANDEST = @mandir@
#
# You shouldn't need to edit anything below here.
#
CC = @CC@
CCOPT = @V_CCOPT@
! INCLS = -I. @V_INCLS@
! DEFS = @DEFS@ -DPPP -DHAVE_FDDI
# Standard CFLAGS
CFLAGS = $(CCOPT) $(DEFS) $(INCLS)
--- 31,49 ----
# Pathname of directory to install the man page
MANDEST = @mandir@
+ # source directory of my radius server
+ RADIUS_SRC=../../radius-960528/radius-1.16-ascend/ascendd
+
#
# You shouldn't need to edit anything below here.
#
CC = @CC@
CCOPT = @V_CCOPT@
! INCLS = -I. @V_INCLS@ -I$(RADIUS_SRC)
! # BINARY_FILTERS should probably be enabled if your RADIUS dictionary has any
! # attribute types of "abinary"
! DEFS = @DEFS@ -DPPP -DHAVE_FDDI -DBINARY_FILTERS
# Standard CFLAGS
CFLAGS = $(CCOPT) $(DEFS) $(INCLS)
***************
*** 64,69 ****
--- 69,75 ----
print-fddi.c print-llc.c print-sunrpc.c print-wb.c \
print-decnet.c print-isoclns.c print-ipx.c \
print-atm.c print-dvmrp.c print-pim.c print-krb.c \
+ print-radius.c dict.c attrprint.c radius_util.c \
util.c machdep.c bpf_dump.c parsenfsfh.c
LOCALSRC =
GENSRC = version.c
***************
*** 72,78 ****
# We would like to say "OBJ = $(SRC:.c=.o)" but Ultrix's make cannot
# hack the extra indirection
! OBJ = $(CSRC:.c=.o) $(GENSRC:.c=.o) $(LOCALSRC:.c=.o) @LIBOBJS@
HDR = addrtoname.h appletalk.h bootp.h decnet.h \
ethertype.h extract.h fddi.h interface.h igrp.h ipx.h \
llc.h machdep.h mib.h nfsfh.h nfsv2.h ntp.h ospf.h
--- 78,84 ----
# We would like to say "OBJ = $(SRC:.c=.o)" but Ultrix's make cannot
# hack the extra indirection
! OBJ = radius_util.o $(CSRC:.c=.o) $(GENSRC:.c=.o) $(LOCALSRC:.c=.o) @LIBOBJS@
HDR = addrtoname.h appletalk.h bootp.h decnet.h \
ethertype.h extract.h fddi.h interface.h igrp.h ipx.h \
llc.h machdep.h mib.h nfsfh.h nfsv2.h ntp.h ospf.h
***************
*** 94,99 ****
--- 100,117 ----
tcpdump: $(OBJ) @V_PCAPDEP@
@rm -f $@
$(CC) $(CFLAGS) -o $@ $(OBJ) $(LIBS)
+
+ attrprint.o: $(RADIUS_SRC)/attrprint.c
+ @rm -f $@
+ $(CC) $(CFLAGS) -c $(RADIUS_SRC)/$*.c
+
+ radius_util.o: $(RADIUS_SRC)/util.c
+ @rm -f $@
+ $(CC) $(CFLAGS) -o $*.o -c $(RADIUS_SRC)/util.c
+
+ dict.o: $(RADIUS_SRC)/dict.c
+ @rm -f $@
+ $(CC) $(CFLAGS) -c $(RADIUS_SRC)/$*.c
version.o: version.c
version.c: VERSION
diff -N -c -r dist/print-radius.c mine/print-radius.c
*** dist/print-radius.c Wed Dec 31 16:00:00 1969
--- mine/print-radius.c Mon Oct 7 17:44:37 1996
***************
*** 0 ****
--- 1,163 ----
+ /* decode RADIUS packets.
+ ** By Brian J. Murrell - brian@ilinx.com
+ */
+
+ #include <sys/param.h>
+ #include <sys/time.h>
+ #include <sys/socket.h>
+
+ #include <netinet/in.h>
+ #include <netinet/in_systm.h>
+ #include <netinet/ip.h>
+ #include <netinet/ip_var.h>
+ #include <netinet/udp.h>
+ #include <netinet/udp_var.h>
+
+ #include <ctype.h>
+ #include <errno.h>
+ #include <stdio.h>
+
+ #include "interface.h"
+ #include "addrtoname.h"
+ #include "radius.h"
+ #include "protos.h"
+
+ void radacct_print(const u_char *, u_int);
+ void print_attr(const u_char *, u_int);
+
+ static char tstr[] = " [|RADIUS]";
+
+ extern char *progname; /* for dict.c */
+ extern char *radius_dir;
+
+ struct radacct {
+ u_char code;
+ u_char ident;
+ u_short length;
+ u_char authenticator[16];
+ u_char attr;
+
+ };
+
+ struct attr {
+ u_char type;
+ u_char length;
+ u_char value;
+ };
+
+ void
+ radacct_print(const u_char *dat, u_int length)
+ {
+ register const struct radacct *ra;
+
+ ra = (struct radacct *)dat;
+
+ if (dat >= snapend) {
+ fputs(tstr, stdout);
+ return;
+ }
+
+ switch ((int)ra->code){
+ int len;
+ case 1:
+ printf(" RADIUS accs-req %d (%d)", (int)ra->ident,
+ ra->length);
+ len=ra->length-20;
+ print_attr(&(ra->attr), len);
+ break;
+ case 2:
+ printf(" RADIUS accs-resp %d (%d)", (int)ra->ident,
+ ra->length);
+ len=ra->length-20;
+ print_attr(&(ra->attr), len);
+ break;
+ case 3:
+ printf(" RADIUS accs-rej %d (%d)", (int)ra->ident,
+ ra->length);
+ len=ra->length-20;
+ print_attr(&(ra->attr), len);
+ break;
+ case 4:
+ printf(" RADIUS acct-req %d (%d)", (int)ra->ident,
+ ra->length);
+ len=ra->length-20;
+ print_attr(&(ra->attr), len);
+ break;
+ case 5:
+ printf(" RADIUS acct-resp %d (%d)", (int)ra->ident,
+ ra->length);
+ len=ra->length-20;
+ print_attr(&(ra->attr), len);
+ break;
+ default:
+ printf(" unknown RADIUS packet code \"%d\"", (int)ra->code);
+ break;
+ }
+
+ return;
+ }
+
+ /* print radius attributes */
+ void
+ print_attr(const u_char *dat, u_int length)
+ {
+
+ register const struct attr *ra;
+ DICT_ATTR *dict_attr;
+ VALUE_PAIR attr_pair;
+ UINT4 lvalue;
+
+ /* check to see if a RADIUS directory was specified */
+ if (!radius_dir){
+ printf(" no RADIUS directory use -R");
+ return(0);
+ }
+
+ ra = (struct attr *)dat;
+
+ while (length > 0){
+ dict_attr=dict_attrget((int)ra->type);
+ /*
+ printf(" [%d ", ra->type); fflush(stdout);
+ printf(" (%d) ", ra->length); fflush(stdout);
+ printf(" (%d) ", length); fflush(stdout);
+ printf(" = %lu", dict_attr->name); fflush(stdout);
+ printf(" (%s)]\n", dict_attr->name); fflush(stdout);
+ */
+ strcpy(attr_pair.name, dict_attr->name);
+ attr_pair.attribute = dict_attr->value;
+ attr_pair.type = dict_attr->type;
+ attr_pair.size = ra->length;
+ attr_pair.next = (VALUE_PAIR *)NULL;
+
+ switch(dict_attr->type) {
+
+ case PW_TYPE_STRING:
+ memcpy(attr_pair.strvalue, &(ra->value), ra->length);
+ attr_pair.strvalue[ra->length] = '\0';
+ break;
+
+ case PW_TYPE_INTEGER:
+ case PW_TYPE_IPADDR:
+ memcpy(&lvalue, &(ra->value), sizeof(UINT4));
+ attr_pair.lvalue = ntohl(lvalue);
+ break;
+ #if defined ( BINARY_FILTERS )
+ case PW_TYPE_FILTER_BINARY:
+ memcpy(attr_pair.strvalue, &(ra->value), ra->length);
+ attr_pair.strvalue[ra->length] = '\0';
+ break;
+ #endif
+ default:
+ break;
+ }
+
+ fprint_attr_val(stdout, &attr_pair);
+ putchar(' ');
+ fflush(stdout);
+ /* and decrease total attributes length */
+ length-=ra->length;
+ /* point ra to the next attribute */
+ ra=(u_char *)ra+ra->length; /* cast to u_char to add bytes */
+ }
+ }
diff -N -c -r dist/print-udp.c mine/print-udp.c
*** dist/print-udp.c Tue Jul 23 14:17:28 1996
--- mine/print-udp.c Mon Oct 7 14:53:53 1996
***************
*** 388,393 ****
--- 388,395 ----
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(1646) || ISPORT(1645))
+ radacct_print((const void *)(up + 1), length);
else if (dport == 3456)
vat_print((const void *)(up + 1), length, up);
/*
diff -N -c -r dist/tcpdump.c mine/tcpdump.c
*** dist/tcpdump.c Wed Jul 17 00:12:57 1996
--- mine/tcpdump.c Mon Oct 7 15:56:19 1996
***************
*** 67,72 ****
--- 67,75 ----
int dflag; /* print filter code */
char *program_name;
+ char *progname; /* for dict.c */
+
+ char *radius_dir = NULL; /* init to NULL for later check */
int32_t thiszone; /* seconds offset from gmt to local time */
***************
*** 141,151 ****
else
program_name = argv[0];
if (abort_on_misalignment(ebuf) < 0)
error(ebuf);
opterr = 0;
! while ((op = getopt(argc, argv, "c:defF:i:lnNOpqr:s:StT:vw:xY")) != EOF)
switch (op) {
case 'c':
cnt = atoi(optarg);
--- 144,155 ----
else
program_name = argv[0];
+ progname=program_name;
if (abort_on_misalignment(ebuf) < 0)
error(ebuf);
opterr = 0;
! while ((op = getopt(argc, argv, "c:defF:i:lnNOpqr:R:s:StT:vw:xY")) != EOF)
switch (op) {
case 'c':
cnt = atoi(optarg);
***************
*** 203,208 ****
--- 207,218 ----
case 'r':
RFileName = optarg;
+ break;
+
+ case 'R':
+ radius_dir = optarg;
+ /* load the RADIUS dictionary */
+ dict_init();
break;
case 's':
------------11ljg0ndczntgxns4ymzg0lmj4dnljbxzzymfaymn0zwwubmv0
Content-Description: Signature
Content-Type: text/enriched
--
------------11ljg0ndczntgxns4ymzg0lmj4dnljbxzzymfaymn0zwwubmv0--