From 0bd117e39df67ed8340fe7afb11e1cde78face6b Mon Sep 17 00:00:00 2001 From: pdw <> Date: Thu, 31 Oct 2002 16:53:32 +0000 Subject: [PATCH] Added token ring network support. --- CHANGES | 6 +++ Makefile | 5 +- ethertype.h | 122 ++++++++++++++++++++++++++++++++++++++++++++++++ extract.h | 57 +++++++++++++++++++++++ iftop.c | 61 ++++++++++++++++++++++++ llc.h | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++++ resolver.c | 3 -- token.h | 52 +++++++++++++++++++++ 8 files changed, 433 insertions(+), 5 deletions(-) create mode 100644 ethertype.h create mode 100644 extract.h create mode 100644 llc.h create mode 100644 token.h diff --git a/CHANGES b/CHANGES index c1ed49b..bffd0ae 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,12 @@ Change log for iftop $Id$ +0.11 + +Added support for token ring networks +Token ring network direction determination + Martin Garton + 0.10 29/10/02 User selectable sort criteria diff --git a/Makefile b/Makefile index e74cebf..a6ada50 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ # $Id$ # -VERSION = 0.10 +VERSION = 0.11pre1 # C compiler to use. #CC = gcc @@ -73,7 +73,8 @@ LDLIBS += -lpcap -lcurses -lm SRCS = iftop.c addr_hash.c hash.c ns_hash.c resolver.c ui.c util.c sorted_list.c\ options.c serv_hash.c threadprof.c edline.c screenfilter.c HDRS = addr_hash.h hash.h iftop.h ns_hash.h resolver.h sorted_list.h ui.h options.h sll.h\ - serv_hash.h threadprof.h ether.h ip.h tcp.h screenfilter.h + serv_hash.h threadprof.h ether.h ip.h tcp.h screenfilter.h token.h llc.h \ + extract.h ethertype.h TXTS = README CHANGES INSTALL TODO iftop.8 COPYING SPECFILE = iftop.spec iftop.spec.in diff --git a/ethertype.h b/ethertype.h new file mode 100644 index 0000000..1f6aab6 --- /dev/null +++ b/ethertype.h @@ -0,0 +1,122 @@ +/* + * Copyright (c) 1993, 1994, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#) $Header$ (LBL) + */ + +/* + * Ethernet types. + * + * We wrap the declarations with #ifdef, so that if a file includes + * , which may declare some of these, we don't + * get a bunch of complaints from the C compiler about redefinitions + * of these values. + * + * We declare all of them here so that no file has to include + * if all it needs are ETHERTYPE_ values. + */ + +#ifndef ETHERTYPE_PUP +#define ETHERTYPE_PUP 0x0200 /* PUP protocol */ +#endif +#ifndef ETHERTYPE_IP +#define ETHERTYPE_IP 0x0800 /* IP protocol */ +#endif +#ifndef ETHERTYPE_ARP +#define ETHERTYPE_ARP 0x0806 /* Addr. resolution protocol */ +#endif +#ifndef ETHERTYPE_REVARP +#define ETHERTYPE_REVARP 0x8035 /* reverse Addr. resolution protocol */ +#endif +#ifndef ETHERTYPE_NS +#define ETHERTYPE_NS 0x0600 +#endif +#ifndef ETHERTYPE_SPRITE +#define ETHERTYPE_SPRITE 0x0500 +#endif +#ifndef ETHERTYPE_TRAIL +#define ETHERTYPE_TRAIL 0x1000 +#endif +#ifndef ETHERTYPE_MOPDL +#define ETHERTYPE_MOPDL 0x6001 +#endif +#ifndef ETHERTYPE_MOPRC +#define ETHERTYPE_MOPRC 0x6002 +#endif +#ifndef ETHERTYPE_DN +#define ETHERTYPE_DN 0x6003 +#endif +#ifndef ETHERTYPE_LAT +#define ETHERTYPE_LAT 0x6004 +#endif +#ifndef ETHERTYPE_SCA +#define ETHERTYPE_SCA 0x6007 +#endif +#ifndef ETHERTYPE_REVARP +#define ETHERTYPE_REVARP 0x8035 +#endif +#ifndef ETHERTYPE_LANBRIDGE +#define ETHERTYPE_LANBRIDGE 0x8038 +#endif +#ifndef ETHERTYPE_DECDNS +#define ETHERTYPE_DECDNS 0x803c +#endif +#ifndef ETHERTYPE_DECDTS +#define ETHERTYPE_DECDTS 0x803e +#endif +#ifndef ETHERTYPE_VEXP +#define ETHERTYPE_VEXP 0x805b +#endif +#ifndef ETHERTYPE_VPROD +#define ETHERTYPE_VPROD 0x805c +#endif +#ifndef ETHERTYPE_ATALK +#define ETHERTYPE_ATALK 0x809b +#endif +#ifndef ETHERTYPE_AARP +#define ETHERTYPE_AARP 0x80f3 +#endif +#ifndef ETHERTYPE_8021Q +#define ETHERTYPE_8021Q 0x8100 +#endif +#ifndef ETHERTYPE_IPX +#define ETHERTYPE_IPX 0x8137 +#endif +#ifndef ETHERTYPE_IPV6 +#define ETHERTYPE_IPV6 0x86dd +#endif +#ifndef ETHERTYPE_PPP +#define ETHERTYPE_PPP 0x880b +#endif +#ifndef ETHERTYPE_MPLS +#define ETHERTYPE_MPLS 0x8847 +#endif +#ifndef ETHERTYPE_MPLS_MULTI +#define ETHERTYPE_MPLS_MULTI 0x8848 +#endif +#ifndef ETHERTYPE_PPPOED +#define ETHERTYPE_PPPOED 0x8863 +#endif +#ifndef ETHERTYPE_PPPOES +#define ETHERTYPE_PPPOES 0x8864 +#endif +#ifndef ETHERTYPE_LOOPBACK +#define ETHERTYPE_LOOPBACK 0x9000 +#endif diff --git a/extract.h b/extract.h new file mode 100644 index 0000000..120e1a0 --- /dev/null +++ b/extract.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 1992, 1993, 1994, 1995, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#) $Header$ (LBL) + */ + +/* Network to host order macros */ + +#ifdef LBL_ALIGN +#define EXTRACT_16BITS(p) \ + ((u_int16_t)*((const u_int8_t *)(p) + 0) << 8 | \ + (u_int16_t)*((const u_int8_t *)(p) + 1)) +#define EXTRACT_32BITS(p) \ + ((u_int32_t)*((const u_int8_t *)(p) + 0) << 24 | \ + (u_int32_t)*((const u_int8_t *)(p) + 1) << 16 | \ + (u_int32_t)*((const u_int8_t *)(p) + 2) << 8 | \ + (u_int32_t)*((const u_int8_t *)(p) + 3)) +#else +#define EXTRACT_16BITS(p) \ + ((u_int16_t)ntohs(*(const u_int16_t *)(p))) +#define EXTRACT_32BITS(p) \ + ((u_int32_t)ntohl(*(const u_int32_t *)(p))) +#endif + +#define EXTRACT_24BITS(p) \ + ((u_int32_t)*((const u_int8_t *)(p) + 0) << 16 | \ + (u_int32_t)*((const u_int8_t *)(p) + 1) << 8 | \ + (u_int32_t)*((const u_int8_t *)(p) + 2)) + +/* Little endian protocol host order macros */ + +#define EXTRACT_LE_8BITS(p) (*(p)) +#define EXTRACT_LE_16BITS(p) \ + ((u_int16_t)*((const u_int8_t *)(p) + 1) << 8 | \ + (u_int16_t)*((const u_int8_t *)(p) + 0)) +#define EXTRACT_LE_32BITS(p) \ + ((u_int32_t)*((const u_int8_t *)(p) + 3) << 24 | \ + (u_int32_t)*((const u_int8_t *)(p) + 2) << 16 | \ + (u_int32_t)*((const u_int8_t *)(p) + 1) << 8 | \ + (u_int32_t)*((const u_int8_t *)(p) + 0)) diff --git a/iftop.c b/iftop.c index eff4a54..d7bca4d 100644 --- a/iftop.c +++ b/iftop.c @@ -30,6 +30,10 @@ #include "ether.h" #include "ip.h" #include "tcp.h" +#include "token.h" +#include "llc.h" +#include "extract.h" +#include "ethertype.h" unsigned char if_hw_addr[6]; /* ethernet address of interface. */ @@ -257,6 +261,59 @@ static void handle_raw_packet(unsigned char* args, const struct pcap_pkthdr* pkt handle_ip_packet((struct ip*)packet, -1); } +static void handle_llc_packet(const struct llc* llc, int dir) { + + struct ip* ip = (struct ip*)((void*)llc + sizeof(struct llc)); + + /* Taken from tcpdump/print-llc.c */ + if(llc->ssap == LLCSAP_SNAP && llc->dsap == LLCSAP_SNAP + && llc->llcui == LLC_UI) { + u_int32_t orgcode; + register u_short et; + orgcode = EXTRACT_24BITS(&llc->llc_orgcode[0]); + et = EXTRACT_16BITS(&llc->llc_ethertype[0]); + switch(orgcode) { + case OUI_ENCAP_ETHER: + case OUI_CISCO_90: + handle_ip_packet(ip, dir); + break; + case OUI_APPLETALK: + if(et == ETHERTYPE_ATALK) { + handle_ip_packet(ip, dir); + } + break; + default: + /* Not a lot we can do */ + } + } +} + +static void handle_tokenring_packet(unsigned char* args, const struct pcap_pkthdr* pkthdr, const unsigned char* packet) +{ + struct token_header *trp; + int dir = -1; + trp = (struct token_header *)packet; + + if(IS_SOURCE_ROUTED(trp)) { + packet += RIF_LENGTH(trp); + } + packet += TOKEN_HDRLEN; + + if(memcmp(trp->token_shost, if_hw_addr, 6) == 0 ) { + /* packet leaving this i/f */ + dir = 1; + } + else if(memcmp(trp->token_dhost, if_hw_addr, 6) == 0 || memcmp("\xFF\xFF\xFF\xFF\xFF\xFF", trp->token_dhost, 6) == 0) { + /* packet entering this i/f */ + dir = 0; + } + + /* Only know how to deal with LLC encapsulated packets */ + if(FRAME_TYPE(trp) == TOKEN_FC_LLC) { + handle_llc_packet((struct llc*)packet, dir); + } +} + #ifdef DLT_LINUX_SLL static void handle_cooked_packet(unsigned char *args, const struct pcap_pkthdr * thdr, const unsigned char * packet) { @@ -367,6 +424,7 @@ void packet_init() { resolver_initialise(); pd = pcap_open_live(options.interface, CAPTURE_LENGTH, options.promiscuous, 1000, errbuf); + // DEBUG: pd = pcap_open_offline("tcpdump.out", errbuf); if(pd == NULL) { fprintf(stderr, "pcap_open_live(%s): %s\n", options.interface, errbuf); exit(1); @@ -378,6 +436,9 @@ void packet_init() { else if(dlt == DLT_RAW) { packet_handler = handle_raw_packet; } + else if(dlt == DLT_IEEE802) { + packet_handler = handle_tokenring_packet; + } /* * SLL support not available in older libpcaps */ diff --git a/llc.h b/llc.h new file mode 100644 index 0000000..b7f33d0 --- /dev/null +++ b/llc.h @@ -0,0 +1,132 @@ +/* + * Copyright (c) 1993, 1994, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#) $Header$ (LBL) + */ + +/* + * This stuff should come from a system header file, but there's no + * obviously portable way to do that and it's not really going + * to change from system to system. + */ + +/* + * A somewhat abstracted view of the LLC header + */ + +struct llc { + u_int8_t dsap; + u_int8_t ssap; + union { + u_int8_t u_ctl; + u_int16_t is_ctl; + struct { + u_int8_t snap_ui; + u_int8_t snap_pi[5]; + } snap; + struct { + u_int8_t snap_ui; + u_int8_t snap_orgcode[3]; + u_int8_t snap_ethertype[2]; + } snap_ether; + } ctl; +}; + +#define llcui ctl.snap.snap_ui +#define llcpi ctl.snap.snap_pi +#define llc_orgcode ctl.snap_ether.snap_orgcode +#define llc_ethertype ctl.snap_ether.snap_ethertype +#define llcis ctl.is_ctl +#define llcu ctl.u_ctl + +#define LLC_U_FMT 3 +#define LLC_GSAP 1 +#define LLC_S_FMT 1 + +#define LLC_U_POLL 0x10 +#define LLC_IS_POLL 0x0100 +#define LLC_XID_FI 0x81 + +#define LLC_U_CMD(u) ((u) & 0xef) +#define LLC_UI 0x03 +#define LLC_UA 0x63 +#define LLC_DISC 0x43 +#define LLC_DM 0x0f +#define LLC_SABME 0x6f +#define LLC_TEST 0xe3 +#define LLC_XID 0xaf +#define LLC_FRMR 0x87 + +#define LLC_S_CMD(is) (((is) >> 1) & 0x03) +#define LLC_RR 0x0001 +#define LLC_RNR 0x0005 +#define LLC_REJ 0x0009 + +#define LLC_IS_NR(is) (((is) >> 9) & 0x7f) +#define LLC_I_NS(is) (((is) >> 1) & 0x7f) + +#ifndef LLCSAP_NULL +#define LLCSAP_NULL 0x00 +#endif +#ifndef LLCSAP_GLOBAL +#define LLCSAP_GLOBAL 0xff +#endif +#ifndef LLCSAP_8021B_I +#define LLCSAP_8021B_I 0x02 +#endif +#ifndef LLCSAP_8021B_G +#define LLCSAP_8021B_G 0x03 +#endif +#ifndef LLCSAP_IP +#define LLCSAP_IP 0x06 +#endif +#ifndef LLCSAP_PROWAYNM +#define LLCSAP_PROWAYNM 0x0e +#endif +#ifndef LLCSAP_8021D +#define LLCSAP_8021D 0x42 +#endif +#ifndef LLCSAP_RS511 +#define LLCSAP_RS511 0x4e +#endif +#ifndef LLCSAP_ISO8208 +#define LLCSAP_ISO8208 0x7e +#endif +#ifndef LLCSAP_PROWAY +#define LLCSAP_PROWAY 0x8e +#endif +#ifndef LLCSAP_SNAP +#define LLCSAP_SNAP 0xaa +#endif +#ifndef LLCSAP_IPX +#define LLCSAP_IPX 0xe0 +#endif +#ifndef LLCSAP_NETBEUI +#define LLCSAP_NETBEUI 0xf0 +#endif +#ifndef LLCSAP_ISONS +#define LLCSAP_ISONS 0xfe +#endif + +#define OUI_ENCAP_ETHER 0x000000 /* encapsulated Ethernet */ +#define OUI_CISCO 0x00000c /* Cisco protocols */ +#define ETHERTYPE_CISCO_CDP 0x2000 /* Cisco Discovery Protocol */ +#define OUI_CISCO_90 0x0000f8 /* Cisco bridging */ +#define OUI_APPLETALK 0x080007 /* Appletalk */ diff --git a/resolver.c b/resolver.c index 55fbd58..086bde5 100644 --- a/resolver.c +++ b/resolver.c @@ -238,10 +238,7 @@ char *do_resolve(struct in_addr *addr) { #endif void resolver_worker(void* ptr) { - struct timespec delay; /* int thread_number = *(int*)ptr;*/ - delay.tv_sec = 0; - delay.tv_nsec = 500; pthread_mutex_lock(&resolver_queue_mutex); sethostent(1); while(1) { diff --git a/token.h b/token.h new file mode 100644 index 0000000..8b90dff --- /dev/null +++ b/token.h @@ -0,0 +1,52 @@ +/* @(#) $Header$ (LBL) */ +/* + * Copyright (c) 1998, Larry Lile + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#define TOKEN_HDRLEN 14 +#define TOKEN_RING_MAC_LEN 6 +#define ROUTING_SEGMENT_MAX 16 +#define IS_SOURCE_ROUTED(trp) ((trp)->token_shost[0] & 0x80) +#define FRAME_TYPE(trp) (((trp)->token_fc & 0xC0) >> 6) +#define TOKEN_FC_LLC 1 + +#define BROADCAST(trp) ((ntohs((trp)->token_rcf) & 0xE000) >> 13) +#define RIF_LENGTH(trp) ((ntohs((trp)->token_rcf) & 0x1f00) >> 8) +#define DIRECTION(trp) ((ntohs((trp)->token_rcf) & 0x0080) >> 7) +#define LARGEST_FRAME(trp) ((ntohs((trp)->token_rcf) & 0x0070) >> 4) +#define RING_NUMBER(trp, x) ((ntohs((trp)->token_rseg[x]) & 0xfff0) >> 4) +#define BRIDGE_NUMBER(trp, x) ((ntohs((trp)->token_rseg[x]) & 0x000f)) +#define SEGMENT_COUNT(trp) ((RIF_LENGTH(trp) - 2) / 2) + +struct token_header { + u_int8_t token_ac; + u_int8_t token_fc; + u_int8_t token_dhost[TOKEN_RING_MAC_LEN]; + u_int8_t token_shost[TOKEN_RING_MAC_LEN]; + u_int16_t token_rcf; + u_int16_t token_rseg[ROUTING_SEGMENT_MAX]; +};