ipv4_multicast.c
Go to the documentation of this file.
1 /**
2  * @file ipv4_multicast.c
3  * @brief IPv4 multicast filtering
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneTCP Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.4.4
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL IPV4_TRACE_LEVEL
33 
34 //Dependencies
35 #include "core/net.h"
36 #include "core/socket_misc.h"
37 #include "ipv4/ipv4.h"
38 #include "ipv4/ipv4_multicast.h"
39 #include "igmp/igmp_host.h"
40 #include "debug.h"
41 
42 //Check TCP/IP stack configuration
43 #if (IPV4_SUPPORT == ENABLED)
44 
45 
46 /**
47  * @brief Filter out incoming multicast traffic
48  * @param[in] interface The interface on which the packet was received
49  * @param[in] destAddr Destination IP address of the received packet
50  * @param[in] srcAddr Source IP address of the received packet
51  * @return Error code
52  **/
53 
56 {
57  error_t error;
58  uint_t i;
59  Ipv4FilterEntry *entry;
60 
61  //Initialize status code
62  error = ERROR_INVALID_ADDRESS;
63 
64  //Go through the multicast filter table
65  for(i = 0; i < IPV4_MULTICAST_FILTER_SIZE && error; i++)
66  {
67  //Point to the current entry
68  entry = &interface->ipv4Context.multicastFilter[i];
69 
70  //Matching multicast address?
71  if(entry->addr == destAddr)
72  {
73 #if (IPV4_MAX_MULTICAST_SOURCES > 0)
74  uint_t j;
75 
76  //Check filter mode
78  {
79  //In INCLUDE mode, reception of packets sent to the specified
80  //multicast address is requested only from those IP source
81  //addresses listed in the source list
82  for(j = 0; j < IPV4_MAX_MULTICAST_SOURCES && error; j++)
83  {
84  //Compare source addresses
85  if(entry->srcFilter.sources[j] == srcAddr)
86  {
87  error = NO_ERROR;
88  }
89  }
90  }
91  else
92  {
93  //In EXCLUDE mode, reception of packets sent to the given multicast
94  //address is requested from all IP source addresses except those
95  //listed in the source list
96  error = NO_ERROR;
97 
98  //Loop through the list of excluded source addresses
99  for(j = 0; j < entry->srcFilter.numSources && !error; j++)
100  {
101  //Compare source addresses
102  if(entry->srcFilter.sources[j] == srcAddr)
103  {
104  error = ERROR_INVALID_ADDRESS;
105  }
106  }
107  }
108 #else
109  //The multicast address is acceptable
110  error = NO_ERROR;
111 #endif
112  }
113  }
114 
115  //Return status code
116  return error;
117 }
118 
119 
120 /**
121  * @brief Join the specified host group
122  * @param[in] interface Underlying network interface
123  * @param[in] groupAddr IPv4 address identifying the host group to join
124  * @return Error code
125  **/
126 
128 {
129  error_t error;
130  Ipv4FilterEntry *entry;
131 
132  //Initialize status code
133  error = NO_ERROR;
134 
135  //The IPv4 address must be a valid multicast address
137  {
138  //Search the IPv4 multicast filter table for the specified address
139  entry = ipv4FindMulticastFilterEntry(interface, groupAddr);
140 
141  //No matching entry found?
142  if(entry == NULL)
143  {
144  //Create a new entry
145  entry = ipv4CreateMulticastFilterEntry(interface, groupAddr);
146  }
147 
148  //Entry successfully created?
149  if(entry != NULL)
150  {
151  //Increment the reference count
152  entry->anySourceRefCount++;
153  }
154  else
155  {
156  //A new entry cannot be added to the multicast filter table
157  error = ERROR_OUT_OF_RESOURCES;
158  }
159  }
160  else
161  {
162  //The specified group address is not valid
163  error = ERROR_INVALID_ADDRESS;
164  }
165 
166  //Check status code
167  if(!error)
168  {
169  //Update IPv4 multicast filter table
171  }
172 
173  //Return status code
174  return error;
175 }
176 
177 
178 /**
179  * @brief Leave the specified host group
180  * @param[in] interface Underlying network interface
181  * @param[in] groupAddr IPv4 address identifying the host group to leave
182  * @return Error code
183  **/
184 
186 {
187  error_t error;
188  Ipv4FilterEntry *entry;
189 
190  //Initialize status code
191  error = NO_ERROR;
192 
193  //Search the IPv4 multicast filter table for the specified address
194  entry = ipv4FindMulticastFilterEntry(interface, groupAddr);
195 
196  //Check whether a matching entry has been found
197  if(entry != NULL)
198  {
199  //Decrement the reference count
200  if(entry->anySourceRefCount > 0)
201  {
202  entry->anySourceRefCount--;
203  }
204  }
205  else
206  {
207  //The specified IPv4 address does not exist
208  error = ERROR_ADDRESS_NOT_FOUND;
209  }
210 
211  //Check status code
212  if(!error)
213  {
214  //Update IPv4 multicast filter table
216  }
217 
218  //Return status code
219  return error;
220 }
221 
222 
223 /**
224  * @brief Update IPv4 multicast filter table
225  * @param[in] interface Underlying network interface
226  * @param[in] groupAddr IPv4 multicast address
227  **/
228 
230 {
231  error_t error;
232  uint_t i;
233  Ipv4FilterEntry *entry;
234 
235  //First, reset the per-interface state
236  for(i = 0; i < IPV4_MULTICAST_FILTER_SIZE; i++)
237  {
238  //Point to the current entry
239  entry = &interface->ipv4Context.multicastFilter[i];
240 
241  //Matching multicast address?
242  if(groupAddr == IPV4_UNSPECIFIED_ADDR || groupAddr == entry->addr)
243  {
244  //Any-source multicast mode?
245  if(entry->anySourceRefCount > 0)
246  {
248  entry->srcFilter.numSources = 0;
249  }
250  else
251  {
253  entry->srcFilter.numSources = 0;
254  }
255  }
256  }
257 
258 #if (SOCKET_MAX_MULTICAST_GROUPS > 0)
259  //The per-interface state is derived from the per-socket state, but may
260  //differ from the per-socket state when different sockets have differing
261  //filter modes and/or source lists for the same multicast address and
262  //interface (refer to RFC 3376, section 3.2)
263  for(i = 0; i < SOCKET_MAX_COUNT; i++)
264  {
265  uint_t j;
266  Socket *socket;
267  SocketMulticastGroup *group;
268 
269  //Point to the current socket
270  socket = &socketTable[i];
271 
272  //Connectionless or raw socket?
273  if(socket->type == SOCKET_TYPE_DGRAM ||
274  socket->type == SOCKET_TYPE_RAW_IP)
275  {
276  //Loop through multicast groups
277  for(j = 0; j < SOCKET_MAX_MULTICAST_GROUPS; j++)
278  {
279  //Point to the per-socket state
280  group = &socket->multicastGroups[j];
281 
282  //IPv4 group address?
283  if(group->addr.length == sizeof(Ipv4Addr))
284  {
285  //Matching multicast address?
287  groupAddr == group->addr.ipv4Addr)
288  {
289  //Search the IPv4 multicast filter table for the specified
290  //address
291  entry = ipv4FindMulticastFilterEntry(interface,
292  group->addr.ipv4Addr);
293 
294  //No matching entry found?
295  if(entry == NULL)
296  {
297  //Create a new entry
298  entry = ipv4CreateMulticastFilterEntry(interface,
299  group->addr.ipv4Addr);
300  }
301 
302  //Entry successfully created?
303  if(entry != NULL)
304  {
305  //For each distinct (interface, multicast-address) pair
306  //that appears in any socket state, a per-interface record
307  //is created for that multicast address on that interface
308  ipv4DeriveInterfaceState(entry, group);
309  }
310  }
311  }
312  }
313  }
314  }
315 #endif
316 
317  //Take the necessary actions when the per-interface state is changed
318  for(i = 0; i < IPV4_MULTICAST_FILTER_SIZE; i++)
319  {
320  //Point to the current entry
321  entry = &interface->ipv4Context.multicastFilter[i];
322 
323  //Valid entry?
324  if(entry->addr != IPV4_UNSPECIFIED_ADDR)
325  {
326  //Check whether the interface has reception state for that group
327  //address
328  if(entry->srcFilterMode == IP_FILTER_MODE_EXCLUDE ||
329  entry->srcFilter.numSources > 0)
330  {
331  //The MAC layer is reconfigured to accept the multicast traffic
332  if(!entry->macFilterConfigured)
333  {
334  //Map the IPv4 multicast address to a MAC-layer address and add
335  //the corresponding address to the MAC filter table
336  error = ipv4AcceptMulticastAddr(interface, entry->addr);
337 
338  //MAC filter table successfully updated?
339  if(!error)
340  {
341  entry->macFilterConfigured = TRUE;
342  }
343  }
344  }
345  else
346  {
347  //The MAC layer is reconfigured to drop the multicast traffic
348  if(entry->macFilterConfigured)
349  {
350  ipv4DropMulticastAddr(interface, entry->addr);
351  }
352  }
353 
354 #if (IGMP_HOST_SUPPORT == ENABLED)
355  //Any change of interface state causes the system to immediately
356  //transmit a State-Change Report from that interface
357  igmpHostStateChangeEvent(&interface->igmpHostContext, entry->addr,
358  (IpFilterMode) entry->srcFilterMode, &entry->srcFilter);
359 #endif
360  //If no state exists after the change, the "non-existent" state is
361  //considered to have a filter mode of INCLUDE and an empty source list
362  if(entry->srcFilterMode != IP_FILTER_MODE_EXCLUDE &&
363  entry->srcFilter.numSources == 0)
364  {
365  //Remove the entry from the multicast filter
367  }
368  }
369  }
370 }
371 
372 
373 /**
374  * @brief Derive the per-interface state from the per-socket state
375  * @param[in] entry Pointer to the per-interface state
376  * @param[in] group Pointer to the per-socket state
377  **/
378 
380  SocketMulticastGroup *group)
381 {
382 #if (IPV4_MAX_MULTICAST_SOURCES > 0 && SOCKET_MAX_MULTICAST_SOURCES > 0)
383  uint_t i;
384 
385  //For each distinct (interface, multicast-address) pair that appears in any
386  //socket state, a per-interface record is created for that multicast address
387  //on that interface
388  if(entry->srcFilterMode == IP_FILTER_MODE_INCLUDE &&
389  group->filterMode == IP_FILTER_MODE_INCLUDE)
390  {
391  //If all records have a filter mode of INCLUDE, then the filter mode of
392  //the interface record is INCLUDE, and the source list of the interface
393  //record is the union of the source lists of all the socket records
394  for(i = 0; i < group->numSources; i++)
395  {
396  ipv4AddSrcAddr(&entry->srcFilter, group->sources[i].ipv4Addr);
397  }
398  }
399  else if(entry->srcFilterMode == IP_FILTER_MODE_EXCLUDE &&
400  group->filterMode == IP_FILTER_MODE_EXCLUDE)
401  {
402  //The source list of the interface record is the intersection of the
403  //source lists of all socket records in EXCLUDE mode
404  for(i = 0; i < entry->srcFilter.numSources; )
405  {
406  IpAddr srcAddr;
407 
408  //Get current source address
409  srcAddr.length = sizeof(Ipv4Addr);
410  srcAddr.ipv4Addr = entry->srcFilter.sources[i];
411 
412  //Calculate the intersection of the records
413  if(socketFindMulticastSrcAddr(group, &srcAddr) >= 0)
414  {
415  i++;
416  }
417  else
418  {
419  ipv4RemoveSrcAddr(&entry->srcFilter, srcAddr.ipv4Addr);
420  }
421  }
422  }
423  else if(entry->srcFilterMode == IP_FILTER_MODE_EXCLUDE &&
424  group->filterMode == IP_FILTER_MODE_INCLUDE)
425  {
426  //Remove the source addresses that appear in any socket record in INCLUDE
427  //mode
428  for(i = 0; i < group->numSources; i++)
429  {
430  ipv4RemoveSrcAddr(&entry->srcFilter, group->sources[i].ipv4Addr);
431  }
432  }
433  else if(entry->srcFilterMode == IP_FILTER_MODE_INCLUDE &&
434  group->filterMode == IP_FILTER_MODE_EXCLUDE)
435  {
436  Ipv4SrcAddrList srcFilter;
437 
438  //If any record has a filter mode of EXCLUDE, then the filter mode of the
439  //interface record is EXCLUDE
441 
442  //Initialize record
443  srcFilter.numSources = 0;
444 
445  //Copy the source addresses that appear in the per-socket record
446  for(i = 0; i < group->numSources; i++)
447  {
448  ipv4AddSrcAddr(&srcFilter, group->sources[i].ipv4Addr);
449  }
450 
451  //Remove the source addresses that appear in any socket record in INCLUDE
452  //mode
453  for(i = 0; i < entry->srcFilter.numSources; i++)
454  {
455  ipv4RemoveSrcAddr(&srcFilter, entry->srcFilter.sources[i]);
456  }
457 
458  //Save the resulting per-interface record
459  entry->srcFilter = srcFilter;
460  }
461  else
462  {
463  //Just for sanity
464  }
465 #else
466  //All sources are accepted
468  entry->srcFilter.numSources = 0;
469 #endif
470 }
471 
472 
473 /**
474  * @brief Reconfigure the MAC layer to accept multicast traffic
475  * @param[in] interface Underlying network interface
476  * @param[in] groupAddr IPv4 multicast address to accept
477  * @return Error code
478  **/
479 
481 {
482  error_t error;
483 #if (ETH_SUPPORT == ENABLED)
484  NetInterface *physicalInterface;
485  MacAddr macAddr;
486 #endif
487 
488  //Initialize status code
489  error = NO_ERROR;
490 
491 #if (ETH_SUPPORT == ENABLED)
492  //Point to the physical interface
493  physicalInterface = nicGetPhysicalInterface(interface);
494 
495  //Map the IPv4 multicast address to a MAC-layer address
497 
498  //Add the corresponding address to the MAC filter table
499  error = ethAcceptMacAddr(interface, &macAddr);
500 
501  //Check status code
502  if(!error)
503  {
504  //Virtual interface?
505  if(interface != physicalInterface)
506  {
507  //Configure the physical interface to accept the MAC address
508  error = ethAcceptMacAddr(physicalInterface, &macAddr);
509 
510  //Any error to report?
511  if(error)
512  {
513  //Clean up side effects
514  ethDropMacAddr(interface, &macAddr);
515  }
516  }
517  }
518 #endif
519 
520  //Return status code
521  return error;
522 }
523 
524 
525 /**
526  * @brief Reconfigure the MAC layer to reject multicast traffic
527  * @param[in] interface Underlying network interface
528  * @param[in] groupAddr IPv4 multicast address to reject
529  **/
530 
532 {
533 #if (ETH_SUPPORT == ENABLED)
534  NetInterface *physicalInterface;
535  MacAddr macAddr;
536 
537  //Point to the physical interface
538  physicalInterface = nicGetPhysicalInterface(interface);
539 
540  //Map the IPv4 multicast address to a MAC-layer address
542  //Drop the corresponding address from the MAC filter table
543  ethDropMacAddr(interface, &macAddr);
544 
545  //Virtual interface?
546  if(interface != physicalInterface)
547  {
548  //Drop the corresponding address from the MAC filter table of
549  //the physical interface
550  ethDropMacAddr(physicalInterface, &macAddr);
551  }
552 #endif
553 }
554 
555 
556 /**
557  * @brief Map an host group address to a MAC-layer multicast address
558  * @param[in] ipAddr IPv4 host group address
559  * @param[out] macAddr Corresponding MAC-layer multicast address
560  * @return Error code
561  **/
562 
564 {
565  error_t error;
566  uint8_t *p;
567 
568  //Initialize status code
569  error = NO_ERROR;
570 
571  //Check parameters
572  if(macAddr != NULL)
573  {
574  //Ensure the specified IPv4 address is a valid host group address
576  {
577  //Cast the address to byte array
578  p = (uint8_t *) &ipAddr;
579 
580  //An IP host group address is mapped to an Ethernet multicast address
581  //by placing the low-order 23-bits of the IP address into the low-order
582  //23 bits of the Ethernet multicast address 01-00-5E-00-00-00
583  macAddr->b[0] = 0x01;
584  macAddr->b[1] = 0x00;
585  macAddr->b[2] = 0x5E;
586  macAddr->b[3] = p[1] & 0x7F;
587  macAddr->b[4] = p[2];
588  macAddr->b[5] = p[3];
589  }
590  else
591  {
592  //The specified IPv4 address is not a valid host group address
593  error = ERROR_INVALID_ADDRESS;
594  }
595  }
596  else
597  {
598  //Report an error
599  error = ERROR_INVALID_PARAMETER;
600  }
601 
602  //Return status code
603  return error;
604 }
605 
606 
607 /**
608  * @brief Create a new multicast filter entry
609  * @param[in] interface Underlying network interface
610  * @param[in] multicastAddr IPv4 multicast address
611  * @return Pointer to the newly created multicast filter entry
612  **/
613 
616 {
617  uint_t i;
618  Ipv4FilterEntry *entry;
619 
620  //Initialize pointer
621  entry = NULL;
622 
623  //Go through the multicast filter table
624  for(i = 0; i < IPV4_MULTICAST_FILTER_SIZE; i++)
625  {
626  //Check whether the current entry is available for use
627  if(interface->ipv4Context.multicastFilter[i].addr == IPV4_UNSPECIFIED_ADDR)
628  {
629  //Point to the current entry
630  entry = &interface->ipv4Context.multicastFilter[i];
631 
632  //Initialize entry
633  entry->addr = multicastAddr;
634  entry->anySourceRefCount = 0;
635  entry->macFilterConfigured = FALSE;
637  entry->srcFilter.numSources = 0;
638 
639  //We are done
640  break;
641  }
642  }
643 
644  //Return a pointer to the newly created multicast filter entry
645  return entry;
646 }
647 
648 
649 /**
650  * @brief Search the multicast filter for a given address
651  * @param[in] interface Underlying network interface
652  * @param[in] multicastAddr IPv4 multicast address
653  * @return A pointer to the matching multicast filter entry is returned. NULL
654  * is returned if the specified group address cannot be found
655  **/
656 
659 {
660  uint_t i;
661  Ipv4FilterEntry *entry;
662 
663  //Initialize pointer
664  entry = NULL;
665 
666  //Go through the multicast filter table
667  for(i = 0; i < IPV4_MULTICAST_FILTER_SIZE; i++)
668  {
669  //Compare multicast addresses
670  if(interface->ipv4Context.multicastFilter[i].addr == multicastAddr)
671  {
672  //Point to the current entry
673  entry = &interface->ipv4Context.multicastFilter[i];
674  break;
675  }
676  }
677 
678  //Return a pointer to the matching multicast filter entry
679  return entry;
680 }
681 
682 
683 /**
684  * @brief Delete a multicast filter entry
685  * @param[in] entry Pointer to the multicast filter entry
686  **/
687 
689 {
690  //Delete the specified entry
691  entry->addr = IPV4_UNSPECIFIED_ADDR;
692 }
693 
694 
695 /**
696  * @brief Append a source address to a given list
697  * @param[in] list Pointer to the list of source addresses
698  * @param[in] srcAddr Source IP address to be added
699  **/
700 
702 {
703 #if (IPV4_MAX_MULTICAST_SOURCES > 0)
704  error_t error;
705 
706  //Initialize status code
707  error = NO_ERROR;
708 
709  //Make sure that the source address is not a duplicate
710  if(ipv4FindSrcAddr(list, srcAddr) < 0)
711  {
712  //Check the length of the list
714  {
715  //Append the source address to the list
716  list->sources[list->numSources] = srcAddr;
717  list->numSources++;
718  }
719  else
720  {
721  //The implementation limits the number of source addresses
722  error = ERROR_OUT_OF_RESOURCES;
723  }
724  }
725 
726  //Return status code
727  return error;
728 #else
729  //Not implemented
730  return ERROR_NOT_IMPLEMENTED;
731 #endif
732 }
733 
734 
735 /**
736  * @brief Remove a source address from a given list
737  * @param[in] list Pointer to the list of source addresses
738  * @param[in] srcAddr Source IP address to be removed
739  **/
740 
742 {
743 #if (IPV4_MAX_MULTICAST_SOURCES > 0)
744  uint_t i;
745  uint_t j;
746 
747  //Loop through the list of source addresses
748  for(i = 0; i < list->numSources; i++)
749  {
750  //Matching IP address?
751  if(list->sources[i] == srcAddr)
752  {
753  //Remove the source address from the list
754  for(j = i + 1; j < list->numSources; j++)
755  {
756  list->sources[j - 1] = list->sources[j];
757  }
758 
759  //Update the length of the list
760  list->numSources--;
761 
762  //We are done
763  break;
764  }
765  }
766 #endif
767 }
768 
769 
770 /**
771  * @brief Search the list of sources for a given IP address
772  * @param[in] list Pointer to the list of source addresses
773  * @param[in] srcAddr Source IP address
774  * @return Index of the matching IP address is returned. -1 is
775  * returned if the specified IP address cannot be found
776  **/
777 
779 {
780 #if (IPV4_MAX_MULTICAST_SOURCES > 0)
781  int_t i;
782  int_t index;
783 
784  //Initialize index
785  index = -1;
786 
787  //Loop through the list of source addresses
788  for(i = 0; i < list->numSources; i++)
789  {
790  //Matching IP address?
791  if(list->sources[i] == srcAddr)
792  {
793  index = i;
794  break;
795  }
796  }
797 
798  //Return the index of the matching IP address, if any
799  return index;
800 #else
801  //Not implemented
802  return -1;
803 #endif
804 }
805 
806 
807 /**
808  * @brief Compare lists of sources
809  * @param[in] list1 Pointer to the first list of source addresses
810  * @param[in] list2 Pointer to the first list of source addresses
811  * @return TRUE if the lists contain the same set of addresses, else FALSE
812  **/
813 
815  const Ipv4SrcAddrList *list2)
816 {
817 #if (IPV4_MAX_MULTICAST_SOURCES > 0)
818  uint_t i;
819  bool_t res;
820 
821  //Same number of elements?
822  if(list1->numSources == list2->numSources)
823  {
824  //Initialize flag
825  res = TRUE;
826 
827  //Loop through the first list of source addresses
828  for(i = 0; i < list1->numSources && res; i++)
829  {
830  //Check whether the current address is present in the second list
831  if(ipv4FindSrcAddr(list2, list1->sources[i]) < 0)
832  {
833  res = FALSE;
834  }
835  }
836  }
837  else
838  {
839  //The lists do not have the same number of elements
840  res = FALSE;
841  }
842 
843  //Return TRUE if the lists contain the same set of addresses
844  return res;
845 #else
846  //Not implemented
847  return TRUE;
848 #endif
849 }
850 
851 #endif
#define ipv4IsMulticastAddr(ipAddr)
Definition: ipv4.h:175
IpFilterMode
Multicast filter mode.
Definition: ip.h:67
error_t ethAcceptMacAddr(NetInterface *interface, const MacAddr *macAddr)
Add a unicast/multicast address to the MAC filter table.
Definition: ethernet.c:594
void ipv4RemoveSrcAddr(Ipv4SrcAddrList *list, Ipv4Addr srcAddr)
Remove a source address from a given list.
Multicast group.
Definition: socket.h:273
int bool_t
Definition: compiler_port.h:53
Source address list.
Definition: ipv4.h:399
error_t ipv4AddSrcAddr(Ipv4SrcAddrList *list, Ipv4Addr srcAddr)
Append a source address to a given list.
Ipv4Addr destAddr
Definition: ipv4.h:329
signed int int_t
Definition: compiler_port.h:49
IP network address.
Definition: ip.h:90
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
uint8_t p
Definition: ndp.h:300
int_t ipv4FindSrcAddr(const Ipv4SrcAddrList *list, Ipv4Addr srcAddr)
Search the list of sources for a given IP address.
#define TRUE
Definition: os_port.h:50
#define SOCKET_MAX_MULTICAST_GROUPS
Definition: socket.h:53
@ ERROR_OUT_OF_RESOURCES
Definition: error.h:64
bool_t ipv4CompareSrcAddrLists(const Ipv4SrcAddrList *list1, const Ipv4SrcAddrList *list2)
Compare lists of sources.
@ SOCKET_TYPE_DGRAM
Definition: socket.h:93
@ IP_FILTER_MODE_EXCLUDE
Definition: ip.h:68
bool_t macFilterConfigured
MAC address filter is configured.
Definition: ipv4.h:415
#define IPV4_MAX_MULTICAST_SOURCES
Definition: ipv4.h:90
error_t ipv4AcceptMulticastAddr(NetInterface *interface, Ipv4Addr groupAddr)
Reconfigure the MAC layer to accept multicast traffic.
const uint8_t res[]
uint32_t Ipv4Addr
IPv4 network address.
Definition: ipv4.h:297
error_t ethDropMacAddr(NetInterface *interface, const MacAddr *macAddr)
Remove a unicast/multicast address from the MAC filter table.
Definition: ethernet.c:666
IpAddr addr
Multicast address.
Definition: socket.h:274
IPv4 multicast filtering.
#define FALSE
Definition: os_port.h:46
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
NetInterface * nicGetPhysicalInterface(NetInterface *interface)
Retrieve physical interface.
Definition: nic.c:85
error_t
Error codes.
Definition: error.h:43
int_t socket(int_t family, int_t type, int_t protocol)
Create a socket that is bound to a specific transport service provider.
Definition: bsd_socket.c:65
@ ERROR_INVALID_ADDRESS
Definition: error.h:103
#define NetInterface
Definition: net.h:36
uint_t numSources
Number of source addresses.
Definition: ipv4.h:400
IPv4 multicast filter entry.
Definition: ipv4.h:412
@ SOCKET_TYPE_RAW_IP
Definition: socket.h:94
IGMP host.
error_t ipv4JoinMulticastGroup(NetInterface *interface, Ipv4Addr groupAddr)
Join the specified host group.
size_t length
Definition: ip.h:91
Socket socketTable[SOCKET_MAX_COUNT]
Definition: socket.c:49
MacAddr
Definition: ethernet.h:195
uint_t anySourceRefCount
Reference count for the current entry.
Definition: ipv4.h:414
error_t ipv4MulticastFilter(NetInterface *interface, Ipv4Addr destAddr, Ipv4Addr srcAddr)
Filter out incoming multicast traffic.
void ipv4UpdateMulticastFilter(NetInterface *interface, Ipv4Addr groupAddr)
Update IPv4 multicast filter table.
Ipv4Addr addr
Multicast address.
Definition: ipv4.h:413
Ipv4Addr ipv4Addr
Definition: ip.h:95
Helper functions for sockets.
void ipv4DeriveInterfaceState(Ipv4FilterEntry *entry, SocketMulticastGroup *group)
Derive the per-interface state from the per-socket state.
uint_t srcFilterMode
Source filter mode.
Definition: ipv4.h:416
Ipv4Addr groupAddr
Definition: igmp_common.h:214
error_t ipv4LeaveMulticastGroup(NetInterface *interface, Ipv4Addr groupAddr)
Leave the specified host group.
void igmpHostStateChangeEvent(IgmpHostContext *context, Ipv4Addr groupAddr, IpFilterMode newFilterMode, const Ipv4SrcAddrList *newFilter)
Process multicast reception state change.
Definition: igmp_host.c:346
void ipv4DropMulticastAddr(NetInterface *interface, Ipv4Addr groupAddr)
Reconfigure the MAC layer to reject multicast traffic.
Ipv4SrcAddrList srcFilter
Source filter.
Definition: ipv4.h:417
#define Socket
Definition: socket.h:36
@ IP_FILTER_MODE_INCLUDE
Definition: ip.h:69
MacAddr srcAddr
Definition: ethernet.h:220
@ ERROR_ADDRESS_NOT_FOUND
Definition: error.h:258
Ipv4Addr ipAddr
Definition: ipcp.h:105
Ipv4FilterEntry * ipv4CreateMulticastFilterEntry(NetInterface *interface, Ipv4Addr multicastAddr)
Create a new multicast filter entry.
Ipv4FilterEntry * ipv4FindMulticastFilterEntry(NetInterface *interface, Ipv4Addr multicastAddr)
Search the multicast filter for a given address.
IPv4 (Internet Protocol Version 4)
unsigned int uint_t
Definition: compiler_port.h:50
void ipv4DeleteMulticastFilterEntry(Ipv4FilterEntry *entry)
Delete a multicast filter entry.
TCP/IP stack core.
#define SOCKET_MAX_COUNT
Definition: socket.h:46
error_t ipv4MapMulticastAddrToMac(Ipv4Addr ipAddr, MacAddr *macAddr)
Map an host group address to a MAC-layer multicast address.
int_t socketFindMulticastSrcAddr(SocketMulticastGroup *group, const IpAddr *srcAddr)
Search the list of multicast sources for a given IP address.
Definition: socket_misc.c:564
@ NO_ERROR
Success.
Definition: error.h:44
Ipv4Addr multicastAddr
Definition: igmp_common.h:267
Debugging facilities.
#define IPV4_UNSPECIFIED_ADDR
Definition: ipv4.h:117
#define IPV4_MULTICAST_FILTER_SIZE
Definition: ipv4.h:83