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