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