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