1 /***************************************************************************
2 * Copyright (c) 2024 Microsoft Corporation
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the MIT License which is available at
6 * https://opensource.org/licenses/MIT.
7 *
8 * SPDX-License-Identifier: MIT
9 **************************************************************************/
10
11 #define NX_SOURCE_CODE
12
13 #include "tx_api.h"
14 #include "nx_api.h"
15 #include "nx_ipv6.h"
16
17
18 /**************************************************************************/
19 /* */
20 /* FUNCTION RELEASE */
21 /* */
22 /* CHECK_IP_ADDRESSES_BY_PREFIX PORTABLE C */
23 /* 6.1 */
24 /* AUTHOR */
25 /* */
26 /* Yuxin Zhou, Microsoft Corporation */
27 /* */
28 /* DESCRIPTION */
29 /* */
30 /* This function checks whether or not two IPv6 addresses are the */
31 /* same by prefix length */
32 /* */
33 /* INPUT */
34 /* */
35 /* ip_addr1 Two 128-bit IPv6 addresses to */
36 /* ip_addr2 be checked. */
37 /* prefix_len Prefix length */
38 /* */
39 /* */
40 /* OUTPUT */
41 /* */
42 /* 0 The addresses are different. */
43 /* 1 The addresses are the same. */
44 /* */
45 /* CALLS */
46 /* */
47 /* NONE */
48 /* */
49 /* CALLED BY */
50 /* */
51 /* NetX Source Code */
52 /* */
53 /* RELEASE HISTORY */
54 /* */
55 /* DATE NAME DESCRIPTION */
56 /* */
57 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
58 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
59 /* resulting in version 6.1 */
60 /* */
61 /**************************************************************************/
CHECK_IP_ADDRESSES_BY_PREFIX(ULONG * ip_addr1,ULONG * ip_addr2,ULONG prefix_len)62 INT CHECK_IP_ADDRESSES_BY_PREFIX(ULONG *ip_addr1, ULONG *ip_addr2,
63 ULONG prefix_len)
64 {
65
66
67 ULONG high_prefix; /* Num of ULONG in prefix. */
68 ULONG low_prefix; /* Remaining bits in prefix after high prefix. */
69 ULONG mask;
70
71
72 /* Get number of ULONGs that can fit in the specified prefix length. */
73 high_prefix = prefix_len >> 5;
74
75 /* Get the remaining bits in prefix length. */
76 low_prefix = prefix_len & 0x1f;
77
78 /* Would the prefix length have 1 or more ULONGs? */
79 if (high_prefix)
80 {
81
82 /* Yes; compare that number of ULONGS (in bytes) in each input address. */
83 if (memcmp(ip_addr1, ip_addr2, high_prefix << 2))
84 {
85 /* A nonzero result indicates a mismatch. */
86 return(0);
87 }
88 }
89
90 /* Are there any bits to compare after the high order bits? */
91 if (low_prefix)
92 {
93
94 /* Compare these bits between the two addresses, after masking out the upper ULONGs. */
95 mask = ((0xFFFFFFFF) << (32 - low_prefix)) & 0xFFFFFFFF;
96
97 if ((ip_addr1[high_prefix] ^ ip_addr2[high_prefix]) & mask)
98 {
99 return(0);
100 }
101 }
102
103 return(1);
104 }
105
106
107
108 /*
109 * Developers may define "NX_IPV6_UTIL_INLINE to make the following functions
110 * inline. Inline functions improve execution speed. However they make
111 * code size larger.
112 */
113
114 #ifndef NX_IPV6_UTIL_INLINE
115 /**************************************************************************/
116 /* */
117 /* FUNCTION RELEASE */
118 /* */
119 /* CHECK_IPV6_ADDRESSES_SAME PORTABLE C */
120 /* 6.1 */
121 /* AUTHOR */
122 /* */
123 /* Yuxin Zhou, Microsoft Corporation */
124 /* */
125 /* DESCRIPTION */
126 /* */
127 /* This function checks whether or not two IPv6 addresses are the */
128 /* same. */
129 /* */
130 /* INPUT */
131 /* */
132 /* ip_addr1 Two 128-bit IPv6 addresses to */
133 /* ip_addr2 be checked. */
134 /* */
135 /* */
136 /* OUTPUT */
137 /* */
138 /* 0 The addresses are different. */
139 /* 1 The addresses are the same. */
140 /* */
141 /* CALLS */
142 /* */
143 /* NONE */
144 /* */
145 /* CALLED BY */
146 /* */
147 /* NetX Source Code */
148 /* */
149 /* RELEASE HISTORY */
150 /* */
151 /* DATE NAME DESCRIPTION */
152 /* */
153 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
154 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
155 /* resulting in version 6.1 */
156 /* */
157 /**************************************************************************/
CHECK_IPV6_ADDRESSES_SAME(ULONG * ip_addr1,ULONG * ip_addr2)158 INT CHECK_IPV6_ADDRESSES_SAME(ULONG *ip_addr1, ULONG *ip_addr2)
159 {
160 #ifdef FEATURE_NX_IPV6
161 return(ip_addr1[0] == ip_addr2[0] &&
162 ip_addr1[1] == ip_addr2[1] &&
163 ip_addr1[2] == ip_addr2[2] &&
164 ip_addr1[3] == ip_addr2[3]);
165 #else /* FEATURE_NX_IPV6 */
166 NX_PARAMETER_NOT_USED(ip_addr1);
167 NX_PARAMETER_NOT_USED(ip_addr2);
168
169 return(0);
170 #endif /* FEATURE_NX_IPV6 */
171 }
172
173 #ifdef NX_IPSEC_ENABLE
174 /**************************************************************************/
175 /* */
176 /* FUNCTION RELEASE */
177 /* */
178 /* CHECK_IPV6_ADDRESS_RANGE PORTABLE C */
179 /* 6.1 */
180 /* AUTHOR */
181 /* */
182 /* Yuxin Zhou, Microsoft Corporation */
183 /* */
184 /* DESCRIPTION */
185 /* */
186 /* This function checks the IPv6 address whether or not between */
187 /* two IPv6 addresses. */
188 /* */
189 /* INPUT */
190 /* */
191 /* ip_addr_start IPv6 address start */
192 /* ip_addr_end Ipv6 address end */
193 /* ip_addr The 128-bit IPv6 address to. */
194 /* be checked */
195 /* */
196 /* OUTPUT */
197 /* */
198 /* 0 Not between two IPv6 address. */
199 /* 1 Between two IPv6 address. */
200 /* */
201 /* CALLS */
202 /* */
203 /* NONE */
204 /* */
205 /* CALLED BY */
206 /* */
207 /* NetX Source Code */
208 /* */
209 /* RELEASE HISTORY */
210 /* */
211 /* DATE NAME DESCRIPTION */
212 /* */
213 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
214 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
215 /* resulting in version 6.1 */
216 /* */
217 /**************************************************************************/
CHECK_IPV6_ADDRESS_RANGE(ULONG * ip_addr_start,ULONG * ip_addr_end,ULONG * ip_addr)218 INT CHECK_IPV6_ADDRESS_RANGE(ULONG *ip_addr_start, ULONG *ip_addr_end, ULONG *ip_addr)
219 {
220 #ifdef FEATURE_NX_IPV6
221 INT ip_addr_cmp1 = 0, ip_addr_cmp2 = 0;
222
223 /* Check the IP address whether or not bigger than IP address start. */
224 /* compare the first 32 bit. */
225 if (ip_addr_start[0] < ip_addr[0])
226 {
227 ip_addr_cmp1 = 1;
228 }
229 else if (ip_addr_start[0] == ip_addr[0])
230 {
231
232 /* compare the second 32 bit. */
233 if (ip_addr_start[1] < ip_addr[1])
234 {
235 ip_addr_cmp1 = 1;
236 }
237 else if (ip_addr_start[1] == ip_addr[1])
238 {
239 /* compare the third 32 bit. */
240 if (ip_addr_start[2] < ip_addr[2])
241 {
242 ip_addr_cmp1 = 1;
243 }
244 else if (ip_addr_start[2] == ip_addr[2])
245 {
246 /* compare the forth 32 bit. */
247 if (ip_addr_start[3] <= ip_addr[3])
248 {
249 ip_addr_cmp1 = 1;
250 }
251 }
252 }
253 }
254
255 /* Check the IP address whether or not smaller than IP address end. */
256 /* compare the first 32 bit. */
257 if (ip_addr[0] < ip_addr_end[0])
258 {
259 ip_addr_cmp2 = 1;
260 }
261 else if (ip_addr[0] == ip_addr_end[0])
262 {
263 /* compare the second 32 bit. */
264 if (ip_addr[1] < ip_addr_end[1])
265 {
266 ip_addr_cmp2 = 1;
267 }
268 else if (ip_addr[1] == ip_addr_end[1])
269 {
270 /* compare the second 32 bit. */
271 if (ip_addr[2] < ip_addr_end[2])
272 {
273 ip_addr_cmp2 = 1;
274 }
275 else if (ip_addr[2] == ip_addr_end[2])
276 {
277 /* compare the second 32 bit. */
278 if (ip_addr[3] <= ip_addr_end[3])
279 {
280 ip_addr_cmp2 = 1;
281 }
282 }
283 }
284 }
285 if ((ip_addr_cmp1 == 1) && (ip_addr_cmp2 == 1))
286 {
287 return(1);
288 }
289 else
290 {
291 return(0);
292 }
293 #else /* FEATURE_NX_IPV6 */
294 NX_PARAMETER_NOT_USED(ip_addr_start);
295 NX_PARAMETER_NOT_USED(ip_addr_end);
296 NX_PARAMETER_NOT_USED(ip_addr);
297
298 return(0);
299 #endif /* FEATURE_NX_IPV6 */
300 }
301 #endif /* NX_IPSEC_ENABLE */
302
303
304 /**************************************************************************/
305 /* */
306 /* FUNCTION RELEASE */
307 /* */
308 /* CHECK_UNSPECIFIED_ADDRESS PORTABLE C */
309 /* 6.1 */
310 /* AUTHOR */
311 /* */
312 /* Yuxin Zhou, Microsoft Corporation */
313 /* */
314 /* DESCRIPTION */
315 /* */
316 /* This function checks whether or not an address is unspecified (::) */
317 /* */
318 /* INPUT */
319 /* */
320 /* ip_address The 128-bit IPv6 address to */
321 /* be checked. The address is */
322 /* in host byte order. */
323 /* */
324 /* */
325 /* OUTPUT */
326 /* */
327 /* status 0:The address is not zero */
328 /* 1:The address is unspecified */
329 /* */
330 /* CALLS */
331 /* */
332 /* NONE */
333 /* */
334 /* CALLED BY */
335 /* */
336 /* NetX Source Code */
337 /* */
338 /* RELEASE HISTORY */
339 /* */
340 /* DATE NAME DESCRIPTION */
341 /* */
342 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
343 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
344 /* resulting in version 6.1 */
345 /* */
346 /**************************************************************************/
CHECK_UNSPECIFIED_ADDRESS(ULONG * ip_addr)347 INT CHECK_UNSPECIFIED_ADDRESS(ULONG *ip_addr)
348 {
349 #ifdef FEATURE_NX_IPV6
350 return(!(ip_addr[0] || ip_addr[1] || ip_addr[2] || ip_addr[3]));
351 #else
352 NX_PARAMETER_NOT_USED(ip_addr);
353 return(0);
354 #endif
355 }
356
357
358 /**************************************************************************/
359 /* */
360 /* FUNCTION RELEASE */
361 /* */
362 /* SET_UNSPECIFIED_ADDRESS PORTABLE C */
363 /* 6.1 */
364 /* AUTHOR */
365 /* */
366 /* Yuxin Zhou, Microsoft Corporation */
367 /* */
368 /* DESCRIPTION */
369 /* */
370 /* This function marks an IPv6 address as unnspecified (::). */
371 /* */
372 /* INPUT */
373 /* */
374 /* ip_address The 128-bit IPv6 address to */
375 /* be set. */
376 /* */
377 /* OUTPUT */
378 /* */
379 /* NONE */
380 /* */
381 /* CALLS */
382 /* */
383 /* NONE */
384 /* */
385 /* CALLED BY */
386 /* */
387 /* NetX Source Code */
388 /* */
389 /* RELEASE HISTORY */
390 /* */
391 /* DATE NAME DESCRIPTION */
392 /* */
393 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
394 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
395 /* resulting in version 6.1 */
396 /* */
397 /**************************************************************************/
SET_UNSPECIFIED_ADDRESS(ULONG * ip_addr)398 void SET_UNSPECIFIED_ADDRESS(ULONG *ip_addr)
399 {
400 #ifdef FEATURE_NX_IPV6
401 ip_addr[0] = 0;
402 ip_addr[1] = 0;
403 ip_addr[2] = 0;
404 ip_addr[3] = 0;
405 #else
406 NX_PARAMETER_NOT_USED(ip_addr);
407 #endif /* FEATURE_NX_IPV6 */
408 }
409
410 /**************************************************************************/
411 /* */
412 /* FUNCTION RELEASE */
413 /* */
414 /* COPY_IPV6_ADDRESS PORTABLE C */
415 /* 6.1 */
416 /* AUTHOR */
417 /* */
418 /* Yuxin Zhou, Microsoft Corporation */
419 /* */
420 /* DESCRIPTION */
421 /* */
422 /* This function makes a copy of an IPv6 address. */
423 /* */
424 /* INPUT */
425 /* */
426 /* copy_from The 128-bit IPv6 address to */
427 /* be copied. */
428 /* copy_to The 128-bit IPv6 address to */
429 /* be filled in. */
430 /* */
431 /* */
432 /* OUTPUT */
433 /* */
434 /* NONE */
435 /* */
436 /* CALLS */
437 /* */
438 /* NONE */
439 /* */
440 /* CALLED BY */
441 /* */
442 /* NetX Source Code */
443 /* */
444 /* RELEASE HISTORY */
445 /* */
446 /* DATE NAME DESCRIPTION */
447 /* */
448 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
449 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
450 /* resulting in version 6.1 */
451 /* */
452 /**************************************************************************/
COPY_IPV6_ADDRESS(ULONG * copy_from,ULONG * copy_to)453 void COPY_IPV6_ADDRESS(ULONG *copy_from, ULONG *copy_to)
454 {
455 #ifdef FEATURE_NX_IPV6
456 copy_to[0] = copy_from[0];
457 copy_to[1] = copy_from[1];
458 copy_to[2] = copy_from[2];
459 copy_to[3] = copy_from[3];
460 #else
461 NX_PARAMETER_NOT_USED(copy_from);
462 NX_PARAMETER_NOT_USED(copy_to);
463 #endif /* FEATURE_NX_IPV6 */
464 }
465
466 /**************************************************************************/
467 /* */
468 /* FUNCTION RELEASE */
469 /* */
470 /* COPY_NXD_ADDRESS PORTABLE C */
471 /* 6.1 */
472 /* AUTHOR */
473 /* */
474 /* Yuxin Zhou, Microsoft Corporation */
475 /* */
476 /* DESCRIPTION */
477 /* */
478 /* This function makes a copy of an IP address from one NXD_ADDRESS */
479 /* data to another NXD_ADDRESS, including the version. Note that */
480 /* filling in the nxd_ip_address.v6[0] address also suffices for */
481 /* filling in the nxd_ip_address.v4 IP address field if the input */
482 /* NXD_ADDRESS argument is for an IPv4 address. */
483 /* */
484 /* INPUT */
485 /* */
486 /* copy_from The NXD address control block */
487 /* to be copied. */
488 /* copy_to The NXD address control block */
489 /* to copy to. */
490 /* */
491 /* */
492 /* OUTPUT */
493 /* */
494 /* NONE */
495 /* */
496 /* CALLS */
497 /* */
498 /* NONE */
499 /* */
500 /* CALLED BY */
501 /* */
502 /* NetX Source Code */
503 /* */
504 /* RELEASE HISTORY */
505 /* */
506 /* DATE NAME DESCRIPTION */
507 /* */
508 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
509 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
510 /* resulting in version 6.1 */
511 /* */
512 /**************************************************************************/
513
COPY_NXD_ADDRESS(NXD_ADDRESS * copy_from,NXD_ADDRESS * copy_to)514 void COPY_NXD_ADDRESS(NXD_ADDRESS *copy_from, NXD_ADDRESS *copy_to)
515 {
516 #ifdef FEATURE_NX_IPV6
517 copy_to -> nxd_ip_version = copy_from -> nxd_ip_version;
518 copy_to -> nxd_ip_address.v6[0] = copy_from -> nxd_ip_address.v6[0];
519 copy_to -> nxd_ip_address.v6[1] = copy_from -> nxd_ip_address.v6[1];
520 copy_to -> nxd_ip_address.v6[2] = copy_from -> nxd_ip_address.v6[2];
521 copy_to -> nxd_ip_address.v6[3] = copy_from -> nxd_ip_address.v6[3];
522 #else
523 NX_PARAMETER_NOT_USED(copy_from);
524 NX_PARAMETER_NOT_USED(copy_to);
525 #endif /* FEATURE_NX_IPV6 */
526 }
527
528 /**************************************************************************/
529 /* */
530 /* FUNCTION RELEASE */
531 /* */
532 /* SET_SOLICITED_NODE_MULTICAST_ADDRESS PORTABLE C */
533 /* 6.1 */
534 /* AUTHOR */
535 /* */
536 /* Yuxin Zhou, Microsoft Corporation */
537 /* */
538 /* DESCRIPTION */
539 /* */
540 /* This function sets the solicited-node multicast address based on */
541 /* a unicast IPv6 address. */
542 /* */
543 /* INPUT */
544 /* */
545 /* address Storage space of an IPv6 */
546 /* solicited-node multicast */
547 /* address to be created. */
548 /* unicast_address The unicast address to use */
549 /* when creating the solicited- */
550 /* node multicast address. */
551 /* */
552 /* */
553 /* OUTPUT */
554 /* */
555 /* NONE */
556 /* */
557 /* CALLS */
558 /* */
559 /* NONE */
560 /* */
561 /* CALLED BY */
562 /* */
563 /* NetX Source Code */
564 /* */
565 /* RELEASE HISTORY */
566 /* */
567 /* DATE NAME DESCRIPTION */
568 /* */
569 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
570 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
571 /* resulting in version 6.1 */
572 /* */
573 /**************************************************************************/
SET_SOLICITED_NODE_MULTICAST_ADDRESS(ULONG * address,ULONG * unicast_address)574 void SET_SOLICITED_NODE_MULTICAST_ADDRESS(ULONG *address,
575 ULONG *unicast_address)
576 {
577 #ifdef FEATURE_NX_IPV6
578 address[0] = (ULONG)0xFF020000;
579 address[1] = (ULONG)0;
580 address[2] = (ULONG)0x00000001;
581 address[3] = (ULONG)(0xFF000000 | unicast_address[3]);
582 #else
583 NX_PARAMETER_NOT_USED(address);
584 NX_PARAMETER_NOT_USED(unicast_address);
585 #endif /* FEATURE_NX_IPV6 */
586 }
587
588 /**************************************************************************/
589 /* */
590 /* FUNCTION RELEASE */
591 /* */
592 /* CHECK_ALL_ROUTER_MCAST_ADDRESS PORTABLE C */
593 /* 6.1 */
594 /* AUTHOR */
595 /* */
596 /* Yuxin Zhou, Microsoft Corporation */
597 /* */
598 /* DESCRIPTION */
599 /* */
600 /* This function checks whether or not an address is an all-router */
601 /* multicast address. */
602 /* */
603 /* INPUT */
604 /* */
605 /* address The 128-bit IPv6 address to */
606 /* be checked. The address is */
607 /* in host byte order. */
608 /* */
609 /* */
610 /* OUTPUT */
611 /* */
612 /* 0 The address is not an all- */
613 /* router mullticast address. */
614 /* 1 The address is an all-router */
615 /* multicast address. */
616 /* CALLS */
617 /* */
618 /* NONE */
619 /* */
620 /* CALLED BY */
621 /* */
622 /* NetX Source Code */
623 /* */
624 /* RELEASE HISTORY */
625 /* */
626 /* DATE NAME DESCRIPTION */
627 /* */
628 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
629 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
630 /* resulting in version 6.1 */
631 /* */
632 /**************************************************************************/
CHECK_ALL_ROUTER_MCAST_ADDRESS(ULONG * address)633 INT CHECK_ALL_ROUTER_MCAST_ADDRESS(ULONG *address)
634 {
635 #ifdef FEATURE_NX_IPV6
636
637 return(address[0] == (ULONG)0xFF020000 &&
638 address[1] == (ULONG)0 &&
639 address[2] == (ULONG)0 &&
640 address[3] == (ULONG)0x00000002);
641
642 #else /* !FEATURE_NX_IPV6 */
643 NX_PARAMETER_NOT_USED(address);
644
645 return(0);
646 #endif /* FEATURE_NX_IPV6 */
647 }
648
649 #endif /* NX_IPV6_UTIL_INLINE */
650
651
652
653 /**************************************************************************/
654 /* */
655 /* FUNCTION RELEASE */
656 /* */
657 /* CHECK_IPV6_SOLICITED_NODE_MCAST_ADDRESS PORTABLE C */
658 /* 6.1 */
659 /* AUTHOR */
660 /* */
661 /* Yuxin Zhou, Microsoft Corporation */
662 /* */
663 /* DESCRIPTION */
664 /* */
665 /* This function checks whether or not an address is a solicited-node */
666 /* multicast address. */
667 /* */
668 /* INPUT */
669 /* */
670 /* dest_ip The 128-bit IPv6 address to */
671 /* be checked. The address is */
672 /* in host byte order. */
673 /* myip The 128-bit local interface */
674 /* address, in host byte order. */
675 /* */
676 /* */
677 /* OUTPUT */
678 /* */
679 /* 0 The address is not solicited- */
680 /* node multicast address. */
681 /* 1 The address is solicited-node */
682 /* multicast address. */
683 /* CALLS */
684 /* */
685 /* NONE */
686 /* */
687 /* CALLED BY */
688 /* */
689 /* NetX Source Code */
690 /* */
691 /* RELEASE HISTORY */
692 /* */
693 /* DATE NAME DESCRIPTION */
694 /* */
695 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
696 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
697 /* resulting in version 6.1 */
698 /* */
699 /**************************************************************************/
CHECK_IPV6_SOLICITED_NODE_MCAST_ADDRESS(ULONG * dest_ip,ULONG * myip)700 INT CHECK_IPV6_SOLICITED_NODE_MCAST_ADDRESS(ULONG *dest_ip, ULONG *myip)
701 {
702 #ifdef FEATURE_NX_IPV6
703
704 INT isMulticast = 0;
705
706 if ((dest_ip[0] == (ULONG)0xFF020000) && (dest_ip[1] == (ULONG)0x0) &&
707 (dest_ip[2] == (ULONG)0x00000001) &&
708 (dest_ip[3] == ((myip[3] & (ULONG)0x00FFFFFF) | (ULONG)0xFF000000)))
709 {
710 isMulticast = 1;
711 }
712 else if ((dest_ip[0] == (ULONG)0xFF020000) &&
713 (dest_ip[1] == (ULONG)0x0) &&
714 (dest_ip[2] == (ULONG)0x0) &&
715 ((dest_ip[3] == (ULONG)0x00000001) || (dest_ip[3] == (ULONG)0x00010002)))
716 {
717 isMulticast = 1;
718 }
719 #ifdef NX_ENABLE_THREAD
720 else if ((dest_ip[0] == (ULONG)0xFF030000) &&
721 (dest_ip[1] == (ULONG)0x0) &&
722 (dest_ip[2] == (ULONG)0x0) &&
723 ((dest_ip[3] == (ULONG)0x00000001))) /* Realm-Local All nodes multicast address. */
724 {
725 isMulticast = 1;
726 }
727 #endif /* NX_ENABLE_THREAD */
728 else if ((dest_ip[0] == (ULONG)0xFF050000) &&
729 (dest_ip[1] == (ULONG)0x0) &&
730 (dest_ip[2] == (ULONG)0x0) &&
731 (dest_ip[3] == (ULONG)0x00010003))
732 {
733 isMulticast = 1;
734 }
735 return(isMulticast);
736 #else
737 NX_PARAMETER_NOT_USED(dest_ip);
738 NX_PARAMETER_NOT_USED(myip);
739
740 return(0);
741 #endif /* FEATURE_NX_IPV6 */
742 }
743
744
745 /**************************************************************************/
746 /* */
747 /* FUNCTION RELEASE */
748 /* */
749 /* IPv6_Address_Type PORTABLE C */
750 /* 6.1 */
751 /* AUTHOR */
752 /* */
753 /* Yuxin Zhou, Microsoft Corporation */
754 /* */
755 /* DESCRIPTION */
756 /* */
757 /* This function checks the type of an IP address. */
758 /* */
759 /* INPUT */
760 /* */
761 /* ip_address The 128-bit IPv6 address to */
762 /* be checked. The address is */
763 /* in host byte order. */
764 /* */
765 /* */
766 /* OUTPUT */
767 /* */
768 /* Address type A bit mask indicates the */
769 /* of the IPv6 address. */
770 /* */
771 /* CALLS */
772 /* */
773 /* NONE */
774 /* */
775 /* CALLED BY */
776 /* */
777 /* NetX Source Code */
778 /* */
779 /* RELEASE HISTORY */
780 /* */
781 /* DATE NAME DESCRIPTION */
782 /* */
783 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
784 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
785 /* resulting in version 6.1 */
786 /* */
787 /**************************************************************************/
IPv6_Address_Type(ULONG * ip_address)788 ULONG IPv6_Address_Type(ULONG *ip_address)
789 {
790
791 #ifdef FEATURE_NX_IPV6
792 ULONG ret;
793
794 /* Validate address type.
795 ::/128 Unspecified address
796 ::1/128 Loopback
797 FF00::/8 Multicast
798 FE80::/10 Link-local
799 FEC0::/10 Global (Its use as Site-local has been deprecated (RFC 4291)
800 Everything else Global
801 */
802 ULONG tmp;
803
804 /* Is this multicast? */
805 if ((ip_address[0] & (ULONG)0xFF000000) == (ULONG)0xFF000000)
806 {
807 /* Yes. */
808 ret = IPV6_ADDRESS_MULTICAST;
809
810 /* Determine type of multicast... */
811 if (((ip_address[0] == (ULONG)0xFF010000) ||
812 (ip_address[0] == (ULONG)0xFF020000)) &&
813 (ip_address[1] == (ULONG)0) &&
814 (ip_address[2] == (ULONG)0) &&
815 (ip_address[3] == (ULONG)1))
816 {
817 return(ret | IPV6_ALL_NODE_MCAST);
818 }
819
820
821 if ((ip_address[0] == (ULONG)0xFF050000) && /* All DHCPv6 relay and server hosts */
822 (ip_address[1] == (ULONG)0) &&
823 (ip_address[2] == (ULONG)0) &&
824 (ip_address[3] == (ULONG)0x00010003))
825 {
826 return(ret | IPV6_ALL_NODE_MCAST);
827 }
828
829 if (((ip_address[0] == (ULONG)0xFF010000) ||
830 (ip_address[0] == (ULONG)0xFF020000) ||
831 (ip_address[0] == (ULONG)0xFF050000)) &&
832 (ip_address[1] == (ULONG)0) &&
833 (ip_address[2] == (ULONG)0) &&
834 (ip_address[3] == (ULONG)2))
835 {
836 return(ret | IPV6_ALL_ROUTER_MCAST);
837 }
838
839 if ((ip_address[0] == (ULONG)0xFF020000) &&
840 (ip_address[1] == (ULONG)0) &&
841 (ip_address[2] == (ULONG)1) &&
842 (ip_address[3] >= (ULONG)0xFF000000))
843 {
844 return(ret | IPV6_SOLICITED_NODE_MCAST);
845 }
846
847 return(IPV6_ADDRESS_MULTICAST);
848 }
849
850 tmp = ip_address[0] & (0xFFC00000);
851
852 if (tmp == (ULONG)0xFE800000)
853 {
854 return((ULONG)(IPV6_ADDRESS_UNICAST | IPV6_ADDRESS_LINKLOCAL));
855 }
856 /* Note that site local are deprecated in RFC 4291 and are
857 treated as global type address. */
858 if (tmp == (ULONG)0xFEC00000)
859 {
860 return((ULONG)(IPV6_ADDRESS_UNICAST | IPV6_ADDRESS_GLOBAL));
861 }
862
863 tmp = ip_address[0] | ip_address[1] | ip_address[2];
864
865 if (tmp == 0)
866 {
867 if (ip_address[3] == 0)
868 {
869 return(IPV6_ADDRESS_UNSPECIFIED);
870 }
871
872 if (ip_address[3] == 1)
873 {
874 return(IPV6_ADDRESS_LOOPBACK);
875 }
876 }
877
878 return((ULONG)(IPV6_ADDRESS_UNICAST | IPV6_ADDRESS_GLOBAL));
879 #else /* FEATURE_NX_IPV6 */
880 NX_PARAMETER_NOT_USED(ip_address);
881
882 return(0);
883 #endif /* FEATURE_NX_IPV6 */
884 }
885
886 #ifdef NX_LITTLE_ENDIAN
887 /**************************************************************************/
888 /* */
889 /* FUNCTION RELEASE */
890 /* */
891 /* _nx_ipv6_address_change_endian PORTABLE C */
892 /* 6.1 */
893 /* AUTHOR */
894 /* */
895 /* Yuxin Zhou, Microsoft Corporation */
896 /* */
897 /* DESCRIPTION */
898 /* */
899 /* This function only applies to little endian hosts. It performs */
900 /* byte swaps on an IPv6 address. */
901 /* */
902 /* INPUT */
903 /* */
904 /* address The 128-bit IPv6 address to be */
905 /* swapped. */
906 /* */
907 /* */
908 /* OUTPUT */
909 /* */
910 /* NONE */
911 /* */
912 /* CALLS */
913 /* */
914 /* NONE */
915 /* */
916 /* CALLED BY */
917 /* */
918 /* NetX Source Code */
919 /* */
920 /* RELEASE HISTORY */
921 /* */
922 /* DATE NAME DESCRIPTION */
923 /* */
924 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
925 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
926 /* resulting in version 6.1 */
927 /* */
928 /**************************************************************************/
_nx_ipv6_address_change_endian(ULONG * address)929 VOID _nx_ipv6_address_change_endian(ULONG *address)
930 {
931 #ifdef FEATURE_NX_IPV6
932 if (address == NX_NULL)
933 {
934 return;
935 }
936
937 NX_CHANGE_ULONG_ENDIAN(address[0]);
938 NX_CHANGE_ULONG_ENDIAN(address[1]);
939 NX_CHANGE_ULONG_ENDIAN(address[2]);
940 NX_CHANGE_ULONG_ENDIAN(address[3]);
941 #else
942 NX_PARAMETER_NOT_USED(address);
943 #endif /* FEATURE_NX_IPV6 */
944 }
945
946 #endif /* NX_LITTLE_ENDIAN */
947
948