suricata
decode-ethernet.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2014 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \ingroup decode
20  *
21  * @{
22  */
23 
24 
25 /**
26  * \file
27  *
28  * \author Victor Julien <victor@inliniac.net>
29  *
30  * Decode Ethernet
31  */
32 
33 #include "suricata-common.h"
34 #include "decode.h"
35 #include "decode-ethernet.h"
36 #include "decode-events.h"
37 
38 #include "util-unittest.h"
39 #include "util-debug.h"
40 
42  uint8_t *pkt, uint32_t len, PacketQueue *pq)
43 {
44  StatsIncr(tv, dtv->counter_eth);
45 
46  if (unlikely(len < ETHERNET_HEADER_LEN)) {
48  return TM_ECODE_FAILED;
49  }
50 
51  if (unlikely(len > ETHERNET_HEADER_LEN + USHRT_MAX)) {
52  return TM_ECODE_FAILED;
53  }
54 
55  p->ethh = (EthernetHdr *)pkt;
56  if (unlikely(p->ethh == NULL))
57  return TM_ECODE_FAILED;
58 
59  SCLogDebug("p %p pkt %p ether type %04x", p, pkt, SCNtohs(p->ethh->eth_type));
60 
61  switch (SCNtohs(p->ethh->eth_type)) {
62  case ETHERNET_TYPE_IP:
63  //printf("DecodeEthernet ip4\n");
64  DecodeIPV4(tv, dtv, p, pkt + ETHERNET_HEADER_LEN,
65  len - ETHERNET_HEADER_LEN, pq);
66  break;
67  case ETHERNET_TYPE_IPV6:
68  //printf("DecodeEthernet ip6\n");
69  DecodeIPV6(tv, dtv, p, pkt + ETHERNET_HEADER_LEN,
70  len - ETHERNET_HEADER_LEN, pq);
71  break;
73  //printf("DecodeEthernet PPPOE Session\n");
74  DecodePPPOESession(tv, dtv, p, pkt + ETHERNET_HEADER_LEN,
75  len - ETHERNET_HEADER_LEN, pq);
76  break;
78  //printf("DecodeEthernet PPPOE Discovery\n");
79  DecodePPPOEDiscovery(tv, dtv, p, pkt + ETHERNET_HEADER_LEN,
80  len - ETHERNET_HEADER_LEN, pq);
81  break;
82  case ETHERNET_TYPE_VLAN:
84  DecodeVLAN(tv, dtv, p, pkt + ETHERNET_HEADER_LEN,
85  len - ETHERNET_HEADER_LEN, pq);
86  break;
89  DecodeMPLS(tv, dtv, p, pkt + ETHERNET_HEADER_LEN,
90  len - ETHERNET_HEADER_LEN, pq);
91  break;
92  case ETHERNET_TYPE_DCE:
93  if (unlikely(len < ETHERNET_DCE_HEADER_LEN)) {
95  } else {
96  DecodeEthernet(tv, dtv, p, pkt + ETHERNET_DCE_HEADER_LEN,
97  len - ETHERNET_DCE_HEADER_LEN, pq);
98  }
99  break;
100  default:
101  SCLogDebug("p %p pkt %p ether type %04x not supported", p,
102  pkt, SCNtohs(p->ethh->eth_type));
103  }
104 
105  return TM_ECODE_OK;
106 }
107 
108 #ifdef UNITTESTS
109 /** DecodeEthernettest01
110  * \brief Valid Ethernet packet
111  * \retval 0 Expected test value
112  */
113 static int DecodeEthernetTest01 (void)
114 {
115  /* ICMP packet wrapped in PPPOE */
116  uint8_t raw_eth[] = {
117  0x00, 0x10, 0x94, 0x55, 0x00, 0x01, 0x00, 0x10,
118  0x94, 0x56, 0x00, 0x01, 0x88, 0x64, 0x11, 0x00,
119  0x00, 0x01, 0x00, 0x68, 0x00, 0x21, 0x45, 0xc0,
120  0x00, 0x64, 0x00, 0x1e, 0x00, 0x00, 0xff, 0x01,
121  0xa7, 0x78, 0x0a, 0x00, 0x00, 0x02, 0x0a, 0x00,
122  0x00, 0x01, 0x08, 0x00, 0x4a, 0x61, 0x00, 0x06,
123  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f,
124  0x3b, 0xd4, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd,
125  0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd,
126  0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd,
127  0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd,
128  0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd,
129  0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd,
130  0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd,
131  0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd,
132  0xab, 0xcd };
133 
135  if (unlikely(p == NULL))
136  return 0;
137  ThreadVars tv;
138  DecodeThreadVars dtv;
139 
140  memset(&dtv, 0, sizeof(DecodeThreadVars));
141  memset(&tv, 0, sizeof(ThreadVars));
142  memset(p, 0, SIZE_OF_PACKET);
143 
144  DecodeEthernet(&tv, &dtv, p, raw_eth, sizeof(raw_eth), NULL);
145 
146  SCFree(p);
147  return 1;
148 }
149 #endif /* UNITTESTS */
150 
151 
152 /**
153  * \brief Registers Ethernet unit tests
154  * \todo More Ethernet tests
155  */
157 {
158 #ifdef UNITTESTS
159  UtRegisterTest("DecodeEthernetTest01", DecodeEthernetTest01);
160 #endif /* UNITTESTS */
161 }
162 /**
163  * @}
164  */
int DecodePPPOESession(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint32_t len, PacketQueue *pq)
Main decoding function for PPPOE Session packets.
Definition: decode-pppoe.c:129
EthernetHdr * ethh
Definition: decode.h:491
#define SCLogDebug(...)
Definition: util-debug.h:335
#define unlikely(expr)
Definition: util-optimize.h:35
uint16_t counter_eth
Definition: decode.h:647
int DecodePPPOEDiscovery(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint32_t len, PacketQueue *pq)
Main decoding function for PPPOE Discovery packets.
Definition: decode-pppoe.c:50
#define ETHERNET_TYPE_VLAN
Definition: decode-vlan.h:31
int DecodeIPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
Definition: decode-ipv4.c:532
#define SIZE_OF_PACKET
Definition: decode.h:618
int DecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
Definition: decode-ipv6.c:584
int DecodeMPLS(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint32_t len, PacketQueue *pq)
Definition: decode-mpls.c:47
#define ETHERNET_TYPE_IP
#define ETHERNET_TYPE_PPPOE_DISC
int DecodeEthernet(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint32_t len, PacketQueue *pq)
#define ETHERNET_TYPE_DCE
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Structure to hold thread specific data for all decode modules.
Definition: decode.h:632
#define ETHERNET_TYPE_MPLS_MULTICAST
Definition: decode-mpls.h:30
void DecodeEthernetRegisterTests(void)
Registers Ethernet unit tests.
#define ETHERNET_DCE_HEADER_LEN
void StatsIncr(ThreadVars *tv, uint16_t id)
Increments the local counter.
Definition: counters.c:163
int DecodeVLAN(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint32_t len, PacketQueue *pq)
Definition: decode-vlan.c:62
#define ETHERNET_HEADER_LEN
#define ETHERNET_TYPE_PPPOE_SESS
#define SCMalloc(a)
Definition: util-mem.h:166
#define SCFree(a)
Definition: util-mem.h:228
#define SCNtohs(x)
uint8_t len
Per thread variable structure.
Definition: threadvars.h:57
#define ETHERNET_TYPE_IPV6
#define ETHERNET_TYPE_MPLS_UNICAST
Definition: decode-mpls.h:29
#define ETHERNET_TYPE_8021QINQ
#define ENGINE_SET_INVALID_EVENT(p, e)
Definition: decode.h:999