ipv6_multicast.c
Go to the documentation of this file.
1 /**
2  * @file ipv6_multicast.c
3  * @brief IPv6 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 IPV6_TRACE_LEVEL
33 
34 //Dependencies
35 #include "core/net.h"
36 #include "core/socket_misc.h"
37 #include "ipv6/ipv6.h"
38 #include "ipv6/ipv6_multicast.h"
39 #include "mld/mld_node.h"
40 #include "debug.h"
41 
42 //Check TCP/IP stack configuration
43 #if (IPV6_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 
55  const Ipv6Addr *srcAddr)
56 {
57  error_t error;
58  uint_t i;
59  Ipv6FilterEntry *entry;
60 
61  //Initialize status code
62  error = ERROR_INVALID_ADDRESS;
63 
64  //Go through the multicast filter table
65  for(i = 0; i < IPV6_MULTICAST_FILTER_SIZE && error; i++)
66  {
67  //Point to the current entry
68  entry = &interface->ipv6Context.multicastFilter[i];
69 
70  //Matching multicast address?
71  if(ipv6CompAddr(&entry->addr, destAddr))
72  {
73 #if (IPV6_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 < IPV6_MAX_MULTICAST_SOURCES && error; j++)
83  {
84  //Compare source addresses
85  if(ipv6CompAddr(&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(ipv6CompAddr(&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 an IPv6 multicast group
122  * @param[in] interface Underlying network interface
123  * @param[in] groupAddr IPv6 Multicast address to join
124  * @return Error code
125  **/
126 
128  const Ipv6Addr *groupAddr)
129 {
130  error_t error;
131  Ipv6FilterEntry *entry;
132 
133  //Initialize status code
134  error = NO_ERROR;
135 
136  //The IPv6 address must be a valid multicast address
138  {
139  //Search the IPv6 multicast filter table for the specified address
140  entry = ipv6FindMulticastFilterEntry(interface, groupAddr);
141 
142  //No matching entry found?
143  if(entry == NULL)
144  {
145  //Create a new entry
146  entry = ipv6CreateMulticastFilterEntry(interface, groupAddr);
147  }
148 
149  //Entry successfully created?
150  if(entry != NULL)
151  {
152  //Increment the reference count
153  entry->anySourceRefCount++;
154  }
155  else
156  {
157  //A new entry cannot be added to the multicast filter table
158  error = ERROR_OUT_OF_RESOURCES;
159  }
160  }
161  else
162  {
163  //The specified group address is not valid
164  error = ERROR_INVALID_ADDRESS;
165  }
166 
167  //Check status code
168  if(!error)
169  {
170  //Update IPv6 multicast filter table
172  }
173 
174  //Return status code
175  return error;
176 }
177 
178 
179 /**
180  * @brief Leave an IPv6 multicast group
181  * @param[in] interface Underlying network interface
182  * @param[in] groupAddr IPv6 multicast address to drop
183  * @return Error code
184  **/
185 
187  const Ipv6Addr *groupAddr)
188 {
189  error_t error;
190  Ipv6FilterEntry *entry;
191 
192  //Initialize status code
193  error = NO_ERROR;
194 
195  //Search the IPv6 multicast filter table for the specified address
196  entry = ipv6FindMulticastFilterEntry(interface, groupAddr);
197 
198  //Check whether a matching entry has been found
199  if(entry != NULL)
200  {
201  //Decrement the reference count
202  if(entry->anySourceRefCount > 0)
203  {
204  entry->anySourceRefCount--;
205  }
206  }
207  else
208  {
209  //The specified IPv6 address does not exist
210  error = ERROR_ADDRESS_NOT_FOUND;
211  }
212 
213  //Check status code
214  if(!error)
215  {
216  //Update IPv6 multicast filter table
218  }
219 
220  //Return status code
221  return error;
222 }
223 
224 
225 /**
226  * @brief Update IPv6 multicast filter table
227  * @param[in] interface Underlying network interface
228  * @param[in] groupAddr IPv6 multicast address
229  **/
230 
232  const Ipv6Addr *groupAddr)
233 {
234  error_t error;
235  uint_t i;
236  Ipv6FilterEntry *entry;
237 
238  //First, reset the per-interface state
239  for(i = 0; i < IPV6_MULTICAST_FILTER_SIZE; i++)
240  {
241  //Point to the current entry
242  entry = &interface->ipv6Context.multicastFilter[i];
243 
244  //Matching multicast address?
246  ipv6CompAddr(groupAddr, &entry->addr))
247  {
248  //Any-source multicast mode?
249  if(entry->anySourceRefCount > 0)
250  {
252  entry->srcFilter.numSources = 0;
253  }
254  else
255  {
257  entry->srcFilter.numSources = 0;
258  }
259  }
260  }
261 
262 #if (SOCKET_MAX_MULTICAST_GROUPS > 0)
263  //The per-interface state is derived from the per-socket state, but may
264  //differ from the per-socket state when different sockets have differing
265  //filter modes and/or source lists for the same multicast address and
266  //interface (refer to RFC 3376, section 3.2)
267  for(i = 0; i < SOCKET_MAX_COUNT; i++)
268  {
269  uint_t j;
270  Socket *socket;
271  SocketMulticastGroup *group;
272 
273  //Point to the current socket
274  socket = &socketTable[i];
275 
276  //Connectionless or raw socket?
277  if(socket->type == SOCKET_TYPE_DGRAM ||
278  socket->type == SOCKET_TYPE_RAW_IP)
279  {
280  //Loop through multicast groups
281  for(j = 0; j < SOCKET_MAX_MULTICAST_GROUPS; j++)
282  {
283  //Point to the per-socket state
284  group = &socket->multicastGroups[j];
285 
286  //IPv6 group address?
287  if(group->addr.length == sizeof(Ipv6Addr))
288  {
289  //Matching multicast address?
292  {
293  //Search the IPv6 multicast filter table for the specified
294  //address
295  entry = ipv6FindMulticastFilterEntry(interface,
296  &group->addr.ipv6Addr);
297 
298  //No matching entry found?
299  if(entry == NULL)
300  {
301  //Create a new entry
302  entry = ipv6CreateMulticastFilterEntry(interface,
303  &group->addr.ipv6Addr);
304  }
305 
306  //Entry successfully created?
307  if(entry != NULL)
308  {
309  //For each distinct (interface, multicast-address) pair
310  //that appears in any socket state, a per-interface record
311  //is created for that multicast address on that interface
312  ipv6DeriveInterfaceState(entry, group);
313  }
314  }
315  }
316  }
317  }
318  }
319 #endif
320 
321  //Take the necessary actions when the per-interface state is changed
322  for(i = 0; i < IPV6_MULTICAST_FILTER_SIZE; i++)
323  {
324  //Point to the current entry
325  entry = &interface->ipv6Context.multicastFilter[i];
326 
327  //Valid entry?
328  if(!ipv6CompAddr(&entry->addr, &IPV6_UNSPECIFIED_ADDR))
329  {
330  //Check whether the interface has reception state for that group
331  //address
332  if(entry->srcFilterMode == IP_FILTER_MODE_EXCLUDE ||
333  entry->srcFilter.numSources > 0)
334  {
335  //The MAC layer is reconfigured to accept the multicast traffic
336  if(!entry->macFilterConfigured)
337  {
338  //Map the IPv6 multicast address to a MAC-layer address and add
339  //the corresponding address to the MAC filter table
340  error = ipv6AcceptMulticastAddr(interface, &entry->addr);
341 
342  //MAC filter table successfully updated?
343  if(!error)
344  {
345  entry->macFilterConfigured = TRUE;
346  }
347  }
348  }
349  else
350  {
351  //The MAC layer is reconfigured to drop the multicast traffic
352  if(entry->macFilterConfigured)
353  {
354  ipv6DropMulticastAddr(interface, &entry->addr);
355  }
356  }
357 
358 #if (MLD_NODE_SUPPORT == ENABLED)
359  //Any change of interface state causes the system to immediately
360  //transmit a State-Change Report from that interface
361  mldNodeStateChangeEvent(&interface->mldNodeContext, &entry->addr,
362  (IpFilterMode) entry->srcFilterMode, &entry->srcFilter);
363 #endif
364  //If no state exists after the change, the "non-existent" state is
365  //considered to have a filter mode of INCLUDE and an empty source list
366  if(entry->srcFilterMode != IP_FILTER_MODE_EXCLUDE &&
367  entry->srcFilter.numSources == 0)
368  {
369  //Remove the entry from the multicast filter
371  }
372  }
373  }
374 }
375 
376 
377 /**
378  * @brief Derive the per-interface state from the per-socket state
379  * @param[in] entry Pointer to the per-interface state
380  * @param[in] group Pointer to the per-socket state
381  **/
382 
384  SocketMulticastGroup *group)
385 {
386 #if (IPV6_MAX_MULTICAST_SOURCES > 0 && SOCKET_MAX_MULTICAST_SOURCES > 0)
387  uint_t i;
388 
389  //For each distinct (interface, multicast-address) pair that appears in any
390  //socket state, a per-interface record is created for that multicast address
391  //on that interface
392  if(entry->srcFilterMode == IP_FILTER_MODE_INCLUDE &&
393  group->filterMode == IP_FILTER_MODE_INCLUDE)
394  {
395  //If all records have a filter mode of INCLUDE, then the filter mode of
396  //the interface record is INCLUDE, and the source list of the interface
397  //record is the union of the source lists of all the socket records
398  for(i = 0; i < group->numSources; i++)
399  {
400  ipv6AddSrcAddr(&entry->srcFilter, &group->sources[i].ipv6Addr);
401  }
402  }
403  else if(entry->srcFilterMode == IP_FILTER_MODE_EXCLUDE &&
404  group->filterMode == IP_FILTER_MODE_EXCLUDE)
405  {
406  //The source list of the interface record is the intersection of the
407  //source lists of all socket records in EXCLUDE mode
408  for(i = 0; i < entry->srcFilter.numSources; )
409  {
410  IpAddr srcAddr;
411 
412  //Get current source address
413  srcAddr.length = sizeof(Ipv6Addr);
414  srcAddr.ipv6Addr = entry->srcFilter.sources[i];
415 
416  //Calculate the intersection of the records
417  if(socketFindMulticastSrcAddr(group, &srcAddr) >= 0)
418  {
419  i++;
420  }
421  else
422  {
423  ipv6RemoveSrcAddr(&entry->srcFilter, &srcAddr.ipv6Addr);
424  }
425  }
426  }
427  else if(entry->srcFilterMode == IP_FILTER_MODE_EXCLUDE &&
428  group->filterMode == IP_FILTER_MODE_INCLUDE)
429  {
430  //Remove the source addresses that appear in any socket record in INCLUDE
431  //mode
432  for(i = 0; i < group->numSources; i++)
433  {
434  ipv6RemoveSrcAddr(&entry->srcFilter, &group->sources[i].ipv6Addr);
435  }
436  }
437  else if(entry->srcFilterMode == IP_FILTER_MODE_INCLUDE &&
438  group->filterMode == IP_FILTER_MODE_EXCLUDE)
439  {
440  Ipv6SrcAddrList srcFilter;
441 
442  //If any record has a filter mode of EXCLUDE, then the filter mode of the
443  //interface record is EXCLUDE
445 
446  //Initialize record
447  srcFilter.numSources = 0;
448 
449  //Copy the source addresses that appear in the per-socket record
450  for(i = 0; i < group->numSources; i++)
451  {
452  ipv6AddSrcAddr(&srcFilter, &group->sources[i].ipv6Addr);
453  }
454 
455  //Remove the source addresses that appear in any socket record in INCLUDE
456  //mode
457  for(i = 0; i < entry->srcFilter.numSources; i++)
458  {
459  ipv6RemoveSrcAddr(&srcFilter, &entry->srcFilter.sources[i]);
460  }
461 
462  //Save the resulting per-interface record
463  entry->srcFilter = srcFilter;
464  }
465  else
466  {
467  //Just for sanity
468  }
469 #else
470  //All sources are accepted
472  entry->srcFilter.numSources = 0;
473 #endif
474 }
475 
476 
477 /**
478  * @brief Reconfigure the MAC layer to accept multicast traffic
479  * @param[in] interface Underlying network interface
480  * @param[in] groupAddr IPv6 multicast address to accept
481  * @return Error code
482  **/
483 
485  const Ipv6Addr *groupAddr)
486 {
487  error_t error;
488 #if (ETH_SUPPORT == ENABLED)
489  NetInterface *physicalInterface;
490  MacAddr macAddr;
491 #endif
492 
493  //Initialize status code
494  error = NO_ERROR;
495 
496 #if (ETH_SUPPORT == ENABLED)
497  //Point to the physical interface
498  physicalInterface = nicGetPhysicalInterface(interface);
499 
500  //Map the IPv6 multicast address to a MAC-layer address
502 
503  //Add the corresponding address to the MAC filter table
504  error = ethAcceptMacAddr(interface, &macAddr);
505 
506  //Check status code
507  if(!error)
508  {
509  //Virtual interface?
510  if(interface != physicalInterface)
511  {
512  //Configure the physical interface to accept the MAC address
513  error = ethAcceptMacAddr(physicalInterface, &macAddr);
514 
515  //Any error to report?
516  if(error)
517  {
518  //Clean up side effects
519  ethDropMacAddr(interface, &macAddr);
520  }
521  }
522  }
523 #endif
524 
525  //Return status code
526  return error;
527 }
528 
529 
530 /**
531  * @brief Reconfigure the MAC layer to reject multicast traffic
532  * @param[in] interface Underlying network interface
533  * @param[in] groupAddr IPv6 multicast address to reject
534  **/
535 
537  const Ipv6Addr *groupAddr)
538 {
539 #if (ETH_SUPPORT == ENABLED)
540  NetInterface *physicalInterface;
541  MacAddr macAddr;
542 
543  //Point to the physical interface
544  physicalInterface = nicGetPhysicalInterface(interface);
545 
546  //Map the IPv6 multicast address to a MAC-layer address
548  //Drop the corresponding address from the MAC filter table
549  ethDropMacAddr(interface, &macAddr);
550 
551  //Virtual interface?
552  if(interface != physicalInterface)
553  {
554  //Drop the corresponding address from the MAC filter table of
555  //the physical interface
556  ethDropMacAddr(physicalInterface, &macAddr);
557  }
558 #endif
559 }
560 
561 
562 /**
563  * @brief Map an IPv6 multicast address to a MAC-layer multicast address
564  * @param[in] ipAddr IPv6 multicast address
565  * @param[out] macAddr Corresponding MAC-layer multicast address
566  * @return Error code
567  **/
568 
570 {
571  error_t error;
572 
573  //Ensure the specified IPv6 address is a multicast address
575  {
576  //To support IPv6 multicasting, MAC address range of 33-33-00-00-00-00
577  //to 33-33-FF-FF-FF-FF is reserved (refer to RFC 2464)
578  macAddr->b[0] = 0x33;
579  macAddr->b[1] = 0x33;
580 
581  //The low-order 32 bits of the IPv6 multicast address are mapped directly
582  //to the low-order 32 bits in the MAC-layer multicast address
583  macAddr->b[2] = ipAddr->b[12];
584  macAddr->b[3] = ipAddr->b[13];
585  macAddr->b[4] = ipAddr->b[14];
586  macAddr->b[5] = ipAddr->b[15];
587 
588  //The specified IPv6 multicast address was successfully mapped to a
589  //MAC-layer address
590  error = NO_ERROR;
591  }
592  else
593  {
594  //Report an error
595  error = ERROR_INVALID_ADDRESS;
596  }
597 
598  //Return status code
599  return error;
600 }
601 
602 
603 /**
604  * @brief Create a new multicast filter entry
605  * @param[in] interface Underlying network interface
606  * @param[in] multicastAddr IPv6 multicast address
607  * @return Pointer to the newly created multicast filter entry
608  **/
609 
611  const Ipv6Addr *multicastAddr)
612 {
613  uint_t i;
614  Ipv6FilterEntry *entry;
615 
616  //Initialize pointer
617  entry = NULL;
618 
619  //Go through the multicast filter table
620  for(i = 0; i < IPV6_MULTICAST_FILTER_SIZE; i++)
621  {
622  //Check whether the current entry is available for use
623  if(ipv6CompAddr(&interface->ipv6Context.multicastFilter[i].addr,
625  {
626  //Point to the current entry
627  entry = &interface->ipv6Context.multicastFilter[i];
628 
629  //Initialize entry
630  entry->addr = *multicastAddr;
631  entry->anySourceRefCount = 0;
632  entry->macFilterConfigured = FALSE;
634  entry->srcFilter.numSources = 0;
635 
636  //We are done
637  break;
638  }
639  }
640 
641  //Return a pointer to the newly created multicast filter entry
642  return entry;
643 }
644 
645 
646 /**
647  * @brief Search the multicast filter for a given address
648  * @param[in] interface Underlying network interface
649  * @param[in] multicastAddr IPv6 multicast address
650  * @return A pointer to the matching multicast filter entry is returned. NULL
651  * is returned if the specified group address cannot be found
652  **/
653 
655  const Ipv6Addr *multicastAddr)
656 {
657  uint_t i;
658  Ipv6FilterEntry *entry;
659 
660  //Initialize pointer
661  entry = NULL;
662 
663  //Go through the multicast filter table
664  for(i = 0; i < IPV6_MULTICAST_FILTER_SIZE; i++)
665  {
666  //Compare multicast addresses
667  if(ipv6CompAddr(&interface->ipv6Context.multicastFilter[i].addr,
668  multicastAddr))
669  {
670  //Point to the current entry
671  entry = &interface->ipv6Context.multicastFilter[i];
672  break;
673  }
674  }
675 
676  //Return a pointer to the matching multicast filter entry
677  return entry;
678 }
679 
680 
681 /**
682  * @brief Delete a multicast filter entry
683  * @param[in] entry Pointer to the multicast filter entry
684  **/
685 
687 {
688  //Delete the specified entry
689  entry->addr = IPV6_UNSPECIFIED_ADDR;
690 }
691 
692 
693 /**
694  * @brief Append a source address to a given list
695  * @param[in] list Pointer to the list of source addresses
696  * @param[in] srcAddr Source IP address to be added
697  **/
698 
700 {
701 #if (IPV6_MAX_MULTICAST_SOURCES > 0)
702  error_t error;
703 
704  //Initialize status code
705  error = NO_ERROR;
706 
707  //Make sure that the source address is not a duplicate
708  if(ipv6FindSrcAddr(list, srcAddr) < 0)
709  {
710  //Check the length of the list
712  {
713  //Append the source address to the list
714  list->sources[list->numSources] = *srcAddr;
715  list->numSources++;
716  }
717  else
718  {
719  //The implementation limits the number of source addresses
720  error = ERROR_OUT_OF_RESOURCES;
721  }
722  }
723 
724  //Return status code
725  return error;
726 #else
727  //Not implemented
728  return ERROR_NOT_IMPLEMENTED;
729 #endif
730 }
731 
732 
733 /**
734  * @brief Remove a source address from a given list
735  * @param[in] list Pointer to the list of source addresses
736  * @param[in] srcAddr Source IP address to be removed
737  **/
738 
740 {
741 #if (IPV6_MAX_MULTICAST_SOURCES > 0)
742  uint_t i;
743  uint_t j;
744 
745  //Loop through the list of source addresses
746  for(i = 0; i < list->numSources; i++)
747  {
748  //Matching IP address?
749  if(ipv6CompAddr(&list->sources[i], srcAddr))
750  {
751  //Remove the source address from the list
752  for(j = i + 1; j < list->numSources; j++)
753  {
754  list->sources[j - 1] = list->sources[j];
755  }
756 
757  //Update the length of the list
758  list->numSources--;
759 
760  //We are done
761  break;
762  }
763  }
764 #endif
765 }
766 
767 
768 /**
769  * @brief Search the list of sources for a given IP address
770  * @param[in] list Pointer to the list of source addresses
771  * @param[in] srcAddr Source IP address
772  * @return Index of the matching IP address is returned. -1 is
773  * returned if the specified IP address cannot be found
774  **/
775 
777 {
778 #if (IPV6_MAX_MULTICAST_SOURCES > 0)
779  int_t i;
780  int_t index;
781 
782  //Initialize index
783  index = -1;
784 
785  //Loop through the list of source addresses
786  for(i = 0; i < list->numSources; i++)
787  {
788  //Matching IP address?
789  if(ipv6CompAddr(&list->sources[i], srcAddr))
790  {
791  index = i;
792  break;
793  }
794  }
795 
796  //Return the index of the matching IP address, if any
797  return index;
798 #else
799  //Not implemented
800  return -1;
801 #endif
802 }
803 
804 
805 /**
806  * @brief Compare lists of sources
807  * @param[in] list1 Pointer to the first list of source addresses
808  * @param[in] list2 Pointer to the first list of source addresses
809  * @return TRUE if the lists contain the same set of addresses, else FALSE
810  **/
811 
813  const Ipv6SrcAddrList *list2)
814 {
815 #if (IPV6_MAX_MULTICAST_SOURCES > 0)
816  uint_t i;
817  bool_t res;
818 
819  //Same number of elements?
820  if(list1->numSources == list2->numSources)
821  {
822  //Initialize flag
823  res = TRUE;
824 
825  //Loop through the first list of source addresses
826  for(i = 0; i < list1->numSources && res; i++)
827  {
828  //Check whether the current address is present in the second list
829  if(ipv6FindSrcAddr(list2, &list1->sources[i]) < 0)
830  {
831  res = FALSE;
832  }
833  }
834  }
835  else
836  {
837  //The lists do not have the same number of elements
838  res = FALSE;
839  }
840 
841  //Return TRUE if the lists contain the same set of addresses
842  return res;
843 #else
844  //Not implemented
845  return TRUE;
846 #endif
847 }
848 
849 #endif
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
IPv6 (Internet Protocol Version 6)
Multicast group.
Definition: socket.h:273
int bool_t
Definition: compiler_port.h:53
void ipv6DeleteMulticastFilterEntry(Ipv6FilterEntry *entry)
Delete a multicast filter entry.
Ipv4Addr destAddr
Definition: ipv4.h:329
Source address list.
Definition: ipv6.h:469
bool_t ipv6CompareSrcAddrLists(const Ipv6SrcAddrList *list1, const Ipv6SrcAddrList *list2)
Compare lists of sources.
int_t ipv6FindSrcAddr(const Ipv6SrcAddrList *list, const Ipv6Addr *srcAddr)
Search the list of sources for a given IP address.
signed int int_t
Definition: compiler_port.h:49
IP network address.
Definition: ip.h:90
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
#define TRUE
Definition: os_port.h:50
error_t ipv6AddSrcAddr(Ipv6SrcAddrList *list, const Ipv6Addr *srcAddr)
Append a source address to a given list.
#define SOCKET_MAX_MULTICAST_GROUPS
Definition: socket.h:53
@ ERROR_OUT_OF_RESOURCES
Definition: error.h:64
Ipv6Addr
Definition: ipv6.h:260
@ SOCKET_TYPE_DGRAM
Definition: socket.h:93
@ IP_FILTER_MODE_EXCLUDE
Definition: ip.h:68
#define ipv6CompAddr(ipAddr1, ipAddr2)
Definition: ipv6.h:127
error_t ipv6MulticastFilter(NetInterface *interface, const Ipv6Addr *destAddr, const Ipv6Addr *srcAddr)
Filter out incoming multicast traffic.
const uint8_t res[]
error_t ethDropMacAddr(NetInterface *interface, const MacAddr *macAddr)
Remove a unicast/multicast address from the MAC filter table.
Definition: ethernet.c:666
Ipv6FilterEntry * ipv6FindMulticastFilterEntry(NetInterface *interface, const Ipv6Addr *multicastAddr)
Search the multicast filter for a given address.
void mldNodeStateChangeEvent(MldNodeContext *context, const Ipv6Addr *groupAddr, IpFilterMode newFilterMode, const Ipv6SrcAddrList *newFilter)
Process multicast reception state change.
Definition: mld_node.c:306
IpAddr addr
Multicast address.
Definition: socket.h:274
#define ipv6IsMulticastAddr(ipAddr)
Definition: ipv6.h:139
IPv6 multicast filtering.
#define FALSE
Definition: os_port.h:46
NetInterface * nicGetPhysicalInterface(NetInterface *interface)
Retrieve physical interface.
Definition: nic.c:85
error_t
Error codes.
Definition: error.h:43
error_t ipv6JoinMulticastGroup(NetInterface *interface, const Ipv6Addr *groupAddr)
Join an IPv6 multicast group.
void ipv6DeriveInterfaceState(Ipv6FilterEntry *entry, SocketMulticastGroup *group)
Derive the per-interface state from the per-socket state.
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 IPV6_MAX_MULTICAST_SOURCES
Definition: ipv6.h:107
uint_t numSources
Number of source addresses.
Definition: ipv6.h:470
#define NetInterface
Definition: net.h:36
error_t ipv6MapMulticastAddrToMac(const Ipv6Addr *ipAddr, MacAddr *macAddr)
Map an IPv6 multicast address to a MAC-layer multicast address.
void ipv6DropMulticastAddr(NetInterface *interface, const Ipv6Addr *groupAddr)
Reconfigure the MAC layer to reject multicast traffic.
Ipv6SrcAddrList srcFilter
Source filter.
Definition: ipv6.h:487
#define IPV6_MULTICAST_FILTER_SIZE
Definition: ipv6.h:100
@ SOCKET_TYPE_RAW_IP
Definition: socket.h:94
const Ipv6Addr IPV6_UNSPECIFIED_ADDR
Definition: ipv6.c:66
size_t length
Definition: ip.h:91
Socket socketTable[SOCKET_MAX_COUNT]
Definition: socket.c:49
MacAddr
Definition: ethernet.h:195
Ipv6Addr addr
Multicast address.
Definition: ipv6.h:483
MLD node (Multicast Listener Discovery for IPv6)
void ipv6UpdateMulticastFilter(NetInterface *interface, const Ipv6Addr *groupAddr)
Update IPv6 multicast filter table.
Helper functions for sockets.
bool_t macFilterConfigured
MAC address filter is configured.
Definition: ipv6.h:485
Ipv4Addr groupAddr
Definition: igmp_common.h:214
#define Socket
Definition: socket.h:36
@ IP_FILTER_MODE_INCLUDE
Definition: ip.h:69
error_t ipv6LeaveMulticastGroup(NetInterface *interface, const Ipv6Addr *groupAddr)
Leave an IPv6 multicast group.
MacAddr srcAddr
Definition: ethernet.h:220
@ ERROR_ADDRESS_NOT_FOUND
Definition: error.h:258
uint_t srcFilterMode
Source filter mode.
Definition: ipv6.h:486
Ipv4Addr ipAddr
Definition: ipcp.h:105
void ipv6RemoveSrcAddr(Ipv6SrcAddrList *list, const Ipv6Addr *srcAddr)
Remove a source address from a given list.
Ipv6Addr ipv6Addr
Definition: ip.h:98
Ipv6FilterEntry * ipv6CreateMulticastFilterEntry(NetInterface *interface, const Ipv6Addr *multicastAddr)
Create a new multicast filter entry.
unsigned int uint_t
Definition: compiler_port.h:50
TCP/IP stack core.
error_t ipv6AcceptMulticastAddr(NetInterface *interface, const Ipv6Addr *groupAddr)
Reconfigure the MAC layer to accept multicast traffic.
#define SOCKET_MAX_COUNT
Definition: socket.h:46
uint_t anySourceRefCount
Reference count for the current entry.
Definition: ipv6.h:484
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.
IPv6 multicast filter entry.
Definition: ipv6.h:482