aboutsummaryrefslogtreecommitdiff
path: root/src/inet.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/inet.c')
-rw-r--r--src/inet.c117
1 files changed, 74 insertions, 43 deletions
diff --git a/src/inet.c b/src/inet.c
index fd16506..5823c36 100644
--- a/src/inet.c
+++ b/src/inet.c
@@ -165,61 +165,92 @@ static int inet_global_gethostname(lua_State *L)
165/*-------------------------------------------------------------------------*\ 165/*-------------------------------------------------------------------------*\
166* Retrieves socket peer name 166* Retrieves socket peer name
167\*-------------------------------------------------------------------------*/ 167\*-------------------------------------------------------------------------*/
168int inet_meth_getpeername(lua_State *L, p_socket ps) 168int inet_meth_getpeername(lua_State *L, p_socket ps, int family)
169{ 169{
170 union { 170 switch (family) {
171 struct sockaddr_storage sas; 171 case PF_INET: {
172 struct sockaddr sa; 172 struct sockaddr_in peer;
173 struct sockaddr_in sa4; 173 socklen_t peer_len = sizeof(peer);
174 struct sockaddr_in6 sa6; 174 char name[INET_ADDRSTRLEN];
175 } peer; 175 if (getpeername(*ps, (SA *) &peer, &peer_len) < 0) {
176 socklen_t peer_len = sizeof(peer); 176 lua_pushnil(L);
177 177 lua_pushstring(L, "getpeername failed");
178 if (getpeername(*ps, &peer.sa, &peer_len) < 0) { 178 return 2;
179 lua_pushnil(L); 179 } else {
180 lua_pushfstring(L, "getpeername failed (%d): %s", errno, 180 inet_ntop(family, &peer.sin_addr, name, sizeof(name));
181 strerror(errno)); 181 lua_pushstring(L, name);
182 } else { 182 lua_pushnumber(L, ntohs(peer.sin_port));
183 char ipaddr[INET6_ADDRSTRLEN] = ""; 183 lua_pushliteral(L, "inet");
184 unsigned short port = 0; 184 return 3;
185 185 }
186 switch (peer.sa.sa_family) { 186 }
187 case AF_INET: 187 case PF_INET6: {
188 inet_ntop(AF_INET, &peer.sa4.sin_addr, ipaddr, sizeof(ipaddr)); 188 struct sockaddr_in6 peer;
189 port = ntohs(peer.sa4.sin_port); 189 socklen_t peer_len = sizeof(peer);
190 break; 190 char name[INET6_ADDRSTRLEN];
191 case AF_INET6: 191 if (getpeername(*ps, (SA *) &peer, &peer_len) < 0) {
192 inet_ntop(AF_INET6, &peer.sa6.sin6_addr, ipaddr, sizeof(ipaddr)); 192 lua_pushnil(L);
193 port = ntohs(peer.sa6.sin6_port); 193 lua_pushstring(L, "getpeername failed");
194 break; 194 return 2;
195 } else {
196 inet_ntop(family, &peer.sin6_addr, name, sizeof(name));
197 lua_pushstring(L, name);
198 lua_pushnumber(L, ntohs(peer.sin6_port));
199 lua_pushliteral(L, "inet6");
200 return 3;
201 }
202 return 2;
203 }
195 default: 204 default:
196 lua_pushnil(L); 205 lua_pushnil(L);
197 lua_pushfstring(L, "Unknown address family %d", peer.sa.sa_family); 206 lua_pushstring(L, "unknown family");
198 return 2; 207 return 2;
199 break;
200 }
201
202 lua_pushstring(L, ipaddr);
203 lua_pushnumber(L, port);
204 } 208 }
205 return 2;
206} 209}
207 210
208/*-------------------------------------------------------------------------*\ 211/*-------------------------------------------------------------------------*\
209* Retrieves socket local name 212* Retrieves socket local name
210\*-------------------------------------------------------------------------*/ 213\*-------------------------------------------------------------------------*/
211int inet_meth_getsockname(lua_State *L, p_socket ps) 214int inet_meth_getsockname(lua_State *L, p_socket ps, int family)
212{ 215{
213 struct sockaddr_in local; 216 switch (family) {
214 socklen_t local_len = sizeof(local); 217 case PF_INET: {
215 if (getsockname(*ps, (SA *) &local, &local_len) < 0) { 218 struct sockaddr_in local;
216 lua_pushnil(L); 219 socklen_t local_len = sizeof(local);
217 lua_pushstring(L, "getsockname failed"); 220 char name[INET_ADDRSTRLEN];
218 } else { 221 if (getsockname(*ps, (SA *) &local, &local_len) < 0) {
219 lua_pushstring(L, inet_ntoa(local.sin_addr)); 222 lua_pushnil(L);
220 lua_pushnumber(L, ntohs(local.sin_port)); 223 lua_pushstring(L, "getsockname failed");
224 return 2;
225 } else {
226 inet_ntop(family, &local.sin_addr, name, sizeof(name));
227 lua_pushstring(L, name);
228 lua_pushnumber(L, ntohs(local.sin_port));
229 lua_pushliteral(L, "inet");
230 return 3;
231 }
232 }
233 case PF_INET6: {
234 struct sockaddr_in6 local;
235 socklen_t local_len = sizeof(local);
236 char name[INET6_ADDRSTRLEN];
237 if (getsockname(*ps, (SA *) &local, &local_len) < 0) {
238 lua_pushnil(L);
239 lua_pushstring(L, "getsockname failed");
240 return 2;
241 } else {
242 inet_ntop(family, &local.sin6_addr, name, sizeof(name));
243 lua_pushstring(L, name);
244 lua_pushnumber(L, ntohs(local.sin6_port));
245 lua_pushliteral(L, "inet6");
246 return 3;
247 }
248 }
249 default:
250 lua_pushnil(L);
251 lua_pushstring(L, "unknown family");
252 return 2;
221 } 253 }
222 return 2;
223} 254}
224 255
225/*=========================================================================*\ 256/*=========================================================================*\