ip: Protocol Independent IP Neighbors
[vpp.git] / src / vnet / ethernet / arp_packet.c
1 /*
2  * ethernet/arp.c: IP v4 ARP node
3  *
4  * Copyright (c) 2010 Cisco and/or its affiliates.
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #include <vnet/ethernet/arp_packet.h>
19 #include <vnet/ethernet/ethernet.h>
20 #include <vnet/ip/format.h>
21
22 u8 *
23 format_ethernet_arp_opcode (u8 * s, va_list * va)
24 {
25   ethernet_arp_opcode_t o = va_arg (*va, ethernet_arp_opcode_t);
26   char *t = 0;
27   switch (o)
28     {
29 #define _(f) case ETHERNET_ARP_OPCODE_##f: t = #f; break;
30       foreach_ethernet_arp_opcode;
31 #undef _
32
33     default:
34       return format (s, "unknown 0x%x", o);
35     }
36
37   return format (s, "%s", t);
38 }
39
40 u8 *
41 format_ethernet_arp_hardware_type (u8 * s, va_list * va)
42 {
43   ethernet_arp_hardware_type_t h = va_arg (*va, ethernet_arp_hardware_type_t);
44   char *t = 0;
45   switch (h)
46     {
47 #define _(n,f) case n: t = #f; break;
48       foreach_ethernet_arp_hardware_type;
49 #undef _
50
51     default:
52       return format (s, "unknown 0x%x", h);
53     }
54
55   return format (s, "%s", t);
56 }
57
58 u8 *
59 format_ethernet_arp_header (u8 * s, va_list * va)
60 {
61   ethernet_arp_header_t *a = va_arg (*va, ethernet_arp_header_t *);
62   u32 max_header_bytes = va_arg (*va, u32);
63   u32 indent;
64   u16 l2_type, l3_type;
65
66   if (max_header_bytes != 0 && sizeof (a[0]) > max_header_bytes)
67     return format (s, "ARP header truncated");
68
69   l2_type = clib_net_to_host_u16 (a->l2_type);
70   l3_type = clib_net_to_host_u16 (a->l3_type);
71
72   indent = format_get_indent (s);
73
74   s = format (s, "%U, type %U/%U, address size %d/%d",
75               format_ethernet_arp_opcode, clib_net_to_host_u16 (a->opcode),
76               format_ethernet_arp_hardware_type, l2_type,
77               format_ethernet_type, l3_type,
78               a->n_l2_address_bytes, a->n_l3_address_bytes);
79
80   if (l2_type == ETHERNET_ARP_HARDWARE_TYPE_ethernet
81       && l3_type == ETHERNET_TYPE_IP4)
82     {
83       s = format (s, "\n%U%U/%U -> %U/%U",
84                   format_white_space, indent,
85                   format_mac_address_t, &a->ip4_over_ethernet[0].mac,
86                   format_ip4_address, &a->ip4_over_ethernet[0].ip4,
87                   format_mac_address_t, &a->ip4_over_ethernet[1].mac,
88                   format_ip4_address, &a->ip4_over_ethernet[1].ip4);
89     }
90   else
91     {
92       uword n2 = a->n_l2_address_bytes;
93       uword n3 = a->n_l3_address_bytes;
94       s = format (s, "\n%U%U/%U -> %U/%U",
95                   format_white_space, indent,
96                   format_hex_bytes, a->data + 0 * n2 + 0 * n3, n2,
97                   format_hex_bytes, a->data + 1 * n2 + 0 * n3, n3,
98                   format_hex_bytes, a->data + 1 * n2 + 1 * n3, n2,
99                   format_hex_bytes, a->data + 2 * n2 + 1 * n3, n3);
100     }
101
102   return s;
103 }
104
105 /*
106  * fd.io coding-style-patch-verification: ON
107  *
108  * Local Variables:
109  * eval: (c-set-style "gnu")
110  * End:
111  */