Skip to content

Commit a6576c1

Browse files
authored
Merge pull request #144 from BonnyAD9/support-gre-protocol
Support gre protocol
2 parents 0a8da6e + b8de339 commit a6576c1

File tree

2 files changed

+73
-2
lines changed

2 files changed

+73
-2
lines changed

input/headers.hpp

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

4747
namespace ipxp {
4848

49+
struct grehdr {
50+
uint16_t flags;
51+
#define GRE_CHECKSUM 0x8000
52+
#define GRE_KEY 0x2000
53+
#define GRE_SEQNUM 0x1000
54+
uint16_t type;
55+
};
56+
4957
// Copied protocol headers from netinet/* files, which may not be present on other platforms
5058

5159
struct ethhdr {

input/parser.cpp

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,59 @@ inline uint16_t parse_trill(const u_char *data_ptr, uint16_t data_len, Packet *p
231231
return sizeof(trill_hdr) + op_len_bytes;
232232
}
233233

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

301+
const int ihl = ip->ihl << 2;
302+
303+
if (ip->protocol == IPPROTO_GRE) {
304+
DEBUG_MSG("Parse GRE in ipv4 header\n");
305+
if (data_len < ihl) {
306+
throw "Parser detected malformed packet";
307+
}
308+
return parse_gre(data_ptr + ihl, data_len - ihl, pkt) + ihl;
309+
}
310+
248311
pkt->ip_version = IP::v4;
249312
pkt->ip_proto = ip->protocol;
250313
pkt->ip_tos = ip->tos;
251314
pkt->ip_len = ntohs(ip->tot_len);
252-
pkt->ip_payload_len = pkt->ip_len - (ip->ihl << 2);
315+
pkt->ip_payload_len = pkt->ip_len - ihl;
253316
pkt->ip_ttl = ip->ttl;
254317
pkt->ip_flags = (ntohs(ip->frag_off) & 0xE000) >> 13;
255318
pkt->src_ip.v4 = ip->saddr;
@@ -269,7 +332,7 @@ inline uint16_t parse_ipv4_hdr(const u_char *data_ptr, uint16_t data_len, Packet
269332
DEBUG_MSG("\tSrc addr:\t%s\n", inet_ntoa(*(struct in_addr *) (&ip->saddr)));
270333
DEBUG_MSG("\tDest addr:\t%s\n", inet_ntoa(*(struct in_addr *) (&ip->daddr)));
271334

272-
return (ip->ihl << 2);
335+
return ihl;
273336
}
274337

275338
/**

0 commit comments

Comments
 (0)