2 // Copyright (c) 2010-2017 Intel Corporation
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
17 #ifndef _PKT_PARSER_H_
18 #define _PKT_PARSER_H_
21 #include <rte_ether.h>
25 #include <rte_byteorder.h>
27 #include "prox_compat.h"
38 } __attribute__((packed));
46 static void pkt_tuple_debug2(const struct pkt_tuple *pt)
48 plogx_info("src_ip : %#010x\n", pt->src_addr);
49 plogx_info("dst_ip : %#010x\n", pt->dst_addr);
50 plogx_info("dst_port : %#06x\n", pt->dst_port);
51 plogx_info("src_port : %#06x\n", pt->src_port);
52 plogx_info("proto_id : %#04x\n", pt->proto_id);
53 plogx_info("l2 types: \n");
54 for (int i = 0; i < 4; ++i)
55 plogx_info(" - %#04x\n", pt->l2_types[i]);
58 static void pkt_tuple_debug(const struct pkt_tuple *pt)
60 plogx_dbg("src_ip : %#010x\n", pt->src_addr);
61 plogx_dbg("dst_ip : %#010x\n", pt->dst_addr);
62 plogx_dbg("dst_port : %#06x\n", pt->dst_port);
63 plogx_dbg("src_port : %#06x\n", pt->src_port);
64 plogx_dbg("proto_id : %#04x\n", pt->proto_id);
65 plogx_dbg("l2 types: \n");
66 for (int i = 0; i < 4; ++i)
67 plogx_dbg(" - %#04x\n", pt->l2_types[i]);
70 /* Return 0 on success, i.e. packets parsed without any error. */
71 static int parse_pkt(struct rte_mbuf *mbuf, struct pkt_tuple *pt, struct l4_meta *l4_meta)
73 prox_rte_ether_hdr *peth = rte_pktmbuf_mtod(mbuf, prox_rte_ether_hdr *);
74 size_t l2_types_count = 0;
75 prox_rte_ipv4_hdr* pip = 0;
78 pt->l2_types[l2_types_count++] = peth->ether_type;
80 switch (peth->ether_type) {
82 pip = (prox_rte_ipv4_hdr *)(peth + 1);
85 prox_rte_vlan_hdr *vlan = (prox_rte_vlan_hdr *)(peth + 1);
86 pt->l2_types[l2_types_count++] = vlan->eth_proto;
87 if (vlan->eth_proto == ETYPE_IPv4) {
88 pip = (prox_rte_ipv4_hdr *)(peth + 1);
90 else if (vlan->eth_proto == ETYPE_VLAN) {
91 prox_rte_vlan_hdr *vlan = (prox_rte_vlan_hdr *)(peth + 1);
92 pt->l2_types[l2_types_count++] = vlan->eth_proto;
93 if (vlan->eth_proto == ETYPE_IPv4) {
94 pip = (prox_rte_ipv4_hdr *)(peth + 1);
96 else if (vlan->eth_proto == ETYPE_IPv6) {
100 /* TODO: handle BAD PACKET */
107 prox_rte_vlan_hdr *vlan = (prox_rte_vlan_hdr *)(peth + 1);
108 pt->l2_types[l2_types_count++] = vlan->eth_proto;
109 if (vlan->eth_proto == ETYPE_VLAN) {
110 prox_rte_vlan_hdr *vlan = (prox_rte_vlan_hdr *)(peth + 1);
111 pt->l2_types[l2_types_count++] = vlan->eth_proto;
112 if (vlan->eth_proto == ETYPE_IPv4) {
113 pip = (prox_rte_ipv4_hdr *)(peth + 1);
128 plogx_err("Parsing error: unknown packet ether type = %#06x\n", peth->ether_type);
134 if ((pip->version_ihl >> 4) == 4) {
136 if ((pip->version_ihl & 0x0f) != 0x05) {
137 /* TODO: optional fields */
141 pt->proto_id = pip->next_proto_id;
142 pt->src_addr = pip->src_addr;
143 pt->dst_addr = pip->dst_addr;
146 /* TODO: IPv6 and bad packets */
151 if (pt->proto_id == IPPROTO_UDP) {
152 prox_rte_udp_hdr *udp = (prox_rte_udp_hdr*)(pip + 1);
153 l4_meta->l4_hdr = (uint8_t*)udp;
154 pt->src_port = udp->src_port;
155 pt->dst_port = udp->dst_port;
156 l4_meta->payload = ((uint8_t*)udp) + sizeof(prox_rte_udp_hdr);
157 l4_meta->len = rte_be_to_cpu_16(udp->dgram_len) - sizeof(prox_rte_udp_hdr);
159 else if (pt->proto_id == IPPROTO_TCP) {
160 prox_rte_tcp_hdr *tcp = (prox_rte_tcp_hdr*)(pip + 1);
161 l4_meta->l4_hdr = (uint8_t*)tcp;
162 pt->src_port = tcp->src_port;
163 pt->dst_port = tcp->dst_port;
165 l4_meta->payload = ((uint8_t*)tcp) + ((tcp->data_off >> 4)*4);
166 l4_meta->len = rte_be_to_cpu_16(pip->total_length) - sizeof(prox_rte_ipv4_hdr) - ((tcp->data_off >> 4)*4);
169 plog_err("unsupported protocol %d\n", pt->proto_id);
173 for (; l2_types_count < sizeof(pt->l2_types)/sizeof(pt->l2_types[0]); ++l2_types_count)
174 pt->l2_types[l2_types_count] = 0;
179 #endif /* _PKT_PARSER_H_ */