mcast_set_if.c 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. #include "unp.h"
  2. #include <net/if.h>
  3. int
  4. mcast_set_if(int sockfd, const char *ifname, u_int ifindex)
  5. {
  6. switch (sockfd_to_family(sockfd)) {
  7. case AF_INET: {
  8. struct in_addr inaddr;
  9. struct ifreq ifreq;
  10. if (ifindex > 0) {
  11. if (if_indextoname(ifindex, ifreq.ifr_name) == NULL) {
  12. errno = ENXIO; /* i/f index not found */
  13. return(-1);
  14. }
  15. goto doioctl;
  16. } else if (ifname != NULL) {
  17. strncpy(ifreq.ifr_name, ifname, IFNAMSIZ);
  18. doioctl:
  19. if (ioctl(sockfd, SIOCGIFADDR, &ifreq) < 0)
  20. return(-1);
  21. memcpy(&inaddr,
  22. &((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr,
  23. sizeof(struct in_addr));
  24. } else
  25. inaddr.s_addr = htonl(INADDR_ANY); /* remove prev. set default */
  26. return(setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_IF,
  27. &inaddr, sizeof(struct in_addr)));
  28. }
  29. #ifdef IPV6
  30. case AF_INET6: {
  31. u_int idx;
  32. if ( (idx = ifindex) == 0) {
  33. if (ifname == NULL) {
  34. errno = EINVAL; /* must supply either index or name */
  35. return(-1);
  36. }
  37. if ( (idx = if_nametoindex(ifname)) == 0) {
  38. errno = ENXIO; /* i/f name not found */
  39. return(-1);
  40. }
  41. }
  42. return(setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_IF,
  43. &idx, sizeof(idx)));
  44. }
  45. #endif
  46. default:
  47. errno = EAFNOSUPPORT;
  48. return(-1);
  49. }
  50. }
  51. void
  52. Mcast_set_if(int sockfd, const char *ifname, u_int ifindex)
  53. {
  54. if (mcast_set_if(sockfd, ifname, ifindex) < 0)
  55. err_sys("mcast_set_if error");
  56. }