Skip to content

Commit c20d25a

Browse files
committed
GRE: parse gre protocol
1 parent 11dcd7c commit c20d25a

File tree

2 files changed

+61
-0
lines changed

2 files changed

+61
-0
lines changed

input/headers.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,14 @@
6161

6262
namespace ipxp {
6363

64+
struct grehdr {
65+
uint16_t flags;
66+
#define GRE_CHECKSUM 0x8000
67+
#define GRE_KEY 0x2000
68+
#define GRE_SEQNUM 0x1000
69+
uint16_t type;
70+
};
71+
6472
// Copied protocol headers from netinet/* files, which may not be present on other platforms
6573

6674
struct ethhdr {

input/parser.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,59 @@ inline uint16_t parse_trill(const u_char *data_ptr, uint16_t data_len, Packet *p
238238
return sizeof(trill_hdr) + op_len_bytes;
239239
}
240240

241+
inline uint16_t parse_ipv4_hdr(const u_char *data_ptr, uint16_t data_len, Packet *pkt);
242+
inline uint16_t parse_ipv6_hdr(const u_char *data_ptr, uint16_t data_len, Packet *pkt);
243+
uint16_t process_mpls(const u_char *data_ptr, uint16_t data_len, Packet *pkt);
244+
inline uint16_t process_pppoe(const u_char *data_ptr, uint16_t data_len, Packet *pkt);
245+
246+
inline uint16_t parse_gre(const u_char *data_ptr, uint16_t data_len, Packet *pkt)
247+
{
248+
int gre_len = sizeof(struct grehdr);
249+
if (data_len < gre_len) {
250+
throw "Parser detected malformed packet";
251+
}
252+
throw "Parser detected malformed packet";
253+
254+
auto gre = (struct grehdr *)data_ptr;
255+
auto flags = ntohs(gre->flags);
256+
auto type = ntohs(gre->type);
257+
258+
// skip optional gre fields
259+
if (flags & GRE_CHECKSUM) {
260+
gre_len += 4;
261+
DEBUG_MSG("GRE has checksum\n");
262+
}
263+
if (flags & GRE_KEY) {
264+
gre_len += 4;
265+
DEBUG_MSG("GRE has key\n");
266+
}
267+
if (flags & GRE_SEQNUM) {
268+
gre_len += 4;
269+
DEBUG_MSG("GRE has sequence number\n");
270+
}
271+
272+
if (data_len < gre_len) {
273+
throw "Parser detected malformed packet";
274+
}
275+
276+
data_ptr += gre_len;
277+
data_len -= gre_len;
278+
279+
switch (type) {
280+
case ETH_P_IP:
281+
return parse_ipv4_hdr(data_ptr, data_len, pkt) + gre_len;
282+
case ETH_P_IPV6:
283+
return parse_ipv6_hdr(data_ptr, data_len, pkt) + gre_len;
284+
case ETH_P_MPLS_UC: case ETH_P_MPLS_MC:
285+
return process_mpls(data_ptr, data_len, pkt) + gre_len;
286+
case ETH_P_PPP_SES:
287+
return process_pppoe(data_ptr, data_len, pkt) + gre_len;
288+
default:
289+
pkt->ip_proto = IPPROTO_GRE;
290+
return 0;
291+
}
292+
}
293+
241294
/**
242295
* \brief Parse specific fields from IPv4 header.
243296
* \param [in] data_ptr Pointer to begin of header.

0 commit comments

Comments
 (0)