| /* |
| * ethernet/arp.c: IP v4 ARP node |
| * |
| * Copyright (c) 2010 Cisco and/or its affiliates. |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at: |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include <vnet/ethernet/arp_packet.h> |
| #include <vnet/ethernet/ethernet.h> |
| #include <vnet/ip/format.h> |
| |
| u8 * |
| format_ethernet_arp_opcode (u8 * s, va_list * va) |
| { |
| ethernet_arp_opcode_t o = va_arg (*va, ethernet_arp_opcode_t); |
| char *t = 0; |
| switch (o) |
| { |
| #define _(f) case ETHERNET_ARP_OPCODE_##f: t = #f; break; |
| foreach_ethernet_arp_opcode; |
| #undef _ |
| |
| default: |
| return format (s, "unknown 0x%x", o); |
| } |
| |
| return format (s, "%s", t); |
| } |
| |
| u8 * |
| format_ethernet_arp_hardware_type (u8 * s, va_list * va) |
| { |
| ethernet_arp_hardware_type_t h = va_arg (*va, ethernet_arp_hardware_type_t); |
| char *t = 0; |
| switch (h) |
| { |
| #define _(n,f) case n: t = #f; break; |
| foreach_ethernet_arp_hardware_type; |
| #undef _ |
| |
| default: |
| return format (s, "unknown 0x%x", h); |
| } |
| |
| return format (s, "%s", t); |
| } |
| |
| u8 * |
| format_ethernet_arp_header (u8 * s, va_list * va) |
| { |
| ethernet_arp_header_t *a = va_arg (*va, ethernet_arp_header_t *); |
| u32 max_header_bytes = va_arg (*va, u32); |
| u32 indent; |
| u16 l2_type, l3_type; |
| |
| if (max_header_bytes != 0 && sizeof (a[0]) > max_header_bytes) |
| return format (s, "ARP header truncated"); |
| |
| l2_type = clib_net_to_host_u16 (a->l2_type); |
| l3_type = clib_net_to_host_u16 (a->l3_type); |
| |
| indent = format_get_indent (s); |
| |
| s = format (s, "%U, type %U/%U, address size %d/%d", |
| format_ethernet_arp_opcode, clib_net_to_host_u16 (a->opcode), |
| format_ethernet_arp_hardware_type, l2_type, |
| format_ethernet_type, l3_type, |
| a->n_l2_address_bytes, a->n_l3_address_bytes); |
| |
| if (l2_type == ETHERNET_ARP_HARDWARE_TYPE_ethernet |
| && l3_type == ETHERNET_TYPE_IP4) |
| { |
| s = format (s, "\n%U%U/%U -> %U/%U", |
| format_white_space, indent, |
| format_mac_address_t, &a->ip4_over_ethernet[0].mac, |
| format_ip4_address, &a->ip4_over_ethernet[0].ip4, |
| format_mac_address_t, &a->ip4_over_ethernet[1].mac, |
| format_ip4_address, &a->ip4_over_ethernet[1].ip4); |
| } |
| else |
| { |
| uword n2 = a->n_l2_address_bytes; |
| uword n3 = a->n_l3_address_bytes; |
| s = format (s, "\n%U%U/%U -> %U/%U", |
| format_white_space, indent, |
| format_hex_bytes, a->data + 0 * n2 + 0 * n3, n2, |
| format_hex_bytes, a->data + 1 * n2 + 0 * n3, n3, |
| format_hex_bytes, a->data + 1 * n2 + 1 * n3, n2, |
| format_hex_bytes, a->data + 2 * n2 + 1 * n3, n3); |
| } |
| |
| return s; |
| } |
| |
| /* |
| * fd.io coding-style-patch-verification: ON |
| * |
| * Local Variables: |
| * eval: (c-set-style "gnu") |
| * End: |
| */ |