igmp.c (1da177e4c3f41524e886b7f1b8a0c1fc7321cac2) | igmp.c (ca9b907d140a5f249250d19f956129dbbbf84f73) |
---|---|
1/* 2 * Linux NET3: Internet Group Management Protocol [IGMP] 3 * 4 * This code implements the IGMP protocol as defined in RFC1112. There has 5 * been a further revision of this protocol since which is now supported. 6 * 7 * If you have trouble with this module be careful what gcc you have used, 8 * the older version didn't come out right using gcc 2.5.8, the newer one --- 1601 unchanged lines hidden (view full) --- 1610 1611/* 1612 * Join a multicast group 1613 */ 1614int ip_mc_join_group(struct sock *sk , struct ip_mreqn *imr) 1615{ 1616 int err; 1617 u32 addr = imr->imr_multiaddr.s_addr; | 1/* 2 * Linux NET3: Internet Group Management Protocol [IGMP] 3 * 4 * This code implements the IGMP protocol as defined in RFC1112. There has 5 * been a further revision of this protocol since which is now supported. 6 * 7 * If you have trouble with this module be careful what gcc you have used, 8 * the older version didn't come out right using gcc 2.5.8, the newer one --- 1601 unchanged lines hidden (view full) --- 1610 1611/* 1612 * Join a multicast group 1613 */ 1614int ip_mc_join_group(struct sock *sk , struct ip_mreqn *imr) 1615{ 1616 int err; 1617 u32 addr = imr->imr_multiaddr.s_addr; |
1618 struct ip_mc_socklist *iml, *i; | 1618 struct ip_mc_socklist *iml=NULL, *i; |
1619 struct in_device *in_dev; 1620 struct inet_sock *inet = inet_sk(sk); | 1619 struct in_device *in_dev; 1620 struct inet_sock *inet = inet_sk(sk); |
1621 int ifindex; |
|
1621 int count = 0; 1622 1623 if (!MULTICAST(addr)) 1624 return -EINVAL; 1625 1626 rtnl_shlock(); 1627 1628 in_dev = ip_mc_find_dev(imr); 1629 1630 if (!in_dev) { 1631 iml = NULL; 1632 err = -ENODEV; 1633 goto done; 1634 } 1635 | 1622 int count = 0; 1623 1624 if (!MULTICAST(addr)) 1625 return -EINVAL; 1626 1627 rtnl_shlock(); 1628 1629 in_dev = ip_mc_find_dev(imr); 1630 1631 if (!in_dev) { 1632 iml = NULL; 1633 err = -ENODEV; 1634 goto done; 1635 } 1636 |
1636 iml = (struct ip_mc_socklist *)sock_kmalloc(sk, sizeof(*iml), GFP_KERNEL); 1637 | |
1638 err = -EADDRINUSE; | 1637 err = -EADDRINUSE; |
1638 ifindex = imr->imr_ifindex; |
|
1639 for (i = inet->mc_list; i; i = i->next) { | 1639 for (i = inet->mc_list; i; i = i->next) { |
1640 if (memcmp(&i->multi, imr, sizeof(*imr)) == 0) { 1641 /* New style additions are reference counted */ 1642 if (imr->imr_address.s_addr == 0) { 1643 i->count++; 1644 err = 0; 1645 } | 1640 if (i->multi.imr_multiaddr.s_addr == addr && 1641 i->multi.imr_ifindex == ifindex) |
1646 goto done; | 1642 goto done; |
1647 } | |
1648 count++; 1649 } 1650 err = -ENOBUFS; | 1643 count++; 1644 } 1645 err = -ENOBUFS; |
1651 if (iml == NULL || count >= sysctl_igmp_max_memberships) | 1646 if (count >= sysctl_igmp_max_memberships) |
1652 goto done; | 1647 goto done; |
1648 iml = (struct ip_mc_socklist *)sock_kmalloc(sk,sizeof(*iml),GFP_KERNEL); 1649 if (iml == NULL) 1650 goto done; 1651 |
|
1653 memcpy(&iml->multi, imr, sizeof(*imr)); 1654 iml->next = inet->mc_list; | 1652 memcpy(&iml->multi, imr, sizeof(*imr)); 1653 iml->next = inet->mc_list; |
1655 iml->count = 1; | |
1656 iml->sflist = NULL; 1657 iml->sfmode = MCAST_EXCLUDE; 1658 inet->mc_list = iml; 1659 ip_mc_inc_group(in_dev, addr); | 1654 iml->sflist = NULL; 1655 iml->sfmode = MCAST_EXCLUDE; 1656 inet->mc_list = iml; 1657 ip_mc_inc_group(in_dev, addr); |
1660 iml = NULL; | |
1661 err = 0; | 1658 err = 0; |
1662 | |
1663done: 1664 rtnl_shunlock(); | 1659done: 1660 rtnl_shunlock(); |
1665 if (iml) 1666 sock_kfree_s(sk, iml, sizeof(*iml)); | |
1667 return err; 1668} 1669 1670static int ip_mc_leave_src(struct sock *sk, struct ip_mc_socklist *iml, 1671 struct in_device *in_dev) 1672{ 1673 int err; 1674 --- 24 unchanged lines hidden (view full) --- 1699 if (iml->multi.imr_multiaddr.s_addr==imr->imr_multiaddr.s_addr && 1700 iml->multi.imr_address.s_addr==imr->imr_address.s_addr && 1701 (!imr->imr_ifindex || iml->multi.imr_ifindex==imr->imr_ifindex)) { 1702 struct in_device *in_dev; 1703 1704 in_dev = inetdev_by_index(iml->multi.imr_ifindex); 1705 if (in_dev) 1706 (void) ip_mc_leave_src(sk, iml, in_dev); | 1661 return err; 1662} 1663 1664static int ip_mc_leave_src(struct sock *sk, struct ip_mc_socklist *iml, 1665 struct in_device *in_dev) 1666{ 1667 int err; 1668 --- 24 unchanged lines hidden (view full) --- 1693 if (iml->multi.imr_multiaddr.s_addr==imr->imr_multiaddr.s_addr && 1694 iml->multi.imr_address.s_addr==imr->imr_address.s_addr && 1695 (!imr->imr_ifindex || iml->multi.imr_ifindex==imr->imr_ifindex)) { 1696 struct in_device *in_dev; 1697 1698 in_dev = inetdev_by_index(iml->multi.imr_ifindex); 1699 if (in_dev) 1700 (void) ip_mc_leave_src(sk, iml, in_dev); |
1707 if (--iml->count) { 1708 rtnl_unlock(); 1709 if (in_dev) 1710 in_dev_put(in_dev); 1711 return 0; 1712 } | |
1713 1714 *imlp = iml->next; 1715 1716 if (in_dev) { 1717 ip_mc_dec_group(in_dev, imr->imr_multiaddr.s_addr); 1718 in_dev_put(in_dev); 1719 } 1720 rtnl_unlock(); --- 29 unchanged lines hidden (view full) --- 1750 1751 if (!in_dev) { 1752 err = -ENODEV; 1753 goto done; 1754 } 1755 err = -EADDRNOTAVAIL; 1756 1757 for (pmc=inet->mc_list; pmc; pmc=pmc->next) { | 1701 1702 *imlp = iml->next; 1703 1704 if (in_dev) { 1705 ip_mc_dec_group(in_dev, imr->imr_multiaddr.s_addr); 1706 in_dev_put(in_dev); 1707 } 1708 rtnl_unlock(); --- 29 unchanged lines hidden (view full) --- 1738 1739 if (!in_dev) { 1740 err = -ENODEV; 1741 goto done; 1742 } 1743 err = -EADDRNOTAVAIL; 1744 1745 for (pmc=inet->mc_list; pmc; pmc=pmc->next) { |
1758 if (memcmp(&pmc->multi, mreqs, 2*sizeof(__u32)) == 0) | 1746 if (pmc->multi.imr_multiaddr.s_addr == imr.imr_multiaddr.s_addr 1747 && pmc->multi.imr_ifindex == imr.imr_ifindex) |
1759 break; 1760 } 1761 if (!pmc) /* must have a prior join */ 1762 goto done; 1763 /* if a source filter was set, must be the same mode as before */ 1764 if (pmc->sflist) { 1765 if (pmc->sfmode != omode) 1766 goto done; --- 707 unchanged lines hidden --- | 1748 break; 1749 } 1750 if (!pmc) /* must have a prior join */ 1751 goto done; 1752 /* if a source filter was set, must be the same mode as before */ 1753 if (pmc->sflist) { 1754 if (pmc->sfmode != omode) 1755 goto done; --- 707 unchanged lines hidden --- |