⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 net.c

📁 wifi 无线网络路由协议OLSR linux下C代码
💻 C
📖 第 1 页 / 共 2 页
字号:
      perror("SO_REUSEADDR failed");      close(sock);      return (-1);    }  if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on)) < 0)     {      perror("SO_REUSEPORT failed");      return (-1);    }#ifdef IPV6_RECVPKTINFO  if (setsockopt(sock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof(on)) < 0)    {      perror("IPV6_RECVPKTINFO failed");      return (-1);    }#elif defined IPV6_PKTINFO    if (setsockopt(sock, IPPROTO_IPV6, IPV6_PKTINFO, &on, sizeof(on)) < 0)      {	perror("IPV6_PKTINFO failed");	return (-1);      }#endif  if (bind(sock, (struct sockaddr *)sin, sizeof (*sin)) < 0)     {      perror("bind");      syslog(LOG_ERR, "bind: %m");      close(sock);      return (-1);    }  if (fcntl(sock, F_SETFL, O_NONBLOCK) == -1)    syslog(LOG_ERR, "fcntl O_NONBLOCK: %m\n");  return (sock);}intjoin_mcast(struct interface *ifs, int sock){  /* See netinet6/in6.h */  struct ipv6_mreq mcastreq;  COPY_IP(&mcastreq.ipv6mr_multiaddr, &ifs->int6_multaddr.sin6_addr);  mcastreq.ipv6mr_interface = ifs->if_index;  OLSR_PRINTF(3, "Interface %s joining multicast %s...",	ifs->int_name, olsr_ip_to_string((union olsr_ip_addr *)&ifs->int6_multaddr.sin6_addr));  /* rfc 3493 */#ifdef IPV6_JOIN_GROUP  /* Join reciever group */  if(setsockopt(sock, 		IPPROTO_IPV6, 		IPV6_JOIN_GROUP, 		(char *)&mcastreq, 		sizeof(struct ipv6_mreq))      < 0)#else /* rfc 2133, obsoleted */  /* Join receiver group */  if(setsockopt(sock, 		IPPROTO_IPV6, 		IPV6_ADD_MEMBERSHIP, 		(char *)&mcastreq, 		sizeof(struct ipv6_mreq))      < 0)#endif     {      perror("Join multicast send");      return -1;    }    if(setsockopt(sock, 		IPPROTO_IPV6, 		IPV6_MULTICAST_IF, 		(char *)&mcastreq.ipv6mr_interface, 		sizeof(mcastreq.ipv6mr_interface))      < 0)    {      perror("Set multicast if");      return -1;    }  OLSR_PRINTF(3, "OK\n");  return 0;}int get_ipv6_address(char *ifname, struct sockaddr_in6 *saddr6, int scope_in){  struct ifaddrs *ifap, *ifa;  const struct sockaddr_in6 *sin6 = NULL;  struct in6_ifreq ifr6;  int found = 0;  int s6;  u_int32_t flags6;  if (getifaddrs(&ifap) != 0)    {      OLSR_PRINTF(3, "get_ipv6_address: getifaddrs() failed.\n");      return 0;    }  for (ifa = ifap; ifa; ifa = ifa->ifa_next)    {      if (ifa->ifa_addr->sa_family == AF_INET6 &&          strcmp(ifa->ifa_name, ifname) == 0)        {	  sin6 = (const struct sockaddr_in6 *)ifa->ifa_addr;	  if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))	    continue;	  strncpy(ifr6.ifr_name, ifname, sizeof(ifr6.ifr_name));	  if ((s6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)	    {	      OLSR_PRINTF(3, "socket(AF_INET6,SOCK_DGRAM)");	      break;	    }	  ifr6.ifr_addr = *sin6;	  if (ioctl(s6, SIOCGIFAFLAG_IN6, &ifr6) < 0)	    {	      OLSR_PRINTF(3, "ioctl(SIOCGIFAFLAG_IN6)");	      close(s6);	      break;	    }	  close(s6);	  flags6 = ifr6.ifr_ifru.ifru_flags6;	  if ((flags6 & IN6_IFF_ANYCAST) != 0)	    continue;	  if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))	    {	      if (scope_in)		{		  memcpy(&saddr6->sin6_addr, &sin6->sin6_addr,			 sizeof(struct in6_addr));		  found = 1;		  break;		}	    }	  else	    {	      if (scope_in == 0)		{		  memcpy(&saddr6->sin6_addr, &sin6->sin6_addr,			 sizeof(struct in6_addr));		  found = 1;		  break;		}	    }	}    }  freeifaddrs(ifap);  if (found)    return 1;  return 0;}/** * Wrapper for sendto(2) */#ifdef SPOOFstatic u_int16_t ip_id = 0;#endif /* SPOOF */ssize_tolsr_sendto(int s, 	    const void *buf, 	    size_t len, 	    int flags, 	    const struct sockaddr *to, 	    socklen_t tolen){#ifdef SPOOF  /* IPv4 for now! */  libnet_t *context;  char errbuf[LIBNET_ERRBUF_SIZE];  libnet_ptag_t udp_tag, ip_tag, ether_tag;  unsigned char enet_broadcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};  int status;  struct sockaddr_in *to_in = (struct sockaddr_in *) to;  u_int32_t destip;  struct interface *iface;  udp_tag = ip_tag = ether_tag = 0;  destip = to_in->sin_addr.s_addr;  iface = if_ifwithsock (s);  /* initialize libnet */  context = libnet_init(LIBNET_LINK, iface->int_name, errbuf);  if (context == NULL)    {      OLSR_PRINTF (1, "libnet init: %s\n", libnet_geterror (context));      return (0);    }  /* initialize IP ID field if necessary */  if (ip_id == 0)    {      ip_id = (u_int16_t) (arc4random () & 0xffff);    }  udp_tag = libnet_build_udp (698, 				/* src port */			      698,				/* dest port */			      LIBNET_UDP_H + len,		/* length */			      0,				/* checksum */			      buf,				/* payload */			      len,				/* payload size */			      context,				/* context */			      udp_tag);				/* pblock */  if (udp_tag == -1)    {      OLSR_PRINTF (1, "libnet UDP header: %s\n", libnet_geterror (context));	return (0);    }  ip_tag = libnet_build_ipv4 (LIBNET_IPV4_H + LIBNET_UDP_H + len, /* len */			      0,				/* TOS */			      ip_id++,				/* IP id */			      0,				/* IP frag */			      1,				/* IP TTL */			      IPPROTO_UDP,			/* protocol */			      0,				/* checksum */			      libnet_get_ipaddr4 (context),	/* src IP */			      destip,				/* dest IP */			      NULL,				/* payload */			      0,				/* payload len */			      context,				/* context */			      ip_tag);				/* pblock */  if (ip_tag == -1)    {      OLSR_PRINTF (1, "libnet IP header: %s\n", libnet_geterror (context));      return (0);    }  ether_tag = libnet_build_ethernet (enet_broadcast,    	/* ethernet dest */				     libnet_get_hwaddr (context), /* ethernet source */				     ETHERTYPE_IP,		/* protocol type */				     NULL,        		/* payload */				     0,           		/* payload size */				     context,     		/* libnet handle */				     ether_tag);  		/* pblock tag */  if (ether_tag == -1)    {      OLSR_PRINTF (1, "libnet ethernet header: %s\n", libnet_geterror (context));      return (0);    }   status = libnet_write (context);  if (status == -1)    {      OLSR_PRINTF (1, "libnet packet write: %s\n", libnet_geterror (context));      return (0);    }  libnet_destroy (context);  return (len);#else  return sendto(s, buf, len, flags, to, tolen);#endif}/** * Wrapper for recvfrom(2) */ssize_t  olsr_recvfrom(int  s, 	      void *buf, 	      size_t len, 	      int flags, 	      struct sockaddr *from,	      socklen_t *fromlen){  struct msghdr mhdr;  struct iovec iov;  union {	struct cmsghdr cmsg;  	unsigned char chdr[4096];  } cmu;  struct cmsghdr *cm;  struct sockaddr_dl *sdl;  struct sockaddr_in *sin = (struct sockaddr_in *) from; //XXX  struct sockaddr_in6 *sin6;  struct in6_addr *iaddr6;  struct in6_pktinfo *pkti;  struct interface *ifc;  char addrstr[INET6_ADDRSTRLEN];  char iname[IFNAMSIZ];  int count;  memset(&mhdr, 0, sizeof(mhdr));  memset(&iov, 0, sizeof(iov));  mhdr.msg_name = (caddr_t) from;  mhdr.msg_namelen = *fromlen;  mhdr.msg_iov = &iov;  mhdr.msg_iovlen = 1;  mhdr.msg_control = (caddr_t) &cmu;  mhdr.msg_controllen = sizeof (cmu);  iov.iov_len = len;  iov.iov_base = buf;  count = recvmsg (s, &mhdr, MSG_DONTWAIT);  if (count <= 0)    {      return (count);    }  /* this needs to get communicated back to caller */  *fromlen = mhdr.msg_namelen;  if (olsr_cnf->ip_version == AF_INET6)    {      for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(&mhdr); cm;	   cm = (struct cmsghdr *)CMSG_NXTHDR(&mhdr, cm))	{	  if (cm->cmsg_level == IPPROTO_IPV6 && cm->cmsg_type == IPV6_PKTINFO)	    {	      pkti = (struct in6_pktinfo *) CMSG_DATA(cm);	      iaddr6 = &pkti->ipi6_addr;	      if_indextoname(pkti->ipi6_ifindex, iname);	    }	}    }  else    {      cm = &cmu.cmsg;      sdl = (struct sockaddr_dl *) CMSG_DATA (cm);      memset (iname, 0, sizeof (iname));      memcpy (iname, sdl->sdl_data, sdl->sdl_nlen);    }  ifc = if_ifwithsock (s);  sin6 = (struct sockaddr_in6 *)from;  OLSR_PRINTF (4, "%d bytes from %s, socket associated %s really received on %s\n",	       count,	       (olsr_cnf->ip_version == AF_INET6) ?		 inet_ntop(AF_INET6, (char *)&sin6->sin6_addr, addrstr,				     INET6_ADDRSTRLEN):	         inet_ntoa (sin->sin_addr),	       ifc->int_name,	       iname);  if (strcmp (ifc->int_name, iname) != 0)    {      return (0);    }  return (count);}/** * Wrapper for select(2) */intolsr_select(int nfds,	    fd_set *readfds,	    fd_set *writefds,	    fd_set *exceptfds,	    struct timeval *timeout){  return select(nfds,		readfds,		writefds,		exceptfds,		timeout);}int check_wireless_interface(char *ifname){#if defined __FreeBSD__ &&  !defined FBSD_NO_80211/* From FreeBSD ifconfig/ifieee80211.c ieee80211_status() */  struct ieee80211req ireq;  u_int8_t data[32];  memset(&ireq, 0, sizeof(ireq));  strlcpy(ireq.i_name, ifname, sizeof(ireq.i_name));  ireq.i_data = &data;  ireq.i_type = IEEE80211_IOC_SSID;  ireq.i_val = -1;  return (ioctl(olsr_cnf->ioctl_s, SIOCG80211, &ireq) >= 0) ? 1 : 0;#else  return 0;#endif}#include <sys/sockio.h>intcalculate_if_metric(char *ifname){  if(check_wireless_interface(ifname))    {      /* Wireless */      return 1;    }  else    {      /* Ethernet */#if 0      /* Andreas: Perhaps SIOCGIFMEDIA is the way to do this? */      struct ifmediareq ifm;      memset(&ifm, 0, sizeof(ifm));      strlcpy(ifm.ifm_name, ifname, sizeof(ifm.ifm_name));      if(ioctl(olsr_cnf->ioctl_s, SIOCGIFMEDIA, &ifm) < 0)	{	  OLSR_PRINTF(1, "Error SIOCGIFMEDIA(%s)\n", ifm.ifm_name);	  return WEIGHT_ETHERNET_DEFAULT;	}      OLSR_PRINTF(1, "%s: STATUS 0x%08x\n", ifm.ifm_name, ifm.ifm_status);#endif      return WEIGHT_ETHERNET_DEFAULT;    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -