1 /* 2 * eui.h -- EUI-48 and EUI-64 (RFC7043) parser 3 * 4 * Copyright (c) 2023, NLnet Labs. All rights reserved. 5 * 6 * SPDX-License-Identifier: BSD-3-Clause 7 * 8 */ 9 #ifndef EUI_H 10 #define EUI_H 11 12 nonnull((1,2)) 13 static really_inline bool 14 eui_base16_dec_loop_generic_32_inner(const uint8_t *s, uint8_t *o, bool last) 15 { 16 const uint32_t val1 = base16_table_dec_32bit_d0[s[0]] 17 | base16_table_dec_32bit_d1[s[1]]; 18 const uint32_t val2 = base16_table_dec_32bit_d0[s[3]] 19 | base16_table_dec_32bit_d1[s[4]]; 20 21 if (val1 > 0xff || val2 > 0xff || s[2] != '-' || (!last && s[5] != '-')) 22 return false; 23 24 o[0] = (uint8_t)val1; 25 o[1] = (uint8_t)val2; 26 27 return true; 28 } 29 30 // RFC7043 section 3.2, require xx-xx-xx-xx-xx-xx 31 nonnull_all 32 static really_inline int32_t parse_eui48( 33 parser_t *parser, 34 const type_info_t *type, 35 const rdata_info_t *field, 36 rdata_t *rdata, 37 const token_t *token) 38 { 39 const uint8_t *input = (const uint8_t *)token->data; 40 if (token->length == 17 && 41 eui_base16_dec_loop_generic_32_inner(input, rdata->octets, false) && 42 eui_base16_dec_loop_generic_32_inner(input+6, rdata->octets+2, false) && 43 eui_base16_dec_loop_generic_32_inner(input+12, rdata->octets+4, true)) 44 return (void)(rdata->octets += 6), 0; 45 SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(field), NAME(type)); 46 } 47 48 // RFC7043 section 4.2, require xx-xx-xx-xx-xx-xx-xx-xx 49 nonnull_all 50 static really_inline int32_t parse_eui64( 51 parser_t *parser, 52 const type_info_t *type, 53 const rdata_info_t *field, 54 rdata_t *rdata, 55 const token_t *token) 56 { 57 const uint8_t *input = (const uint8_t *)token->data; 58 if (token->length == 23 && 59 eui_base16_dec_loop_generic_32_inner(input, rdata->octets, false) && 60 eui_base16_dec_loop_generic_32_inner(input+6, rdata->octets+2, false) && 61 eui_base16_dec_loop_generic_32_inner(input+12, rdata->octets+4, false) && 62 eui_base16_dec_loop_generic_32_inner(input+18, rdata->octets+6, true)) 63 return (void)(rdata->octets += 8), 0; 64 SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(field), NAME(type)); 65 } 66 67 #endif // EUI_H 68