1*433d6423SLionel Sambuc #include <sys/cdefs.h> 2*433d6423SLionel Sambuc #include "namespace.h" 3*433d6423SLionel Sambuc 4*433d6423SLionel Sambuc #include <errno.h> 5*433d6423SLionel Sambuc #include <stdio.h> 6*433d6423SLionel Sambuc #include <string.h> 7*433d6423SLionel Sambuc #include <sys/ioctl.h> 8*433d6423SLionel Sambuc #include <sys/socket.h> 9*433d6423SLionel Sambuc #include <netinet/in.h> 10*433d6423SLionel Sambuc 11*433d6423SLionel Sambuc #include <net/gen/in.h> 12*433d6423SLionel Sambuc #include <net/gen/tcp.h> 13*433d6423SLionel Sambuc #include <net/gen/tcp_io.h> 14*433d6423SLionel Sambuc #include <net/gen/udp.h> 15*433d6423SLionel Sambuc #include <net/gen/udp_io.h> 16*433d6423SLionel Sambuc #include <sys/un.h> 17*433d6423SLionel Sambuc 18*433d6423SLionel Sambuc #define DEBUG 0 19*433d6423SLionel Sambuc 20*433d6423SLionel Sambuc static int _tcp_getpeername(int sock, struct sockaddr *__restrict address, 21*433d6423SLionel Sambuc socklen_t *__restrict address_len, nwio_tcpconf_t *tcpconfp); 22*433d6423SLionel Sambuc 23*433d6423SLionel Sambuc static int _udp_getpeername(int sock, struct sockaddr *__restrict address, 24*433d6423SLionel Sambuc socklen_t *__restrict address_len, nwio_udpopt_t *tcpconfp); 25*433d6423SLionel Sambuc 26*433d6423SLionel Sambuc static int _uds_getpeername(int sock, struct sockaddr *__restrict address, 27*433d6423SLionel Sambuc socklen_t *__restrict address_len, struct sockaddr_un *uds_addr); 28*433d6423SLionel Sambuc 29*433d6423SLionel Sambuc int getpeername(int sock, struct sockaddr *__restrict address, 30*433d6423SLionel Sambuc socklen_t *__restrict address_len) 31*433d6423SLionel Sambuc { 32*433d6423SLionel Sambuc int r; 33*433d6423SLionel Sambuc nwio_tcpconf_t tcpconf; 34*433d6423SLionel Sambuc nwio_udpopt_t udpopt; 35*433d6423SLionel Sambuc struct sockaddr_un uds_addr; 36*433d6423SLionel Sambuc 37*433d6423SLionel Sambuc r= ioctl(sock, NWIOGTCPCONF, &tcpconf); 38*433d6423SLionel Sambuc if (r != -1 || errno != ENOTTY) 39*433d6423SLionel Sambuc { 40*433d6423SLionel Sambuc if (r == -1) 41*433d6423SLionel Sambuc { 42*433d6423SLionel Sambuc /* Bad file descriptor */ 43*433d6423SLionel Sambuc return -1; 44*433d6423SLionel Sambuc } 45*433d6423SLionel Sambuc return _tcp_getpeername(sock, address, address_len, 46*433d6423SLionel Sambuc &tcpconf); 47*433d6423SLionel Sambuc } 48*433d6423SLionel Sambuc 49*433d6423SLionel Sambuc r= ioctl(sock, NWIOGUDPOPT, &udpopt); 50*433d6423SLionel Sambuc if (r != -1 || errno != ENOTTY) 51*433d6423SLionel Sambuc { 52*433d6423SLionel Sambuc if (r == -1) 53*433d6423SLionel Sambuc { 54*433d6423SLionel Sambuc /* Bad file descriptor */ 55*433d6423SLionel Sambuc return -1; 56*433d6423SLionel Sambuc } 57*433d6423SLionel Sambuc return _udp_getpeername(sock, address, address_len, 58*433d6423SLionel Sambuc &udpopt); 59*433d6423SLionel Sambuc } 60*433d6423SLionel Sambuc 61*433d6423SLionel Sambuc r= ioctl(sock, NWIOGUDSPADDR, &uds_addr); 62*433d6423SLionel Sambuc if (r != -1 || errno != ENOTTY) 63*433d6423SLionel Sambuc { 64*433d6423SLionel Sambuc if (r == -1) 65*433d6423SLionel Sambuc { 66*433d6423SLionel Sambuc /* Bad file descriptor */ 67*433d6423SLionel Sambuc return -1; 68*433d6423SLionel Sambuc } 69*433d6423SLionel Sambuc return _uds_getpeername(sock, address, address_len, 70*433d6423SLionel Sambuc &uds_addr); 71*433d6423SLionel Sambuc } 72*433d6423SLionel Sambuc 73*433d6423SLionel Sambuc 74*433d6423SLionel Sambuc #if DEBUG 75*433d6423SLionel Sambuc fprintf(stderr, "getpeername: not implemented for fd %d\n", sock); 76*433d6423SLionel Sambuc #endif 77*433d6423SLionel Sambuc errno= ENOSYS; 78*433d6423SLionel Sambuc return -1; 79*433d6423SLionel Sambuc } 80*433d6423SLionel Sambuc 81*433d6423SLionel Sambuc static int _tcp_getpeername(int sock, struct sockaddr *__restrict address, 82*433d6423SLionel Sambuc socklen_t *__restrict address_len, nwio_tcpconf_t *tcpconfp) 83*433d6423SLionel Sambuc { 84*433d6423SLionel Sambuc socklen_t len; 85*433d6423SLionel Sambuc struct sockaddr_in sin; 86*433d6423SLionel Sambuc 87*433d6423SLionel Sambuc if (tcpconfp->nwtc_remaddr == 0 || 88*433d6423SLionel Sambuc tcpconfp->nwtc_remport == 0) 89*433d6423SLionel Sambuc { 90*433d6423SLionel Sambuc errno= ENOTCONN; 91*433d6423SLionel Sambuc return -1; 92*433d6423SLionel Sambuc } 93*433d6423SLionel Sambuc 94*433d6423SLionel Sambuc memset(&sin, '\0', sizeof(sin)); 95*433d6423SLionel Sambuc sin.sin_family= AF_INET; 96*433d6423SLionel Sambuc sin.sin_addr.s_addr= tcpconfp->nwtc_remaddr; 97*433d6423SLionel Sambuc sin.sin_port= tcpconfp->nwtc_remport; 98*433d6423SLionel Sambuc sin.sin_len = sizeof(sin); 99*433d6423SLionel Sambuc 100*433d6423SLionel Sambuc len= *address_len; 101*433d6423SLionel Sambuc if (len > sizeof(sin)) 102*433d6423SLionel Sambuc len= sizeof(sin); 103*433d6423SLionel Sambuc memcpy(address, &sin, len); 104*433d6423SLionel Sambuc *address_len= len; 105*433d6423SLionel Sambuc 106*433d6423SLionel Sambuc return 0; 107*433d6423SLionel Sambuc } 108*433d6423SLionel Sambuc 109*433d6423SLionel Sambuc static int _udp_getpeername(int sock, struct sockaddr *__restrict address, 110*433d6423SLionel Sambuc socklen_t *__restrict address_len, nwio_udpopt_t *udpopt) 111*433d6423SLionel Sambuc { 112*433d6423SLionel Sambuc socklen_t len; 113*433d6423SLionel Sambuc struct sockaddr_in sin; 114*433d6423SLionel Sambuc 115*433d6423SLionel Sambuc if (udpopt->nwuo_remaddr == 0 || 116*433d6423SLionel Sambuc udpopt->nwuo_remport == 0) 117*433d6423SLionel Sambuc { 118*433d6423SLionel Sambuc errno= ENOTCONN; 119*433d6423SLionel Sambuc return -1; 120*433d6423SLionel Sambuc } 121*433d6423SLionel Sambuc 122*433d6423SLionel Sambuc memset(&sin, '\0', sizeof(sin)); 123*433d6423SLionel Sambuc sin.sin_family= AF_INET; 124*433d6423SLionel Sambuc sin.sin_addr.s_addr= udpopt->nwuo_remaddr; 125*433d6423SLionel Sambuc sin.sin_port= udpopt->nwuo_remport; 126*433d6423SLionel Sambuc sin.sin_len = sizeof(sin); 127*433d6423SLionel Sambuc 128*433d6423SLionel Sambuc len= *address_len; 129*433d6423SLionel Sambuc if (len > sizeof(sin)) 130*433d6423SLionel Sambuc len= sizeof(sin); 131*433d6423SLionel Sambuc memcpy(address, &sin, len); 132*433d6423SLionel Sambuc *address_len= len; 133*433d6423SLionel Sambuc 134*433d6423SLionel Sambuc return 0; 135*433d6423SLionel Sambuc } 136*433d6423SLionel Sambuc 137*433d6423SLionel Sambuc static int _uds_getpeername(int sock, struct sockaddr *__restrict address, 138*433d6423SLionel Sambuc socklen_t *__restrict address_len, struct sockaddr_un *uds_addr) 139*433d6423SLionel Sambuc { 140*433d6423SLionel Sambuc socklen_t len; 141*433d6423SLionel Sambuc 142*433d6423SLionel Sambuc if (uds_addr->sun_family != AF_UNIX) 143*433d6423SLionel Sambuc { 144*433d6423SLionel Sambuc errno= ENOTCONN; 145*433d6423SLionel Sambuc return -1; 146*433d6423SLionel Sambuc } 147*433d6423SLionel Sambuc 148*433d6423SLionel Sambuc len= *address_len; 149*433d6423SLionel Sambuc if (len > sizeof(struct sockaddr_un)) 150*433d6423SLionel Sambuc len = sizeof(struct sockaddr_un); 151*433d6423SLionel Sambuc 152*433d6423SLionel Sambuc memcpy(address, uds_addr, len); 153*433d6423SLionel Sambuc *address_len= len; 154*433d6423SLionel Sambuc 155*433d6423SLionel Sambuc return 0; 156*433d6423SLionel Sambuc } 157