diff options
author | Guy Harris <guy@alum.mit.edu> | 1999-02-15 06:36:57 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 1999-02-15 06:36:57 +0000 |
commit | 38a04d266041d513504124245ab1c344ca89bfbd (patch) | |
tree | de9add6ec01e36d58ad3d8b4a4dbcb00ab570d55 /packet-udp.c | |
parent | 58778fd8ad5d56f3a57fb60e52f6b1c0ae47951c (diff) | |
download | wireshark-38a04d266041d513504124245ab1c344ca89bfbd.tar.gz wireshark-38a04d266041d513504124245ab1c344ca89bfbd.tar.bz2 wireshark-38a04d266041d513504124245ab1c344ca89bfbd.zip |
Added Richard Sharpe's TFTP support.
svn path=/trunk/; revision=190
Diffstat (limited to 'packet-udp.c')
-rw-r--r-- | packet-udp.c | 135 |
1 files changed, 127 insertions, 8 deletions
diff --git a/packet-udp.c b/packet-udp.c index 19c4a5018b..a5d6f86e78 100644 --- a/packet-udp.c +++ b/packet-udp.c @@ -1,12 +1,14 @@ /* packet-udp.c * Routines for UDP packet disassembly * - * $Id: packet-udp.c,v 1.11 1998/12/29 04:05:36 gerald Exp $ + * $Id: packet-udp.c,v 1.12 1999/02/15 06:36:57 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> * Copyright 1998 Gerald Combs * + * Richard Sharpe, 13-Feb-1999, added dispatch table support and + * support for tftp. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -43,10 +45,99 @@ #include "packet.h" #include "resolv.h" +struct hash_struct { + guint16 proto; + void (*dissect)(const u_char *, int, frame_data *, GtkTree *); + struct hash_struct *next; +}; + +struct hash_struct *hash_table[256]; + +/* + * These routines are for UDP, will be generalized soon: RJS + * + * XXX - note that they should probably check the IP address as well as + * the port number, so that we don't mistakenly identify packets as, say, + * TFTP, merely because they have a source or destination port number + * equal to the port being used by a TFTP daemon on some machine other + * than the one they're going to or from. + */ + +struct hash_struct *udp_find_hash_ent(guint16 proto) { + + int idx = proto % 256; + struct hash_struct *hash_ent = hash_table[idx]; + + while (hash_ent != NULL) { + + if (hash_ent -> proto == proto) + return hash_ent; + + hash_ent = hash_ent -> next; + + } + + return NULL; + +} + +void udp_hash_add(guint16 proto, + void (*dissect)(const u_char *, int, frame_data *, GtkTree *)) { + + int idx = proto % 256; /* Simply take the remainder, hope for no collisions */ + struct hash_struct *hash_ent = (struct hash_struct *)malloc(sizeof(struct hash_struct)); + struct hash_struct *hash_ent2; + + hash_ent -> proto = proto; + hash_ent -> dissect = dissect; + hash_ent -> next = NULL; + + if (hash_ent == NULL) { + + fprintf(stderr, "Could not allocate space for hash structure in dissect_udp\n"); + exit(1); + } + + if (hash_table[idx]) { /* Something, add on end */ + + hash_ent2 = hash_table[idx]; + + while (hash_ent2 -> next != NULL) + hash_ent2 = hash_ent2 -> next; + + hash_ent2 -> next = hash_ent; /* Bad in pathalogical cases */ + + } + else { + + hash_table[idx] = hash_ent; + + } + +} + +void init_dissect_udp(void) { + + int i; + + for (i = 0; i < 256; i++) { + + hash_table[i] = NULL; + + } + + /* Now add the protocols we know about */ + + udp_hash_add(UDP_PORT_BOOTPS, dissect_bootp); + udp_hash_add(UDP_PORT_TFTP, dissect_tftp); + +} + void dissect_udp(const u_char *pd, int offset, frame_data *fd, GtkTree *tree) { e_udphdr uh; guint16 uh_sport, uh_dport, uh_ulen, uh_sum; + struct hash_struct *dissect_routine = NULL; GtkWidget *udp_tree, *ti; /* To do: Check for {cap len,pkt len} < struct len */ @@ -99,12 +190,12 @@ dissect_udp(const u_char *pd, int offset, frame_data *fd, GtkTree *tree) { /* we should check the source port too (RIP: UDP src and dst port 520) */ dissect_rip(pd, offset, fd, tree); break; - case UDP_PORT_NBNS: - dissect_nbns(pd, offset, fd, tree); - break; - case UDP_PORT_NBDGM: - dissect_nbdgm(pd, offset, fd, tree); - break; + case UDP_PORT_NBNS: + dissect_nbns(pd, offset, fd, tree); + break; + case UDP_PORT_NBDGM: + dissect_nbdgm(pd, offset, fd, tree); + break; case UDP_PORT_IPX: /* RFC 1234 */ dissect_ipx(pd, offset, fd, tree); break; @@ -112,7 +203,35 @@ dissect_udp(const u_char *pd, int offset, frame_data *fd, GtkTree *tree) { /* FIXME: AFAIK, src and dst port must be the same */ dissect_vines_frp(pd, offset, fd, tree); break; + case UDP_PORT_TFTP: + /* This is the first point of call, but it adds a dynamic call */ + udp_hash_add(MAX(uh_sport, uh_dport), dissect_tftp); /* Add to table */ + dissect_tftp(pd, offset, fd, tree); + break; default: - dissect_data(pd, offset, fd, tree); + + /* OK, find a routine in the table, else use the default */ + + if ((dissect_routine = udp_find_hash_ent(uh_sport))) { + + struct hash_struct *dr2 = udp_find_hash_ent(uh_dport); + + if (dr2 == NULL) { /* Not in the table, add */ + + udp_hash_add(uh_dport, dissect_tftp); + + } + + dissect_routine -> dissect(pd, offset, fd, tree); + } + else if ((dissect_routine = udp_find_hash_ent(uh_dport))) { + + dissect_routine -> dissect(pd, offset, fd, tree); + + } + else { + + dissect_data(pd, offset, fd, tree); + } } } |