@@ -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 (" \t Src addr:\t %s\n " , inet_ntoa (*(struct in_addr *) (&ip->saddr )));
270333 DEBUG_MSG (" \t Dest 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