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 
12 /**************************************************************************/
13 /**************************************************************************/
14 /**                                                                       */
15 /** NetX Component                                                        */
16 /**                                                                       */
17 /**   Internet Protocol (IP)                                              */
18 /**                                                                       */
19 /**************************************************************************/
20 /**************************************************************************/
21 
22 #define NX_SOURCE_CODE
23 
24 
25 /* Include necessary system files.  */
26 
27 #include "nx_api.h"
28 #include "nx_ip.h"
29 #include "nx_packet.h"
30 
31 
32 /**************************************************************************/
33 /*                                                                        */
34 /*  FUNCTION                                               RELEASE        */
35 /*                                                                        */
36 /*    _nx_ip_packet_receive                               PORTABLE C      */
37 /*                                                           6.1.8        */
38 /*  AUTHOR                                                                */
39 /*                                                                        */
40 /*    Yuxin Zhou, Microsoft Corporation                                   */
41 /*                                                                        */
42 /*  DESCRIPTION                                                           */
43 /*                                                                        */
44 /*    This function receives a packet from the link driver (usually the   */
45 /*    link driver's input ISR) and either processes it or places it in a  */
46 /*    deferred processing queue, depending on the complexity of the       */
47 /*    packet.                                                             */
48 /*                                                                        */
49 /*  INPUT                                                                 */
50 /*                                                                        */
51 /*    ip_ptr                                Pointer to IP control block   */
52 /*    packet_ptr                            Pointer to received packet    */
53 /*                                                                        */
54 /*  OUTPUT                                                                */
55 /*                                                                        */
56 /*    None                                                                */
57 /*                                                                        */
58 /*  CALLS                                                                 */
59 /*                                                                        */
60 /*    (ipv4_packet_receive)                 Receive an IPv4 packet        */
61 /*    (ipv6_packet_receive)                 Receive an IPv6 packet        */
62 /*    _nx_packet_release                    Packet release                */
63 /*                                                                        */
64 /*  CALLED BY                                                             */
65 /*                                                                        */
66 /*    Application I/O Driver                                              */
67 /*    _nx_ip_packet_send                    IP loopback packet send       */
68 /*                                                                        */
69 /*  RELEASE HISTORY                                                       */
70 /*                                                                        */
71 /*    DATE              NAME                      DESCRIPTION             */
72 /*                                                                        */
73 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
74 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
75 /*                                            resulting in version 6.1    */
76 /*  08-02-2021     Yuxin Zhou               Modified comment(s), and      */
77 /*                                            added new ip filter,        */
78 /*                                            resulting in version 6.1.8  */
79 /*                                                                        */
80 /**************************************************************************/
_nx_ip_packet_receive(NX_IP * ip_ptr,NX_PACKET * packet_ptr)81 VOID  _nx_ip_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr)
82 {
83 
84 UCHAR ip_version;
85 UCHAR version_byte;
86 
87 
88 #ifndef NX_DISABLE_IP_INFO
89     /* Increment the IP packet count.  */
90     ip_ptr -> nx_ip_total_packets_received++;
91 #endif
92 
93     /* Add debug information. */
94     NX_PACKET_DEBUG(__FILE__, __LINE__, packet_ptr);
95 
96     /* If packet_ptr -> nx_packet_interface_ptr is not set, stamp the packet with interface[0].
97        Legacy Ethernet drivers do not stamp incoming packets. */
98     if (packet_ptr -> nx_packet_address.nx_packet_interface_ptr == NX_NULL)
99     {
100         packet_ptr -> nx_packet_address.nx_packet_interface_ptr = &(ip_ptr -> nx_ip_interface[0]);
101     }
102 
103     /* It's assumed that the IP link driver has positioned the top pointer in the
104        packet to the start of the IP address... so that's where we will start.  */
105     version_byte =  *(packet_ptr -> nx_packet_prepend_ptr);
106 
107     /* Check the version number */
108     ip_version = (version_byte >> 4);
109 
110     packet_ptr -> nx_packet_ip_version = ip_version;
111 
112     packet_ptr -> nx_packet_ip_header = packet_ptr -> nx_packet_prepend_ptr;
113 
114 #ifdef NX_ENABLE_IP_PACKET_FILTER
115     /* Check if the IP packet filter is set. */
116     if (ip_ptr -> nx_ip_packet_filter)
117     {
118 
119         /* Yes, call the IP packet filter routine. */
120         if (ip_ptr -> nx_ip_packet_filter((VOID *)(packet_ptr -> nx_packet_prepend_ptr),
121                                           NX_IP_PACKET_IN) != NX_SUCCESS)
122         {
123 
124             /* Drop the packet. */
125             _nx_packet_release(packet_ptr);
126             return;
127         }
128     }
129 
130     /* Check if the IP packet filter extended is set. */
131     if (ip_ptr -> nx_ip_packet_filter_extended)
132     {
133 
134         /* Yes, call the IP packet filter extended routine. */
135         if (ip_ptr -> nx_ip_packet_filter_extended(ip_ptr, packet_ptr, NX_IP_PACKET_IN) != NX_SUCCESS)
136         {
137 
138             /* Drop the packet. */
139             _nx_packet_release(packet_ptr);
140             return;
141         }
142     }
143 #endif /* NX_ENABLE_IP_PACKET_FILTER */
144 
145 #ifndef NX_DISABLE_IPV4
146 
147     /* Process the packet according to IP version. */
148     if (ip_version == NX_IP_VERSION_V4 && ip_ptr -> nx_ipv4_packet_receive)
149     {
150 
151         /* Call the IPv4 packet handler. */
152         (ip_ptr -> nx_ipv4_packet_receive)(ip_ptr, packet_ptr);
153         return;
154     }
155 #endif /* !NX_DISABLE_IPV4  */
156 
157 #ifdef FEATURE_NX_IPV6
158     if (ip_version == NX_IP_VERSION_V6 && ip_ptr -> nx_ipv6_packet_receive)
159     {
160 
161         /* Call the IPv6 packet handler. */
162         (ip_ptr -> nx_ipv6_packet_receive)(ip_ptr, packet_ptr);
163         return;
164     }
165 #endif /* FEATURE_NX_IPV6 */
166 
167     /* Either the ip_version number is unkonwn, or the ip_packet_receive function is
168         not defined.  In this case, the packet is reclaimed. */
169 
170 #ifndef NX_DISABLE_IP_INFO
171 
172     /* Increment the IP invalid packet error.  */
173     ip_ptr -> nx_ip_invalid_packets++;
174 
175     /* Increment the IP receive packets dropped count.  */
176     ip_ptr -> nx_ip_receive_packets_dropped++;
177 #endif
178 
179     _nx_packet_release(packet_ptr);
180 
181     return;
182 }
183 
184