488008d733205895964912b879cdb811f8560a55
[samplevnf.git] / VNFs / DPPD-PROX / arp.h
1 /*
2 // Copyright (c) 2010-2017 Intel Corporation
3 //
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
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
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.
15 */
16
17 #ifndef _ARP_H_
18 #define _ARP_H_
19
20 #include <rte_ether.h>
21 #include "etypes.h"
22 #include "mbuf_utils.h"
23
24 #define ARP_REQUEST     0x100
25 #define ARP_REPLY       0x200
26
27 struct _arp_ipv4 {
28         struct ether_addr sha; /* Sender hardware address */
29         uint32_t spa;          /* Sender protocol address */
30         struct ether_addr tha; /* Target hardware address */
31         uint32_t tpa;          /* Target protocol address */
32 } __attribute__((__packed__));
33 typedef struct _arp_ipv4 arp_ipv4_t;
34
35 struct my_arp_t {
36         uint16_t   htype;
37         uint16_t   ptype;
38         uint8_t    hlen;
39         uint8_t    plen;
40         uint16_t   oper;
41         arp_ipv4_t data;
42 } __attribute__((__packed__));
43
44 struct ether_hdr_arp {
45         struct ether_hdr ether_hdr;
46         struct my_arp_t arp;
47 };
48
49 static int arp_is_gratuitous(struct ether_hdr_arp *hdr)
50 {
51         return hdr->arp.data.spa == hdr->arp.data.tpa;
52 }
53
54 static inline void build_arp_reply(struct ether_hdr_arp *hdr_arp, struct ether_addr *s_addr)
55 {
56         uint32_t ip_source = hdr_arp->arp.data.spa;
57
58         memcpy(hdr_arp->ether_hdr.d_addr.addr_bytes, hdr_arp->ether_hdr.s_addr.addr_bytes, sizeof(struct ether_addr));
59         memcpy(hdr_arp->ether_hdr.s_addr.addr_bytes, s_addr, sizeof(struct ether_addr));
60
61         hdr_arp->arp.data.spa = hdr_arp->arp.data.tpa;
62         hdr_arp->arp.data.tpa = ip_source;
63         hdr_arp->arp.oper = 0x200;
64         memcpy(&hdr_arp->arp.data.tha, &hdr_arp->arp.data.sha, sizeof(struct ether_addr));
65         memcpy(&hdr_arp->arp.data.sha, s_addr, sizeof(struct ether_addr));
66 }
67
68 static inline void build_arp_request(struct rte_mbuf *mbuf, struct ether_addr *src_mac, uint32_t ip_dst, uint32_t ip_src)
69 {
70         struct ether_hdr_arp *hdr_arp = rte_pktmbuf_mtod(mbuf, struct ether_hdr_arp *);
71         uint64_t mac_bcast = 0xFFFFFFFFFFFF;
72         rte_pktmbuf_pkt_len(mbuf) = 42;
73         rte_pktmbuf_data_len(mbuf) = 42;
74         init_mbuf_seg(mbuf);
75
76         memcpy(&hdr_arp->ether_hdr.d_addr.addr_bytes, &mac_bcast, 6);
77         memcpy(&hdr_arp->ether_hdr.s_addr.addr_bytes, src_mac, 6);
78         hdr_arp->ether_hdr.ether_type = ETYPE_ARP;
79         hdr_arp->arp.htype = 0x100,
80         hdr_arp->arp.ptype = 0x0008;
81         hdr_arp->arp.hlen = 6;
82         hdr_arp->arp.plen = 4;
83         hdr_arp->arp.oper = 0x100;
84         hdr_arp->arp.data.spa = ip_src;
85         hdr_arp->arp.data.tpa = ip_dst;
86         memset(&hdr_arp->arp.data.tha, 0, sizeof(struct ether_addr));
87         memcpy(&hdr_arp->arp.data.sha, src_mac, sizeof(struct ether_addr));
88 }
89
90 static void create_mac(struct ether_hdr_arp *hdr, struct ether_addr *addr)
91 {
92         addr->addr_bytes[0] = 0x2;
93         addr->addr_bytes[1] = 0;
94         // Instead of sending a completely random MAC address, create the following MAC:
95         // 02:00:x1:x2:x3:x4 where x1:x2:x3:x4 is the IP address
96         memcpy(addr->addr_bytes + 2, (uint32_t *)&hdr->arp.data.tpa, 4);
97 }
98
99 #endif /* _ARP_H_ */