コード例 #1
0
int main() {
  int n=-1;
  mh.msg_name=&sa4;
  mh.msg_namelen=sizeof(sa4);
  mh.msg_iov=&iv;
  mh.msg_iovlen=1;
  iv.iov_base=buf;
  iv.iov_len=PKGSIZE;
  mh.msg_control=abuf;
  mh.msg_controllen=sizeof(abuf);

  if (gethostname(myhostname,64)==-1) {
    perror("gethostname");
    return 1;
  }
  namelen=strlen(myhostname);

  init_sockets(&s6,&s4,5353,"\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfb","\xe0\x00\x00\xfb");
  init_sockets(&ls6,&ls4,5355,"\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x03","\xe0\x00\x00\xfc");

  pfd[0].events=pfd[1].events=pfd[2].events=pfd[3].events=POLLIN;
  if (s6!=-1) pfd[++n].fd=s6;
  if (s4!=-1) pfd[++n].fd=s4;
  if (ls6!=-1) pfd[++n].fd=ls6;
  if (ls4!=-1) pfd[++n].fd=ls4;
  if (!++n)
    return 2;
  for (;;) {
    int i;
    switch (poll(pfd,n,5*1000)) {
    case -1:
      if (errno==EINTR) continue;
      perror("poll");
      return 1;
    case 0:
      continue;
    }
    for (i=0; i<n; ++i)
      if (pfd[i].revents & POLLIN) {
	if (pfd[i].fd==s6 || pfd[i].fd==ls6)
	  recv6(pfd[i].fd);
	else
	  recv4(pfd[i].fd);
      }
  }
  return 0;
}
コード例 #2
0
ファイル: dnsd.c プロジェクト: EmuxEvans/CompositeFreeRTOS
int main() {
  mh.msg_name=&sa4;
  mh.msg_namelen=sizeof(sa4);
  mh.msg_iov=&iv;
  mh.msg_iovlen=1;
  iv.iov_base=buf;
  iv.iov_len=PKGSIZE;
  mh.msg_control=abuf;
  mh.msg_controllen=sizeof(abuf);

  if (gethostname(myhostname,64)==-1) {
    perror("gethostname");
    return 1;
  }
  namelen=strlen(myhostname);
  s6=socket(PF_INET6,SOCK_DGRAM,IPPROTO_UDP);
  s4=socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP);
  if (s4==-1 && s6==-1) {
    perror("socket");
    return 2;
  }
  if (s6!=-1) {
    memset(&sa6,0,sizeof(sa6));
    sa6.sin6_family=PF_INET6;
    sa6.sin6_port=htons(5353);
    if (bind(s6,(struct sockaddr*)&sa6,sizeof(struct sockaddr_in6))==-1) {
      perror("bind IPv6");
      close(s6);
      s6=-1;
    }
  }
  if (s4!=-1) {
    memset(&sa4,0,sizeof(sa4));
    sa4.sin_family=PF_INET;
    sa4.sin_port=htons(5353);
    if (bind(s4,(struct sockaddr*)&sa4,sizeof(struct sockaddr_in))==-1) {
      if (errno!=EADDRINUSE || s6==-1)
	perror("bind IPv4");
      close(s4);
      s4=-1;
    }
  }
  if (s4==-1 && s6==-1) return 2;

  {
    int val=255;
    int one=1;
    if (s6!=-1) {
      struct ipv6_mreq opt;
      setsockopt(s6,IPPROTO_IPV6,IPV6_UNICAST_HOPS,&val,sizeof(val));
      setsockopt(s6,IPPROTO_IPV6,IPV6_MULTICAST_LOOP,&one,sizeof(one));
      memcpy(&opt.ipv6mr_multiaddr,"\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfb",16);
      opt.ipv6mr_interface=0;
      setsockopt(s6,IPPROTO_IPV6,IPV6_ADD_MEMBERSHIP,&opt,sizeof opt);
//      setsockopt(s6,IPPROTO_IPV6,IPV6_PKTINFO,&one,sizeof one);
    }
    {
      struct ip_mreq opt;
      int s=(s4==-1?s6:s4);
      setsockopt(s,SOL_IP,IP_TTL,&val,sizeof(val));
      memcpy(&opt.imr_multiaddr.s_addr,"\xe0\x00\x00\xfb",4);
      opt.imr_interface.s_addr=0;
      setsockopt(s,IPPROTO_IP,IP_ADD_MEMBERSHIP,&opt,sizeof(opt));
      setsockopt(s,SOL_IP,IP_PKTINFO,&one,sizeof one);
    }
  }

  for (;;) {
    /* 1500 is the MTU for UDP, I figure we won't longer packets */
    /* add 1 to be able to add \0 */
    int len;
    int interface=0;
    if (s4!=-1 && s6!=-1) {
      if (s4!=-1) {
	recv4();
#if 0
	if ((len=recvmsg(s4,&mh,0))==-1) {
	  perror("recvmsg");
	  return 3;
	}
	peer=(struct sockaddr*)&sa4;
	sl=sizeof(sa4);

	for (x=CMSG_FIRSTHDR(&mh); x; x=CMSG_NXTHDR(&mh,x))
	  if (x->cmsg_level==SOL_IP && x->cmsg_type==IP_PKTINFO) {
	    struct in_pktinfo* y=(struct in_pktinfo*)(CMSG_DATA(x));
	    interface=y->ipi_ifindex;
	    break;
	  }

	handle(s4,buf,len,interface);
#endif
      } else {
	recv6();
#if 0
	sl=sizeof(sa6);
	if ((len=recvfrom(s6,buf,PKGSIZE,0,(struct sockaddr*)&sa6,&sl))==-1) {
	  perror("recvfrom");
	  return 3;
	}
	peer=(struct sockaddr*)&sa6;

	handle(s6,buf,len,sa6.sin6_scope_id);
#endif
      }
    } else {
      pfd[0].fd=s4; pfd[0].events=POLLIN;
      pfd[1].fd=s6; pfd[1].events=POLLIN;
      switch (poll(pfd,2,5*1000)) {
      case -1:
	if (errno==EINTR) continue;
	perror("poll");
	return 1;
      case 0:
	continue;
      }
      if (pfd[0].revents & POLLIN) {
	recv4();
#if 0
	if ((len=recvmsg(s4,&mh,0))==-1) {
	  perror("recvmsg");
	  return 3;
	}
	peer=(struct sockaddr*)&sa4;
	sl=sizeof(sa4);

	for (x=CMSG_FIRSTHDR(&mh); x; x=CMSG_NXTHDR(&mh,x))
	  if (x->cmsg_level==SOL_IP && x->cmsg_type==IP_PKTINFO) {
	    struct in_pktinfo* y=(struct in_pktinfo*)(CMSG_DATA(x));
	    interface=y->ipi_ifindex;
	    break;
	  }

	handle(s4,buf,len,interface);
#endif
      }
      if (pfd[1].revents & POLLIN) {
	recv6();
#if 0
	sl=sizeof(sa6);
	if ((len=recvfrom(s6,buf,sizeof(buf),0,(struct sockaddr*)&sa6,&sl))==-1) {
	  perror("recvfrom");
	  return 3;
	}
	peer=(struct sockaddr*)&sa6;
	handle(s6,buf,len,sa6.sin6_scope_id);
#endif
      }
    }
  }
  return 0;
}