📄 sockunion.c
字号:
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 + -