diff --git a/src/include/pkt.h b/src/include/pkt.h index 82f98b50..f86792c4 100644 --- a/src/include/pkt.h +++ b/src/include/pkt.h @@ -1,24 +1,24 @@ /* - * + * * Copyright (c) 2016 Cisco Systems, Inc. * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: - * + * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. - * + * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. - * + * * Neither the name of the Cisco Systems, Inc. nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS @@ -60,18 +60,44 @@ /** ethernet header */ #define ETHERNET_HDR_LEN 14 +#define TRILL_HDR_LEN 6 #define ETHERNET_ADR_LEN 6 #define ETH_TYPE_IP 0X0800 #define ETH_TYPE_IPV6 0X86DD #define ETH_TYPE_DOT1Q 0X8100 #define ETH_TYPE_QNQ 0X88A8 +#define ETH_TYPE_TRILL 0X22F3 + +typedef struct trill_header { +#ifdef _BIT_FIELDS_HTOL + uint8_t th_version : 2; + uint8_t th_reserved : 2; + uint8_t th_multidest : 1; + uint8_t th_optslen_hi : 3; +#else + uint8_t th_optslen_hi : 3; + uint8_t th_multidest : 1; + uint8_t th_reserved : 2; + uint8_t th_version : 2; +#endif + +#ifdef _BIT_FIELDS_HTOL + uint8_t th_optslen_lo : 2; + uint8_t th_hopcount : 6; +#else + uint8_t th_hopcount : 6; + uint8_t th_optslen_lo : 2; +#endif + uint16_t th_egressnick; + uint16_t th_ingressnick; +} trill_hdr_t; /** ethernet header structure */ struct ethernet_hdr { - unsigned char dst_addr[ETHERNET_ADR_LEN]; - unsigned char src_addr[ETHERNET_ADR_LEN]; - unsigned short ether_type; + unsigned char dst_addr[ETHERNET_ADR_LEN]; + unsigned char src_addr[ETHERNET_ADR_LEN]; + unsigned short ether_type; }; /* IPv6 Header Length */ @@ -121,7 +147,7 @@ typedef struct ipv6_hdr_ { #define IP_RF 0x8000 /* Reserved */ #define IP_DF 0x4000 /* Don't Fragment */ #define IP_MF 0x2000 /* More Fragments */ -#define IP_FOFF 0x1fff /* Fragment Offset */ +#define IP_FOFF 0x1fff /* Fragment Offset */ #define ip_is_fragment(ip) (htons((ip)->ip_flgoff) & (IP_MF | IP_FOFF)) #define ip_fragment_offset(ip) (htons((ip)->ip_flgoff) & IP_FOFF) @@ -179,8 +205,8 @@ struct udp_hdr { /** ICMP header structure */ struct icmp_hdr { - unsigned char type; - unsigned char code; + unsigned char type; + unsigned char code; unsigned short checksum; unsigned int rest_of_header; }; diff --git a/src/pkt_proc.c b/src/pkt_proc.c index 96e4be3a..fa10f93d 100644 --- a/src/pkt_proc.c +++ b/src/pkt_proc.c @@ -840,6 +840,7 @@ uint8_t get_packet_5tuple_key (const unsigned char *packet, flow_key_t *key) { joy_log_info("Ethernet type - 802.1q VLAN #2"); //Offset to get VLAN_TYPE vlan2_ether_type = ntohs(*(const uint16_t *)(packet + ETHERNET_HDR_LEN + DOT1Q_HDR_LEN + 2)); + joy_log_info("Ethernet type - %x", vlan_ether_type); switch(vlan2_ether_type) { case ETH_TYPE_IP: joy_log_info("Ethernet type - IP with 802.1q VLAN #2"); @@ -966,6 +967,9 @@ void* process_packet (unsigned char *ctx_ptr, flow_record_t *record = NULL; bool allocated_packet_header = 0; uint16_t ether_type = 0,vlan_ether_type = 0, vlan2_ether_type = 0; + trill_hdr_t * trill_header; + uint16_t trill_eth_type = 0; + uint32_t trill_op_len = 0; char ipv4_addr[INET_ADDRSTRLEN]; char ipv6_addr[INET6_ADDRSTRLEN]; const struct pcap_pkthdr *header = pkt_header; @@ -1021,7 +1025,61 @@ void* process_packet (unsigned char *ctx_ptr, joy_log_info("Ethernet type - 802.1q VLAN #1"); //Offset to get VLAN_TYPE vlan_ether_type = ntohs(*(const uint16_t *)(packet + ETHERNET_HDR_LEN + 2)); + joy_log_info("vlan_ether_type %x", vlan_ether_type); switch(vlan_ether_type) { + case ETH_TYPE_TRILL: + trill_header = (trill_hdr_t*) (const uint8_t *)(packet +ETHERNET_HDR_LEN + DOT1Q_HDR_LEN ); + trill_op_len = (trill_header->th_optslen_hi <<2)|trill_header->th_optslen_lo; + trill_op_len*=4; + joy_log_info("trill_op_len %x", trill_op_len); + trill_eth_type = ntohs(*(const uint16_t *)(packet + ETHERNET_HDR_LEN + 4 +12 + DOT1Q_HDR_LEN + 2)); + joy_log_info("trill_eth_type %x", trill_eth_type); + switch(trill_eth_type) { + case ETH_TYPE_IP: + joy_log_info("Ethernet type - IP with VLAN #1"); + ip = (ip_hdr_t*)(packet + 2*ETHERNET_HDR_LEN + DOT1Q_HDR_LEN + TRILL_HDR_LEN + trill_op_len); + ip_hdr_len = ip_hdr_length(ip); + ctx->curr_pkt_type = ETH_TYPE_IP; + tot_frame_hdr_len = 2*ETHERNET_HDR_LEN + DOT1Q_HDR_LEN + TRILL_HDR_LEN + trill_op_len; + break; + case ETH_TYPE_IPV6: + joy_log_info("Ethernet type - IPv6"); + ipv6 = (ip_hdrv6_t*)(packet + 2*ETHERNET_HDR_LEN + DOT1Q_HDR_LEN + TRILL_HDR_LEN + trill_op_len); + ip_hdr_len = IPV6_HDR_LENGTH; + ctx->curr_pkt_type = ETH_TYPE_IPV6; + tot_frame_hdr_len = 2*ETHERNET_HDR_LEN + DOT1Q_HDR_LEN + TRILL_HDR_LEN + trill_op_len; + break; + case ETH_TYPE_DOT1Q: + case ETH_TYPE_QNQ: + joy_log_info("Ethernet type - 802.1q VLAN #2"); + //Offset to get VLAN_TYPE + vlan2_ether_type = ntohs(*(const uint16_t *)(packet + ETHERNET_HDR_LEN + TRILL_HDR_LEN + trill_op_len +12 + DOT1Q_HDR_LEN + 2 + 2)); + joy_log_info("vlan2_ether_type %x", vlan2_ether_type); + switch(vlan2_ether_type) { + case ETH_TYPE_IP: + joy_log_info("Ethernet type - IP with 802.1q VLAN #2 with trill"); + ip = (ip_hdr_t*)(packet + 2*ETHERNET_HDR_LEN + DOT1Q_HDR_LEN + DOT1Q_HDR_LEN + TRILL_HDR_LEN + trill_op_len); + ip_hdr_len = ip_hdr_length(ip); + ctx->curr_pkt_type = ETH_TYPE_IP; + tot_frame_hdr_len = 2*ETHERNET_HDR_LEN + DOT1Q_HDR_LEN + DOT1Q_HDR_LEN + TRILL_HDR_LEN + trill_op_len; + break; + case ETH_TYPE_IPV6: + joy_log_info("Ethernet type - IPv6"); + ipv6 = (ip_hdrv6_t*)(packet + 2*ETHERNET_HDR_LEN + DOT1Q_HDR_LEN + DOT1Q_HDR_LEN + TRILL_HDR_LEN + trill_op_len); + ip_hdr_len = IPV6_HDR_LENGTH; + ctx->curr_pkt_type = ETH_TYPE_IPV6; + tot_frame_hdr_len = 2*ETHERNET_HDR_LEN + DOT1Q_HDR_LEN + DOT1Q_HDR_LEN + TRILL_HDR_LEN + trill_op_len; + break; + default : + joy_log_info("Ethernet type - Unknown with 802.1q VLAN #2 with trill"); + return NULL; + } + break; + default : + joy_log_info("Ethernet type - Unknown trill"); + return NULL; + } + break; case ETH_TYPE_IP: joy_log_info("Ethernet type - IP with VLAN #1"); ip = (ip_hdr_t*)(packet + ETHERNET_HDR_LEN + DOT1Q_HDR_LEN);