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