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