From 8817364ef6fa503425aae13aa5880a0e0ab127b9 Mon Sep 17 00:00:00 2001 From: Jamie Date: Sat, 15 Aug 2009 11:22:19 +0100 Subject: [PATCH] initial PPPoE decoder commit --- src/Makefile.am | 1 + src/decode-ethernet.c | 6 +++- src/decode-events.h | 4 +++ src/decode-pppoe.c | 80 +++++++++++++++++++++++++++++++++++++++++++ src/decode-pppoe.h | 39 +++++++++++++++++++++ src/decode.h | 3 ++ src/eidps.c | 1 + src/source-pcap.c | 2 ++ src/source-pcap.h | 1 + 9 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 src/decode-pppoe.c create mode 100644 src/decode-pppoe.h diff --git a/src/Makefile.am b/src/Makefile.am index f6d955e1e7..a0b5f3ab87 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -10,6 +10,7 @@ decode.c decode.h \ decode-ethernet.c decode-ethernet.h \ decode-sll.c decode-sll.h \ decode-ppp.c decode-ppp.h \ +decode-pppoe.c decode-pppoe.h \ decode-ipv4.c decode-ipv4.h \ decode-ipv6.c decode-ipv6.h \ decode-icmpv4.c decode-icmpv4.h \ diff --git a/src/decode-ethernet.c b/src/decode-ethernet.c index e213903103..06c52a4c60 100644 --- a/src/decode-ethernet.c +++ b/src/decode-ethernet.c @@ -27,7 +27,11 @@ void DecodeEthernet(ThreadVars *t, Packet *p, u_int8_t *pkt, u_int16_t len, Pack } else if(ntohs(ethh->eth_type) == ETHERNET_TYPE_IPV6) { //printf("DecodeEthernet ip6\n"); DecodeIPV6(t, p, pkt + ETHERNET_HEADER_LEN, len - ETHERNET_HEADER_LEN); - } + } else if(ntohs(ethh->eth_type) == ETHERNET_TYPE_PPPoE_SESS) { + //printf("DecodeEthernet PPPoE\n"); + PerfCounterIncr(COUNTER_DECODER_PPPOE, t->pca); + DecodePPPoE(t, p, pkt + PPPOE_HEADER_LEN, len - PPPOE_HEADER_LEN, pq); + } return; } diff --git a/src/decode-events.h b/src/decode-events.h index 4c5e2dd45f..5776714393 100644 --- a/src/decode-events.h +++ b/src/decode-events.h @@ -47,6 +47,10 @@ enum { PPPIPV4_PKT_TOO_SMALL, PPPIPV6_PKT_TOO_SMALL, PPP_WRONG_TYPE, + + /* PPPOE EVENTS */ + PPPOE_PKT_TOO_SMALL, + }; }; #endif /* __DECODE_EVENTS_H__ */ diff --git a/src/decode-pppoe.c b/src/decode-pppoe.c new file mode 100644 index 0000000000..281d3f1b77 --- /dev/null +++ b/src/decode-pppoe.c @@ -0,0 +1,80 @@ +/** + * \file Copyright (c) 2009 Open Infosec Foundation + * \author James Riden + * + * PPPoE Decoder + */ + +#include "eidps.h" + +#include "packet-queue.h" + +#include "decode.h" +#include "decode-ppp.h" +#include "decode-pppoe.h" +#include "decode-events.h" + +#include "util-unittest.h" + +/** + * \brief Main decoding function for PPPoE packets + */ +void DecodePPPoE(ThreadVars *t, Packet *p, u_int8_t *pkt, u_int16_t len, PacketQueue *pq) +{ +#ifdef DEBUG + printf("DecodePPPoEPacket\n"); +#endif + + if (len < PPPOE_HEADER_LEN) { + DECODER_SET_EVENT(p, PPPOE_PKT_TOO_SMALL); + return; + } + + p->pppoeh = (PPPoEHdr *)pkt; + + if (p->pppoeh == NULL) + return; + + if (p->pppoeh->pppoe_length>0) { + /* decode contained PPP packet */ + PerfCounterIncr(COUNTER_DECODER_PPP, t->pca); + DecodePPP(t, p, pkt + PPPOE_HEADER_LEN, len - PPPOE_HEADER_LEN, pq); + } + +} + +/** DecodePPPoEtest01 + * /brief Decode malformed PPPoE packet (too short) + * /retval Expected test value: 1 + */ +static int DecodePPPoEtest01 (void) { + + /* 0000 ff ff ff ff ff ff 00 0a e4 13 31 a3 81 00 03 98 ..........1..... + 0010 81 00 00 80 88 63 11 09 00 00 00 08 01 01 00 00 .....c.......... + 0020 01 00 00 00 */ + + u_int8_t raw_pppoe[] = { 0x11, 0x00, 0x00, 0x00, 0x00 }; + Packet p; + ThreadVars tv; + + memset(&tv, 0, sizeof(ThreadVars)); + memset(&p, 0, sizeof(Packet)); + + DecodePPPoE(&tv, &p, raw_pppoe, sizeof(raw_pppoe), NULL); + + /* Function my returns here with expected value */ + + if(DECODER_ISSET_EVENT(&p,PPPOE_PKT_TOO_SMALL)) { + return 1; + } + + return 0; +} + +/** + * \brief Registers PPPoE unit test + * \todo More PPPoE tests + */ +void DecodePPPoERegisterTests(void) { + UtRegisterTest("DecodePPPoEtest01", DecodePPPoEtest01, 1); +} diff --git a/src/decode-pppoe.h b/src/decode-pppoe.h new file mode 100644 index 0000000000..dddd6c7e6f --- /dev/null +++ b/src/decode-pppoe.h @@ -0,0 +1,39 @@ +/** + * \file Copyright (c) 2009 Open Infosec Foundation + * \author James Riden + * + * PPPoE Decoder header file + */ + +#ifndef __DECODE_PPPOE_H__ +#define __DECODE_PPPOE_H__ + +#include +#include +#include +#include +#include + +#include "decode.h" +#include "threadvars.h" + +#define PPPOE_HEADER_LEN 6 + +typedef struct _PPPoEHdr +{ + unsigned pppoe_version :4; + unsigned pppoe_type :4; + u_int8_t pppoe_code; + u_int16_t sessin_id; + u_int16_t pppoe_length; +} PPPoEHdr; + +#define PPPOE_CODE_PADI 0x09 +#define PPPOE_CODE_PADO 0x07 +#define PPPOE_CODE_PADR 0x19 +#define PPPOE_CODE_PADS 0x65 +#define PPPOE_CODE_PADT 0xa7 + +void DecodePPPoERegisterTests(void); + +#endif /* __DECODE_PPPOE_H__ */ diff --git a/src/decode.h b/src/decode.h index 2783f765c0..5c888b1503 100644 --- a/src/decode.h +++ b/src/decode.h @@ -33,6 +33,7 @@ #include "decode-ethernet.h" #include "decode-ppp.h" +#include "decode-pppoe.h" #include "decode-sll.h" #include "decode-ipv4.h" #include "decode-ipv6.h" @@ -239,6 +240,7 @@ typedef struct Packet_ /* header pointers */ EthernetHdr *ethh; PPPHdr *ppph; + PPPoEHdr *pppoeh; IPV4Hdr *ip4h; IPV4Vars ip4vars; @@ -377,6 +379,7 @@ typedef struct PacketQueue_ { void DecodeEthernet(ThreadVars *, Packet *, u_int8_t *, u_int16_t, PacketQueue *); void DecodeSll(ThreadVars *, Packet *, u_int8_t *, u_int16_t, PacketQueue *); void DecodePPP(ThreadVars *, Packet *, u_int8_t *, u_int16_t, PacketQueue *); +void DecodePPPoE(ThreadVars *, Packet *, u_int8_t *, u_int16_t, PacketQueue *); void DecodeTunnel(ThreadVars *, Packet *, u_int8_t *, u_int16_t, PacketQueue *); void DecodeIPV4(ThreadVars *, Packet *, u_int8_t *, u_int16_t, PacketQueue *); void DecodeIPV6(ThreadVars *, Packet *, u_int8_t *, u_int16_t); diff --git a/src/eidps.c b/src/eidps.c index 1b538a7a80..b3d5ecb31e 100644 --- a/src/eidps.c +++ b/src/eidps.c @@ -947,6 +947,7 @@ int main(int argc, char **argv) PerfRegisterTests(); DecodePPPRegisterTests(); HTTPParserRegisterTests(); + DecodePPPoERegisterTests(); UtRunTests(); UtCleanup(); exit(0); diff --git a/src/source-pcap.c b/src/source-pcap.c index 955c8745c6..38c7a88506 100644 --- a/src/source-pcap.c +++ b/src/source-pcap.c @@ -337,6 +337,8 @@ int DecodePcapThreadInit(ThreadVars *tv, void *initdata, void **data) &tv->pctx, TYPE_Q_AVERAGE, 1); PerfRegisterCounter("decoder.max_pkt_size", "DecodePcap", TYPE_UINT64, "NULL", &tv->pctx, TYPE_Q_MAXIMUM, 1); + PerfRegisterCounter("decoder.pppoe", "DecodePcap", TYPE_UINT64, "NULL", + &tv->pctx, TYPE_Q_NONE, 1); tv->pca = PerfGetAllCountersArray(&tv->pctx); diff --git a/src/source-pcap.h b/src/source-pcap.h index 6ffabc1028..0fa8fd703c 100644 --- a/src/source-pcap.h +++ b/src/source-pcap.h @@ -25,6 +25,7 @@ void TmModuleDecodePcapRegister (void); #define COUNTER_DECODER_PPP 11 #define COUNTER_DECODER_AVG_PKT_SIZE 12 #define COUNTER_DECODER_MAX_PKT_SIZE 13 +#define COUNTER_DECODER_PPPOE 14 /* per packet Pcap vars */ typedef struct PcapPacketVars_