@@ -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