1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Copyright (c) 2022 Huawei Device Co., Ltd. 4 * 5 * Description: Provide operations and conversions 6 * related to NewIP address. 7 * 8 * Author: Yang Yanjun <yangyanjun@huawei.com> 9 * 10 * Data: 2022-07-18 11 */ 12#include "nip_addr.h" 13 14/* This is similar to 0.0.0.0 in IPv4. Does not appear as a real address, 15 * just a constant used by the native for special processing 16 */ 17const struct nip_addr nip_any_addr = { 18 .bitlen = NIP_ADDR_BIT_LEN_16, 19 .NIP_ADDR_FIELD8[0] = 0xFF, /* 0xFF09 addr, big-endian */ 20 .NIP_ADDR_FIELD8[1] = 0x09, 21}; 22 23const struct nip_addr nip_broadcast_addr_arp = { 24 .bitlen = NIP_ADDR_BIT_LEN_16, 25 .NIP_ADDR_FIELD8[0] = 0xFF, /* 0xFF04 addr, big-endian */ 26 .NIP_ADDR_FIELD8[1] = 0x04, 27}; 28 29static const struct nip_addr nip_local_addr = { 30 .bitlen = NIP_ADDR_BIT_LEN_16, 31 .NIP_ADDR_FIELD8[0] = 0xFF, /* 0xFF00 addr, big-endian */ 32 .NIP_ADDR_FIELD8[1] = 0x00, 33}; 34 35enum addr_check_ret { 36 NOT_CURRENT_ADDR = -1, 37 CURRENT_ADDR_VALID = 0, 38 ADDR_2BYTE_INVALID = 1, 39 ADDR_3BYTE_INVALID = 2, 40 ADDR_5BYTE_INVALID = 3, 41 ADDR_7BYTE_INVALID = 4, 42 ADDR_BITLEN_INVALID = 5, 43 NIP_ADDR_UNKNOWN, 44}; 45 46#define NIP_TRUE 1 47#define NIP_FALSE 0 48 49/* Short address range: 50 * 【1-byte】0 ~ 220 51 * 00 ~ DC 52 */ 53static inline int is_1byte_addr_flag(unsigned char first_byte) 54{ 55 return first_byte <= ADDR_FIRST_DC ? NIP_TRUE : NIP_FALSE; 56} 57 58/* Short address range: 59 * 【2-byte】221 ~ 5119 60 * DD/DE/.../F0 is a 2-byte address descriptor followed by the address value 61 * DDDD ~ DDFF : 221 ~ 255 62 * DE00 ~ DEFF : 256 ~ 511 63 * DF00 ~ DFFF : 512 ~ 767 64 * ... 65 * F000 ~ F0FF : 4864 ~ 5119 66 */ 67static inline int is_2byte_addr_flag(unsigned char first_byte) 68{ 69 return (first_byte > ADDR_FIRST_DC) && (first_byte <= ADDR_FIRST_F0) ? 70 NIP_TRUE : NIP_FALSE; 71} 72 73/* Short address range: 74 * 【3-byte】5120 ~ 65535 75 * F1 is a 3-byte address descriptor followed by the address value 76 * F1 1400 ~ F1 FFFF 77 */ 78static inline int is_3byte_addr_flag(unsigned char first_byte) 79{ 80 return first_byte == ADDR_FIRST_F1 ? NIP_TRUE : NIP_FALSE; 81} 82 83/* Short address range: 84 * 【5-byte】65536 ~ 4,294,967,295 85 * F2 is a 5-byte address descriptor followed by the address value 86 * F2 0001 0000 ~ F2 FFFF FFFF 87 */ 88static inline int is_5byte_addr_flag(unsigned char first_byte) 89{ 90 return first_byte == ADDR_FIRST_F2 ? NIP_TRUE : NIP_FALSE; 91} 92 93/* Short address range: 94 * 【7-byte】4,294,967,296 ~ 281,474,976,710,655 95 * F3 is a 7-byte address descriptor followed by the address value 96 * F3 0001 0000 0000 ~ F3 FFFF FFFF FFFF 97 */ 98static inline int is_7byte_addr_flag(unsigned char first_byte) 99{ 100 return first_byte == ADDR_FIRST_F3 ? NIP_TRUE : NIP_FALSE; 101} 102 103/* Short address range: 104 * 【8-byte】 105 * F4 is a 8-byte address descriptor followed by the address value 106 * F400 0000 0000 0000 ~ F4FF FFFF FFFF FFFF 107 */ 108static inline int is_8byte_addr_flag(unsigned char first_byte) 109{ 110 return first_byte == ADDR_FIRST_FE ? NIP_TRUE : NIP_FALSE; 111} 112 113/* Short address range: 114 * 【public addr】 115 * 0xFF00 - The loopback address 116 * 0xFF01 - Public address for access authentication 117 * 0xFF02 - Public address of access authentication 118 * 0xFF03 - The neighbor found a public address 119 * 0xFF04 - Address resolution (ARP) 120 * 0xFF05 - DHCP public address 121 * 0xFF06 - Public address for minimalist access authentication 122 * 0xFF07 - Self-organizing protocol public address 123 * 0xFF08 - The IEEE EUI - 64 addresses 124 * 0xFF09 - any_addr 125 */ 126static inline int is_public_addr_flag(unsigned char first_byte) 127{ 128 return first_byte == ADDR_FIRST_FF ? NIP_TRUE : NIP_FALSE; 129} 130 131int is_nip_local_addr(const struct nip_addr *addr) 132{ 133 int result = 0; 134 135 if (addr->bitlen == NIP_ADDR_BIT_LEN_16) { 136 if (addr->NIP_ADDR_FIELD16[0] == nip_local_addr.NIP_ADDR_FIELD16[0] && 137 addr->NIP_ADDR_FIELD16[1] == nip_local_addr.NIP_ADDR_FIELD16[1]) 138 result = 1; 139 } 140 return result; 141} 142 143/* Short address range: 144 * 【1-byte】0 ~ 220 145 * 00 ~ DC 146 */ 147static int nip_addr_1byte_check(unsigned char first_byte, unsigned char second_byte, 148 unsigned char third_byte, int addr_len) 149{ 150 int ret = NOT_CURRENT_ADDR; 151 152 if (is_1byte_addr_flag(first_byte) && addr_len == NIP_ADDR_LEN_1) 153 ret = CURRENT_ADDR_VALID; 154 155 return ret; 156} 157 158/* Short address range: 159 * 【2-byte】221 ~ 5119 160 * DD/DE/.../F0 is a 2-byte address descriptor followed by the address value 161 * DDDD ~ DDFF : 221 ~ 255 162 * DE00 ~ DEFF : 256 ~ 511 163 * DF00 ~ DFFF : 512 ~ 767 164 * ... 165 * F000 ~ F0FF : 4864 ~ 5119 166 */ 167static int nip_addr_2byte_check(unsigned char first_byte, unsigned char second_byte, 168 unsigned char third_byte, int addr_len) 169{ 170 int ret = NOT_CURRENT_ADDR; 171 172 if (is_2byte_addr_flag(first_byte) && addr_len == NIP_ADDR_LEN_2) { 173 if (first_byte > ADDR_FIRST_DC + 1 || 174 second_byte >= ADDR_SECOND_MIN_DD) 175 ret = CURRENT_ADDR_VALID; 176 else 177 ret = ADDR_2BYTE_INVALID; 178 } 179 180 return ret; 181} 182 183/* Short address range: 184 * 【3-byte】5120 ~ 65535 185 * F1 is a 3-byte address descriptor followed by the address value 186 * F1 1400 ~ F1 FFFF 187 */ 188static int nip_addr_3byte_check(unsigned char first_byte, unsigned char second_byte, 189 unsigned char third_byte, int addr_len) 190{ 191 int ret = NOT_CURRENT_ADDR; 192 193 if (is_3byte_addr_flag(first_byte) && addr_len == NIP_ADDR_LEN_3) { 194 if (second_byte >= ADDR_SECOND_MIN_F1) 195 ret = CURRENT_ADDR_VALID; 196 else 197 ret = ADDR_3BYTE_INVALID; 198 } 199 200 return ret; 201} 202 203/* Short address range: 204 * 【5-byte】65536 ~ 4,294,967,295 205 * F2 is a 5-byte address descriptor followed by the address value 206 * F2 0001 0000 ~ F2 FFFF FFFF 207 */ 208static int nip_addr_5byte_check(unsigned char first_byte, unsigned char second_byte, 209 unsigned char third_byte, int addr_len) 210{ 211 int ret = NOT_CURRENT_ADDR; 212 213 if (is_5byte_addr_flag(first_byte) && addr_len == NIP_ADDR_LEN_5) { 214 if (second_byte > 0 || third_byte >= ADDR_THIRD_MIN_F2) 215 ret = CURRENT_ADDR_VALID; 216 else 217 ret = ADDR_5BYTE_INVALID; 218 } 219 220 return ret; 221} 222 223/* Short address range: 224 * 【7-byte】4,294,967,296 ~ 281,474,976,710,655 225 * F3 is a 7-byte address descriptor followed by the address value 226 * F3 0001 0000 0000 ~ F3 FFFF FFFF FFFF 227 */ 228static int nip_addr_7byte_check(unsigned char first_byte, unsigned char second_byte, 229 unsigned char third_byte, int addr_len) 230{ 231 int ret = NOT_CURRENT_ADDR; 232 233 if (is_7byte_addr_flag(first_byte) && addr_len == NIP_ADDR_LEN_7) { 234 if (second_byte > 0 || third_byte >= ADDR_THIRD_MIN_F3) 235 ret = CURRENT_ADDR_VALID; 236 else 237 ret = ADDR_7BYTE_INVALID; 238 } 239 240 return ret; 241} 242 243/* Short address range: 244 * 【8-byte】 245 * F4 is a 8-byte address descriptor followed by the address value 246 * F400 0000 0000 0000 ~ F4FF FFFF FFFF FFFF 247 */ 248static int nip_addr_8byte_check(unsigned char first_byte, unsigned char second_byte, 249 unsigned char third_byte, int addr_len) 250{ 251 int ret = NOT_CURRENT_ADDR; 252 253 if (is_8byte_addr_flag(first_byte) && addr_len == NIP_ADDR_LEN_8) 254 ret = CURRENT_ADDR_VALID; 255 256 return ret; 257} 258 259/* Short address range: 260 * 【public addr】 261 * 0xFF00 - The loopback address 262 * 0xFF01 - Public address for access authentication 263 * 0xFF02 - Public address of access authentication 264 * 0xFF03 - The neighbor found a public address 265 * 0xFF04 - Address resolution (ARP) 266 * 0xFF05 - DHCP public address 267 * 0xFF06 - Public address for minimalist access authentication 268 * 0xFF07 - Self-organizing protocol public address 269 * 0xFF08 - The IEEE EUI - 64 addresses 270 * 0xFF09 - any_addr 271 */ 272static int nip_addr_public_check(unsigned char first_byte, unsigned char second_byte, 273 unsigned char third_byte, int addr_len) 274{ 275 int ret = NOT_CURRENT_ADDR; 276 277 if (is_public_addr_flag(first_byte) && addr_len == NIP_ADDR_LEN_2) 278 ret = CURRENT_ADDR_VALID; 279 280 return ret; 281} 282 283static int nip_addr_unknown(unsigned char first_byte, unsigned char second_byte, 284 unsigned char third_byte, int addr_len) 285{ 286 return NIP_ADDR_UNKNOWN; 287} 288 289#define CHECK_FUN_MAX 8 290static int (*nip_addr_check_fun[CHECK_FUN_MAX])(unsigned char first_byte, 291 unsigned char second_byte, 292 unsigned char third_byte, 293 int addr_len) = { 294 nip_addr_1byte_check, 295 nip_addr_2byte_check, 296 nip_addr_3byte_check, 297 nip_addr_5byte_check, 298 nip_addr_7byte_check, 299 nip_addr_8byte_check, 300 nip_addr_public_check, 301 nip_addr_unknown, 302}; 303 304int nip_addr_invalid(const struct nip_addr *addr) 305{ 306 int i; 307 int addr_len; 308 int ret = NIP_ADDR_UNKNOWN; 309 unsigned char first_byte, second_byte, third_byte; 310 311 first_byte = addr->NIP_ADDR_FIELD8[NIP_8BIT_ADDR_INDEX_0]; 312 second_byte = addr->NIP_ADDR_FIELD8[NIP_8BIT_ADDR_INDEX_1]; 313 third_byte = addr->NIP_ADDR_FIELD8[NIP_8BIT_ADDR_INDEX_2]; 314 addr_len = addr->bitlen / NIP_ADDR_BIT_LEN_8; 315 316 /* The value of the field after the effective length of the short address should be 0 */ 317 for (i = addr_len; i < NIP_8BIT_ADDR_INDEX_MAX; i++) { 318 if (addr->NIP_ADDR_FIELD8[i] > 0x00) 319 return ADDR_BITLEN_INVALID; 320 } 321 322 for (i = 0; i < CHECK_FUN_MAX; i++) { 323 ret = nip_addr_check_fun[i](first_byte, second_byte, third_byte, addr_len); 324 if (ret == CURRENT_ADDR_VALID) 325 return ret; 326 else if (ret == NOT_CURRENT_ADDR) 327 continue; 328 else 329 return ret; 330 } 331 332 return ret; 333} 334 335/* 0xFF00 - The loopback address 336 * 0xFF01 - Public address for access authentication 337 * 0xFF02 - Public address of access authentication 338 * 0xFF03 - The neighbor found a public address 339 * 0xFF04 - Address resolution (ARP) 340 * 0xFF05 - DHCP public address 341 * 0xFF06 - Public address for minimalist access authentication 342 * 0xFF07 - Self-organizing protocol public address 343 * 0xFF08 - The IEEE EUI - 64 addresses 344 * 0xFF09 - any_addr 345 */ 346int nip_addr_public(const struct nip_addr *addr) 347{ 348 if (is_public_addr_flag(addr->NIP_ADDR_FIELD8[NIP_8BIT_ADDR_INDEX_0]) && 349 addr->bitlen == NIP_ADDR_BIT_LEN_16) 350 return 1; 351 else 352 return 0; 353} 354 355/* judge whether the nip_addr is equal to 0xFF09 */ 356int nip_addr_any(const struct nip_addr *addr) 357{ 358 int result = 0; 359 360 if (addr->bitlen == NIP_ADDR_BIT_LEN_16) { 361 if (addr->NIP_ADDR_FIELD16[0] == nip_any_addr.NIP_ADDR_FIELD16[0] && 362 addr->NIP_ADDR_FIELD16[1] == nip_any_addr.NIP_ADDR_FIELD16[1]) 363 result = 1; 364 } 365 return result; 366} 367 368int get_nip_addr_len(const struct nip_addr *addr) 369{ 370 int len = 0; 371 unsigned char first_byte = addr->NIP_ADDR_FIELD8[0]; 372 373 if (is_1byte_addr_flag(first_byte)) 374 len = NIP_ADDR_LEN_1; 375 else if (is_2byte_addr_flag(first_byte) || is_public_addr_flag(first_byte)) 376 len = NIP_ADDR_LEN_2; 377 else if (is_3byte_addr_flag(first_byte)) 378 len = NIP_ADDR_LEN_3; 379 else if (is_5byte_addr_flag(first_byte)) 380 len = NIP_ADDR_LEN_5; 381 else if (is_7byte_addr_flag(first_byte)) 382 len = NIP_ADDR_LEN_7; 383 else if (is_8byte_addr_flag(first_byte)) 384 len = NIP_ADDR_LEN_8; 385 386 return len; 387} 388 389unsigned char *build_nip_addr(const struct nip_addr *addr, unsigned char *buf) 390{ 391 int i; 392 unsigned char *p = buf; 393 int addr_len = get_nip_addr_len(addr); 394 395 if (addr_len == 0) 396 return 0; 397 398 for (i = 0; i < addr_len; i++) { 399 *p = addr->NIP_ADDR_FIELD8[i]; 400 p++; 401 } 402 403 return p; 404} 405 406unsigned char *decode_nip_addr(struct nip_buff *nbuf, struct nip_addr *addr) 407{ 408 int i; 409 int ret; 410 int addr_len; 411 412 if (nbuf->remaining_len < sizeof(unsigned char)) 413 return 0; 414 415 addr->NIP_ADDR_FIELD8[0] = *nbuf->data; 416 addr_len = get_nip_addr_len(addr); 417 if (addr_len == 0) 418 return 0; 419 420 if (nbuf->remaining_len < addr_len) 421 return 0; 422 423 for (i = 0; i < addr_len; i++) { 424 addr->NIP_ADDR_FIELD8[i] = *nbuf->data; 425 nip_buff_pull(nbuf, sizeof(unsigned char)); 426 } 427 addr->bitlen = addr_len * NIP_ADDR_BIT_LEN_8; 428 429 ret = nip_addr_invalid(addr); 430 if (ret) 431 return 0; 432 433 return nbuf->data; 434} 435 436