Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2015 Cisco and/or its affiliates. |
| 3 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | * you may not use this file except in compliance with the License. |
| 5 | * You may obtain a copy of the License at: |
| 6 | * |
| 7 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | * |
| 9 | * Unless required by applicable law or agreed to in writing, software |
| 10 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | * See the License for the specific language governing permissions and |
| 13 | * limitations under the License. |
| 14 | */ |
| 15 | #include <vat/vat.h> |
| 16 | #include <vnet/ip/ip.h> |
| 17 | |
| 18 | uword unformat_sw_if_index (unformat_input_t * input, va_list * args) |
| 19 | { |
| 20 | vat_main_t * vam = va_arg (*args, vat_main_t *); |
| 21 | u32 * result = va_arg (*args, u32 *); |
| 22 | u8 * if_name; |
| 23 | uword * p; |
| 24 | |
| 25 | if (!unformat (input, "%s", &if_name)) |
| 26 | return 0; |
| 27 | |
| 28 | p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name); |
| 29 | if (p == 0) |
| 30 | return 0; |
| 31 | *result = p[0]; |
| 32 | return 1; |
| 33 | } |
| 34 | |
| 35 | /* Parse an IP4 address %d.%d.%d.%d. */ |
| 36 | uword unformat_ip4_address (unformat_input_t * input, va_list * args) |
| 37 | { |
| 38 | u8 * result = va_arg (*args, u8 *); |
| 39 | unsigned a[4]; |
| 40 | |
| 41 | if (! unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3])) |
| 42 | return 0; |
| 43 | |
| 44 | if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256) |
| 45 | return 0; |
| 46 | |
| 47 | result[0] = a[0]; |
| 48 | result[1] = a[1]; |
| 49 | result[2] = a[2]; |
| 50 | result[3] = a[3]; |
| 51 | |
| 52 | return 1; |
| 53 | } |
| 54 | |
| 55 | uword |
| 56 | unformat_ethernet_address (unformat_input_t * input, va_list * args) |
| 57 | { |
| 58 | u8 * result = va_arg (*args, u8 *); |
| 59 | u32 i, a[6]; |
| 60 | |
| 61 | if (! unformat (input, "%_%x:%x:%x:%x:%x:%x%_", |
| 62 | &a[0], &a[1], &a[2], &a[3], &a[4], &a[5])) |
| 63 | return 0; |
| 64 | |
| 65 | /* Check range. */ |
| 66 | for (i = 0; i < 6; i++) |
| 67 | if (a[i] >= (1 << 8)) |
| 68 | return 0; |
| 69 | |
| 70 | for (i = 0; i < 6; i++) |
| 71 | result[i] = a[i]; |
| 72 | |
| 73 | return 1; |
| 74 | } |
| 75 | |
| 76 | /* Returns ethernet type as an int in host byte order. */ |
| 77 | uword |
| 78 | unformat_ethernet_type_host_byte_order (unformat_input_t * input, |
| 79 | va_list * args) |
| 80 | { |
| 81 | u16 * result = va_arg (*args, u16 *); |
| 82 | int type; |
| 83 | |
| 84 | /* Numeric type. */ |
| 85 | if (unformat (input, "0x%x", &type) |
| 86 | || unformat (input, "%d", &type)) |
| 87 | { |
| 88 | if (type >= (1 << 16)) |
| 89 | return 0; |
| 90 | *result = type; |
| 91 | return 1; |
| 92 | } |
| 93 | return 0; |
| 94 | } |
| 95 | |
| 96 | /* Parse an IP6 address. */ |
| 97 | uword unformat_ip6_address (unformat_input_t * input, va_list * args) |
| 98 | { |
| 99 | ip6_address_t * result = va_arg (*args, ip6_address_t *); |
| 100 | u16 hex_quads[8]; |
| 101 | uword hex_quad, n_hex_quads, hex_digit, n_hex_digits; |
| 102 | uword c, n_colon, double_colon_index; |
| 103 | |
| 104 | n_hex_quads = hex_quad = n_hex_digits = n_colon = 0; |
| 105 | double_colon_index = ARRAY_LEN (hex_quads); |
| 106 | while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT) |
| 107 | { |
| 108 | hex_digit = 16; |
| 109 | if (c >= '0' && c <= '9') |
| 110 | hex_digit = c - '0'; |
| 111 | else if (c >= 'a' && c <= 'f') |
| 112 | hex_digit = c + 10 - 'a'; |
| 113 | else if (c >= 'A' && c <= 'F') |
| 114 | hex_digit = c + 10 - 'A'; |
| 115 | else if (c == ':' && n_colon < 2) |
| 116 | n_colon++; |
| 117 | else |
| 118 | { |
| 119 | unformat_put_input (input); |
| 120 | break; |
| 121 | } |
| 122 | |
| 123 | /* Too many hex quads. */ |
| 124 | if (n_hex_quads >= ARRAY_LEN (hex_quads)) |
| 125 | return 0; |
| 126 | |
| 127 | if (hex_digit < 16) |
| 128 | { |
| 129 | hex_quad = (hex_quad << 4) | hex_digit; |
| 130 | |
| 131 | /* Hex quad must fit in 16 bits. */ |
| 132 | if (n_hex_digits >= 4) |
| 133 | return 0; |
| 134 | |
| 135 | n_colon = 0; |
| 136 | n_hex_digits++; |
| 137 | } |
| 138 | |
| 139 | /* Save position of :: */ |
| 140 | if (n_colon == 2) |
| 141 | { |
| 142 | /* More than one :: ? */ |
| 143 | if (double_colon_index < ARRAY_LEN (hex_quads)) |
| 144 | return 0; |
| 145 | double_colon_index = n_hex_quads; |
| 146 | } |
| 147 | |
| 148 | if (n_colon > 0 && n_hex_digits > 0) |
| 149 | { |
| 150 | hex_quads[n_hex_quads++] = hex_quad; |
| 151 | hex_quad = 0; |
| 152 | n_hex_digits = 0; |
| 153 | } |
| 154 | } |
| 155 | |
| 156 | if (n_hex_digits > 0) |
| 157 | hex_quads[n_hex_quads++] = hex_quad; |
| 158 | |
| 159 | { |
| 160 | word i; |
| 161 | |
| 162 | /* Expand :: to appropriate number of zero hex quads. */ |
| 163 | if (double_colon_index < ARRAY_LEN (hex_quads)) |
| 164 | { |
| 165 | word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads; |
| 166 | |
| 167 | for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--) |
| 168 | hex_quads[n_zero + i] = hex_quads[i]; |
| 169 | |
| 170 | for (i = 0; i < n_zero; i++) |
| 171 | hex_quads[double_colon_index + i] = 0; |
| 172 | |
| 173 | n_hex_quads = ARRAY_LEN (hex_quads); |
| 174 | } |
| 175 | |
| 176 | /* Too few hex quads given. */ |
| 177 | if (n_hex_quads < ARRAY_LEN (hex_quads)) |
| 178 | return 0; |
| 179 | |
| 180 | for (i = 0; i < ARRAY_LEN (hex_quads); i++) |
| 181 | result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]); |
| 182 | |
| 183 | return 1; |
| 184 | } |
| 185 | } |
| 186 | |
| 187 | u8 * format_ip4_address (u8 * s, va_list * args) |
| 188 | { |
| 189 | u8 * a = va_arg (*args, u8 *); |
| 190 | return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]); |
| 191 | } |
| 192 | |
| 193 | u8 * format_ethernet_address (u8 * s, va_list * args) |
| 194 | { |
| 195 | u8 * a = va_arg (*args, u8 *); |
| 196 | |
| 197 | return format (s, "%02x:%02x:%02x:%02x:%02x:%02x", |
| 198 | a[0], a[1], a[2], a[3], a[4], a[5]); |
| 199 | } |
| 200 | |
| 201 | void vat_plugin_api_reference(void) { } |