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>
37 } __attribute__((packed));
45 static void pkt_tuple_debug2(const struct pkt_tuple *pt)
47 plogx_info("src_ip : %#010x\n", pt->src_addr);
48 plogx_info("dst_ip : %#010x\n", pt->dst_addr);
49 plogx_info("dst_port : %#06x\n", pt->dst_port);
50 plogx_info("src_port : %#06x\n", pt->src_port);
51 plogx_info("proto_id : %#04x\n", pt->proto_id);
52 plogx_info("l2 types: \n");
53 for (int i = 0; i < 4; ++i)
54 plogx_info(" - %#04x\n", pt->l2_types[i]);
57 static void pkt_tuple_debug(const struct pkt_tuple *pt)
59 plogx_dbg("src_ip : %#010x\n", pt->src_addr);
60 plogx_dbg("dst_ip : %#010x\n", pt->dst_addr);
61 plogx_dbg("dst_port : %#06x\n", pt->dst_port);
62 plogx_dbg("src_port : %#06x\n", pt->src_port);
63 plogx_dbg("proto_id : %#04x\n", pt->proto_id);
64 plogx_dbg("l2 types: \n");
65 for (int i = 0; i < 4; ++i)
66 plogx_dbg(" - %#04x\n", pt->l2_types[i]);
69 /* Return 0 on success, i.e. packets parsed without any error. */
70 static int parse_pkt(struct rte_mbuf *mbuf, struct pkt_tuple *pt, struct l4_meta *l4_meta)
72 struct ether_hdr *peth = rte_pktmbuf_mtod(mbuf, struct ether_hdr *);
73 size_t l2_types_count = 0;
74 struct ipv4_hdr* pip = 0;
77 pt->l2_types[l2_types_count++] = peth->ether_type;
79 switch (peth->ether_type) {
81 pip = (struct ipv4_hdr *)(peth + 1);
84 struct vlan_hdr *vlan = (struct vlan_hdr *)(peth + 1);
85 pt->l2_types[l2_types_count++] = vlan->eth_proto;
86 if (vlan->eth_proto == ETYPE_IPv4) {
87 pip = (struct ipv4_hdr *)(peth + 1);
89 else if (vlan->eth_proto == ETYPE_VLAN) {
90 struct vlan_hdr *vlan = (struct vlan_hdr *)(peth + 1);
91 pt->l2_types[l2_types_count++] = vlan->eth_proto;
92 if (vlan->eth_proto == ETYPE_IPv4) {
93 pip = (struct ipv4_hdr *)(peth + 1);
95 else if (vlan->eth_proto == ETYPE_IPv6) {
99 /* TODO: handle BAD PACKET */
106 struct vlan_hdr *vlan = (struct vlan_hdr *)(peth + 1);
107 pt->l2_types[l2_types_count++] = vlan->eth_proto;
108 if (vlan->eth_proto == ETYPE_VLAN) {
109 struct vlan_hdr *vlan = (struct vlan_hdr *)(peth + 1);
110 pt->l2_types[l2_types_count++] = vlan->eth_proto;
111 if (vlan->eth_proto == ETYPE_IPv4) {
112 pip = (struct ipv4_hdr *)(peth + 1);
127 plogx_err("Parsing error: unknown packet ether type = %#06x\n", peth->ether_type);
133 if ((pip->version_ihl >> 4) == 4) {
135 if ((pip->version_ihl & 0x0f) != 0x05) {
136 /* TODO: optional fields */
140 pt->proto_id = pip->next_proto_id;
141 pt->src_addr = pip->src_addr;
142 pt->dst_addr = pip->dst_addr;
145 /* TODO: IPv6 and bad packets */
150 if (pt->proto_id == IPPROTO_UDP) {
151 struct udp_hdr *udp = (struct udp_hdr*)(pip + 1);
152 l4_meta->l4_hdr = (uint8_t*)udp;
153 pt->src_port = udp->src_port;
154 pt->dst_port = udp->dst_port;
155 l4_meta->payload = ((uint8_t*)udp) + sizeof(struct udp_hdr);
156 l4_meta->len = rte_be_to_cpu_16(udp->dgram_len) - sizeof(struct udp_hdr);
158 else if (pt->proto_id == IPPROTO_TCP) {
159 struct tcp_hdr *tcp = (struct tcp_hdr*)(pip + 1);
160 l4_meta->l4_hdr = (uint8_t*)tcp;
161 pt->src_port = tcp->src_port;
162 pt->dst_port = tcp->dst_port;
164 l4_meta->payload = ((uint8_t*)tcp) + ((tcp->data_off >> 4)*4);
165 l4_meta->len = rte_be_to_cpu_16(pip->total_length) - sizeof(struct ipv4_hdr) - ((tcp->data_off >> 4)*4);
168 plog_err("unsupported protocol %d\n", pt->proto_id);
172 for (; l2_types_count < sizeof(pt->l2_types)/sizeof(pt->l2_types[0]); ++l2_types_count)
173 pt->l2_types[l2_types_count] = 0;
178 #endif /* _PKT_PARSER_H_ */