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

📄 sockunion.c

📁 大名鼎鼎的路由器源码。程序分ZEBRA、OSPFRIP等3个包。程序框架采用一个路由协议一个进程的方式
💻 C
📖 第 1 页 / 共 2 页
字号:
  fcntl (fd, F_SETFL, val);  return connect_in_progress;}/* Make socket from sockunion union. */intsockunion_stream_socket (union sockunion *su){  int sock;  if (su->sa.sa_family == 0)    su->sa.sa_family = AF_INET_UNION;  sock = socket (su->sa.sa_family, SOCK_STREAM, 0);  if (sock < 0)    zlog (NULL, LOG_WARNING, "can't make socket sockunion_stream_socket");  return sock;}/* Bind socket to specified address. */intsockunion_bind (int sock, union sockunion *su, unsigned short port, 		union sockunion *su_addr){  int size = 0;  int ret;  if (su->sa.sa_family == AF_INET)    {      size = sizeof (struct sockaddr_in);      su->sin.sin_port = htons (port);#ifdef HAVE_SIN_LEN      su->sin.sin_len = size;#endif /* HAVE_SIN_LEN */      if (su_addr == NULL)	su->sin.sin_addr.s_addr = htonl (INADDR_ANY);    }#ifdef HAVE_IPV6  else if (su->sa.sa_family == AF_INET6)    {      size = sizeof (struct sockaddr_in6);      su->sin6.sin6_port = htons (port);#ifdef SIN6_LEN      su->sin6.sin6_len = size;#endif /* SIN6_LEN */      if (su_addr == NULL)	{#if defined(LINUX_IPV6) || defined(NRL)	  memset (&su->sin6.sin6_addr, 0, sizeof (struct in6_addr));#else	  su->sin6.sin6_addr = in6addr_any;#endif /* LINUX_IPV6 */	}    }#endif /* HAVE_IPV6 */    ret = bind (sock, (struct sockaddr *)su, size);  if (ret < 0)    zlog (NULL, LOG_WARNING, "can't bind socket : %s", strerror (errno));  return ret;}intsockopt_reuseaddr (int sock){  int ret;  int on = 1;  ret = setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, 		    (void *) &on, sizeof (on));  if (ret < 0)    {      zlog (NULL, LOG_WARNING, "can't set sockopt SO_REUSEADDR to socket %d", sock);      return -1;    }  return 0;}#ifdef SO_REUSEPORTintsockopt_reuseport (int sock){  int ret;  int on = 1;  ret = setsockopt (sock, SOL_SOCKET, SO_REUSEPORT, 		    (void *) &on, sizeof (on));  if (ret < 0)    {      zlog (NULL, LOG_WARNING, "can't set sockopt SO_REUSEADDR to socket %d", sock);      return -1;    }  return 0;}#elseintsockopt_reuseport (int sock){  return 0;}#endif /* 0 */intsockopt_ttl (int family, int sock, int ttl){  int ret;#ifdef IP_TTL  if (family == AF_INET)    {      ret = setsockopt (sock, IPPROTO_IP, IP_TTL, 			(void *) &ttl, sizeof (int));      if (ret < 0)	{	  zlog (NULL, LOG_WARNING, "can't set sockopt IP_TTL %d to socket %d", ttl, sock);	  return -1;	}      return 0;    }#endif /* IP_TTL */#ifdef HAVE_IPV6  if (family == AF_INET6)    {      ret = setsockopt (sock, IPPROTO_IPV6, IPV6_UNICAST_HOPS, 			(void *) &ttl, sizeof (int));      if (ret < 0)	{	  zlog (NULL, LOG_WARNING, "can't set sockopt IPV6_UNICAST_HOPS %d to socket %d",		    ttl, sock);	  return -1;	}      return 0;    }#endif /* HAVE_IPV6 */  return 0;}/* If same family and same prefix return 1. */intsockunion_same (union sockunion *su1, union sockunion *su2){  int ret = 0;  if (su1->sa.sa_family != su2->sa.sa_family)    return 0;  switch (su1->sa.sa_family)    {    case AF_INET:      ret = memcmp (&su1->sin.sin_addr, &su2->sin.sin_addr,		    sizeof (struct in_addr));      break;#ifdef HAVE_IPV6    case AF_INET6:      ret = memcmp (&su1->sin6.sin6_addr, &su2->sin6.sin6_addr,		    sizeof (struct in6_addr));      break;#endif /* HAVE_IPV6 */    }  if (ret == 0)    return 1;  else    return 0;}/* After TCP connection is established.  Get local address and port. */union sockunion *sockunion_getsockname (int fd){  int ret;  int len;  union  {    struct sockaddr sa;    struct sockaddr_in sin;#ifdef HAVE_IPV6    struct sockaddr_in6 sin6;#endif /* HAVE_IPV6 */    char tmp_buffer[128];  } name;  union sockunion *su;  memset (&name, 0, sizeof name);  len = sizeof name;  ret = getsockname (fd, (struct sockaddr *)&name, &len);  if (ret < 0)    {      zlog_warn ("Can't get local address and port by getsockname: %s",		 strerror (errno));      return NULL;    }  if (name.sa.sa_family == AF_INET)    {      su = XCALLOC (MTYPE_TMP, sizeof (union sockunion));      memcpy (su, &name, sizeof (struct sockaddr_in));      return su;    }#ifdef HAVE_IPV6  if (name.sa.sa_family == AF_INET6)    {      su = XCALLOC (MTYPE_TMP, sizeof (union sockunion));      memcpy (su, &name, sizeof (struct sockaddr_in6));      if (IN6_IS_ADDR_V4MAPPED (&su->sin6.sin6_addr))	{	  struct sockaddr_in sin;	  sin.sin_family = AF_INET;	  memcpy (&sin.sin_addr, ((char *)&su->sin6.sin6_addr) + 12, 4);	  sin.sin_port = su->sin6.sin6_port;	  memcpy (su, &sin, sizeof (struct sockaddr_in));	}      return su;    }#endif /* HAVE_IPV6 */  return NULL;}/* After TCP connection is established.  Get remote address and port. */union sockunion *sockunion_getpeername (int fd){  int ret;  int len;  union  {    struct sockaddr sa;    struct sockaddr_in sin;#ifdef HAVE_IPV6    struct sockaddr_in6 sin6;#endif /* HAVE_IPV6 */    char tmp_buffer[128];  } name;  union sockunion *su;  memset (&name, 0, sizeof name);  len = sizeof name;  ret = getpeername (fd, (struct sockaddr *)&name, &len);  if (ret < 0)    {      zlog (NULL, LOG_WARNING, "Can't get remote address and port: %s",	    strerror (errno));      return NULL;    }  if (name.sa.sa_family == AF_INET)    {      su = XCALLOC (MTYPE_TMP, sizeof (union sockunion));      memcpy (su, &name, sizeof (struct sockaddr_in));      return su;    }#ifdef HAVE_IPV6  if (name.sa.sa_family == AF_INET6)    {      su = XCALLOC (MTYPE_TMP, sizeof (union sockunion));      memcpy (su, &name, sizeof (struct sockaddr_in6));      if (IN6_IS_ADDR_V4MAPPED (&su->sin6.sin6_addr))	{	  struct sockaddr_in sin;	  sin.sin_family = AF_INET;	  memcpy (&sin.sin_addr, ((char *)&su->sin6.sin6_addr) + 12, 4);	  sin.sin_port = su->sin6.sin6_port;	  memcpy (su, &sin, sizeof (struct sockaddr_in));	}      return su;    }#endif /* HAVE_IPV6 */  return NULL;}/* Print sockunion structure */voidsockunion_print (union sockunion *su){  if (su == NULL)    return;  switch (su->sa.sa_family)     {    case AF_INET:      printf ("%s\n", inet_ntoa (su->sin.sin_addr));      break;#ifdef HAVE_IPV6    case AF_INET6:      {	char buf [64];	printf ("%s\n", inet_ntop (AF_INET6, &(su->sin6.sin6_addr),				 buf, sizeof (buf)));      }      break;#endif /* HAVE_IPV6 */#ifdef AF_LINK    case AF_LINK:      {	struct sockaddr_dl *sdl;	sdl = (struct sockaddr_dl *)&(su->sa);	printf ("link#%d\n", sdl->sdl_index);      }      break;#endif /* AF_LINK */    default:      printf ("af_unknown %d\n", su->sa.sa_family);      break;    }}#ifdef HAVE_IPV6intin6addr_cmp (struct in6_addr *addr1, struct in6_addr *addr2){  int i;  u_char *p1, *p2;  p1 = (u_char *)addr1;  p2 = (u_char *)addr2;  for (i = 0; i < sizeof (struct in6_addr); i++)    {      if (p1[i] > p2[i])	return 1;      else if (p1[i] < p2[i])	return -1;    }  return 0;}#endif /* HAVE_IPV6 */intsockunion_cmp (union sockunion *su1, union sockunion *su2){  if (su1->sa.sa_family > su2->sa.sa_family)    return 1;  if (su1->sa.sa_family < su2->sa.sa_family)    return -1;  if (su1->sa.sa_family == AF_INET)    {      if (ntohl (su1->sin.sin_addr.s_addr) == ntohl (su2->sin.sin_addr.s_addr))	return 0;      if (ntohl (su1->sin.sin_addr.s_addr) > ntohl (su2->sin.sin_addr.s_addr))	return 1;      else	return -1;    }#ifdef HAVE_IPV6  if (su1->sa.sa_family == AF_INET6)    return in6addr_cmp (&su1->sin6.sin6_addr, &su2->sin6.sin6_addr);#endif /* HAVE_IPV6 */  return 0;}/* Duplicate sockunion. */union sockunion *sockunion_dup (union sockunion *su){  union sockunion *dup = XCALLOC (MTYPE_SOCKUNION, sizeof (union sockunion));  memcpy (dup, su, sizeof (union sockunion));  return dup;}voidsockunion_free (union sockunion *su){  XFREE (MTYPE_SOCKUNION, su);}

⌨️ 快捷键说明

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