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 
13 /**************************************************************************/
14 /**************************************************************************/
15 /**                                                                       */
16 /** NetX Component                                                        */
17 /**                                                                       */
18 /**   Internet Group Management Protocol (IGMP)                           */
19 /**                                                                       */
20 /**************************************************************************/
21 /**************************************************************************/
22 
23 #define NX_SOURCE_CODE
24 
25 
26 /* Include necessary system files.  */
27 
28 #include "nx_api.h"
29 #include "nx_packet.h"
30 #include "nx_igmp.h"
31 #include "nx_ip.h"
32 #include "tx_thread.h"
33 
34 
35 #ifndef NX_DISABLE_IPV4
36 /**************************************************************************/
37 /*                                                                        */
38 /*  FUNCTION                                               RELEASE        */
39 /*                                                                        */
40 /*    _nx_igmp_packet_receive                             PORTABLE C      */
41 /*                                                           6.1          */
42 /*  AUTHOR                                                                */
43 /*                                                                        */
44 /*    Yuxin Zhou, Microsoft Corporation                                   */
45 /*                                                                        */
46 /*  DESCRIPTION                                                           */
47 /*                                                                        */
48 /*    This function handles reception of IGMP packets on the "all hosts"  */
49 /*    multicast address.  If this routine is called from an ISR, the      */
50 /*    IGMP packet is queued.  Otherwise, if this routine is called from   */
51 /*    the IP helper thread, the processing of the IGMP packet is called   */
52 /*    directly.                                                           */
53 /*                                                                        */
54 /*  INPUT                                                                 */
55 /*                                                                        */
56 /*    ip_ptr                                IP instance pointer           */
57 /*    packet_ptr                            IGMP packet pointer           */
58 /*                                                                        */
59 /*  OUTPUT                                                                */
60 /*                                                                        */
61 /*    None                                                                */
62 /*                                                                        */
63 /*  CALLS                                                                 */
64 /*                                                                        */
65 /*    _nx_igmp_packet_process               Process the IGMP packet       */
66 /*    tx_event_flags_set                    Set event flags for IP helper */
67 /*                                            thread                      */
68 /*                                                                        */
69 /*  CALLED BY                                                             */
70 /*                                                                        */
71 /*    _nx_ip_packet_receive                 Raw IP packet receive         */
72 /*                                                                        */
73 /*  RELEASE HISTORY                                                       */
74 /*                                                                        */
75 /*    DATE              NAME                      DESCRIPTION             */
76 /*                                                                        */
77 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
78 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
79 /*                                            resulting in version 6.1    */
80 /*                                                                        */
81 /**************************************************************************/
_nx_igmp_packet_receive(NX_IP * ip_ptr,NX_PACKET * packet_ptr)82 VOID  _nx_igmp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr)
83 {
84 
85 TX_INTERRUPT_SAVE_AREA
86 
87 
88     /* Add debug information. */
89     NX_PACKET_DEBUG(__FILE__, __LINE__, packet_ptr);
90 
91 #ifndef NX_DISABLE_RX_SIZE_CHECKING
92 
93     /* Check for valid packet length.  */
94     if (packet_ptr -> nx_packet_length < sizeof(NX_IGMP_HEADER))
95     {
96 
97 #ifndef NX_DISABLE_IGMP_INFO
98         /* Increment the IGMP invalid packet error.  */
99         ip_ptr -> nx_ip_igmp_invalid_packets++;
100 #endif
101 
102         /* Invalid packet length, just release it.  */
103         _nx_packet_release(packet_ptr);
104 
105         /* The function is complete, just return!  */
106         return;
107     }
108 #endif
109 
110     /* Determine if this routine is being called from an ISR.  */
111     if ((TX_THREAD_GET_SYSTEM_STATE()) || (&(ip_ptr -> nx_ip_thread) != _tx_thread_current_ptr))
112     {
113 
114         /* If system state is non-zero, we are in an ISR. If the current thread is not the IP thread,
115            we need to prevent unnecessary recursion in loopback.  Just place the message at the
116            end of the IGMP message queue and wakeup the IP helper thread.  */
117 
118         /* Disable interrupts.  */
119         TX_DISABLE
120 
121         /* Add the packet to the IGMP message queue.  */
122         if (ip_ptr -> nx_ip_igmp_queue_head)
123         {
124 
125             /* Link the current packet to the list head.  */
126             packet_ptr -> nx_packet_queue_next =  ip_ptr -> nx_ip_igmp_queue_head;
127         }
128         else
129         {
130 
131             /* Empty queue, add to the head of the IGMP message queue.  */
132             packet_ptr -> nx_packet_queue_next =  NX_NULL;
133         }
134 
135         /* Add debug information. */
136         NX_PACKET_DEBUG(__FILE__, __LINE__, packet_ptr);
137 
138         /* Update the queue head pointer.  */
139         ip_ptr -> nx_ip_igmp_queue_head =  packet_ptr;
140 
141         /* Restore interrupts.  */
142         TX_RESTORE
143 
144         /* Wakeup IP thread for processing one or more messages in the IGMP queue.  */
145         tx_event_flags_set(&(ip_ptr -> nx_ip_events), NX_IP_IGMP_EVENT, TX_OR);
146     }
147     else
148     {
149 
150         /* The IP message was deferred, so this routine is called from the IP helper
151            thread and thus may call the IGMP processing directly.  */
152         _nx_igmp_packet_process(ip_ptr, packet_ptr);
153     }
154 }
155 #endif /* !NX_DISABLE_IPV4  */
156 
157