• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
17 const 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 
23 const 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 
29 static 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 
35 enum 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  */
is_1byte_addr_flag(unsigned char first_byte)53 static 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  */
is_2byte_addr_flag(unsigned char first_byte)67 static 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  */
is_3byte_addr_flag(unsigned char first_byte)78 static 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  */
is_5byte_addr_flag(unsigned char first_byte)88 static 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  */
is_7byte_addr_flag(unsigned char first_byte)98 static 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  */
is_8byte_addr_flag(unsigned char first_byte)108 static 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  */
is_public_addr_flag(unsigned char first_byte)126 static inline int is_public_addr_flag(unsigned char first_byte)
127 {
128 	return first_byte == ADDR_FIRST_FF ? NIP_TRUE : NIP_FALSE;
129 }
130 
is_nip_local_addr(const struct nip_addr * addr)131 int 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  */
nip_addr_1byte_check(unsigned char first_byte,unsigned char second_byte,unsigned char third_byte,int addr_len)147 static 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  */
nip_addr_2byte_check(unsigned char first_byte,unsigned char second_byte,unsigned char third_byte,int addr_len)167 static 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  */
nip_addr_3byte_check(unsigned char first_byte,unsigned char second_byte,unsigned char third_byte,int addr_len)188 static 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  */
nip_addr_5byte_check(unsigned char first_byte,unsigned char second_byte,unsigned char third_byte,int addr_len)208 static 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  */
nip_addr_7byte_check(unsigned char first_byte,unsigned char second_byte,unsigned char third_byte,int addr_len)228 static 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  */
nip_addr_8byte_check(unsigned char first_byte,unsigned char second_byte,unsigned char third_byte,int addr_len)248 static 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  */
nip_addr_public_check(unsigned char first_byte,unsigned char second_byte,unsigned char third_byte,int addr_len)272 static 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 
nip_addr_unknown(unsigned char first_byte,unsigned char second_byte,unsigned char third_byte,int addr_len)283 static 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
290 static 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 
nip_addr_invalid(const struct nip_addr * addr)304 int 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  */
nip_addr_public(const struct nip_addr * addr)346 int 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 */
nip_addr_any(const struct nip_addr * addr)356 int 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 
get_nip_addr_len(const struct nip_addr * addr)368 int 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 
build_nip_addr(const struct nip_addr * addr,unsigned char * buf)389 unsigned 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 
decode_nip_addr(struct nip_buff * nbuf,struct nip_addr * addr)406 unsigned 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