/* After TCP connection is established. Get remote address and port. */ union sockunion *sockunion_getpeername(int fd) { int ret; socklen_t len; union { struct sockaddr sa; struct sockaddr_in sin; struct sockaddr_in6 sin6; 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_warn("Can't get remote address and port: %s", safe_strerror(errno)); return NULL; } if (name.sa.sa_family == AF_INET) { su = XCALLOC(MTYPE_SOCKUNION, sizeof(union sockunion)); memcpy(su, &name, sizeof(struct sockaddr_in)); return su; } if (name.sa.sa_family == AF_INET6) { su = XCALLOC(MTYPE_SOCKUNION, sizeof(union sockunion)); memcpy(su, &name, sizeof(struct sockaddr_in6)); sockunion_normalise_mapped(su); return su; } return NULL; }
/* Return accepted new socket file descriptor. */ int sockunion_accept(int sock, union sockunion *su) { socklen_t len; int client_sock; len = sizeof(union sockunion); client_sock = accept(sock, (struct sockaddr *)su, &len); sockunion_normalise_mapped(su); return client_sock; }
/* After TCP connection is established. Get local address and port. */ union sockunion * sockunion_getsockname (int fd) { int ret; socklen_t 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", safe_strerror (errno)); */ return NULL; } if (name.sa.sa_family == AF_INET) { su = XCALLOC (MTYPE_SOCKUNION, 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_SOCKUNION, sizeof (union sockunion)); memcpy (su, &name, sizeof (struct sockaddr_in6)); sockunion_normalise_mapped (su); return su; } #endif /* HAVE_IPV6 */ return NULL; }