comparison src/inet.c @ 0:4b915342e2a8

LuaSocket 2.0.2 + CMake build description.
author Eric Wing <ewing . public |-at-| gmail . com>
date Tue, 26 Aug 2008 18:40:01 -0700
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4b915342e2a8
1 /*=========================================================================*\
2 * Internet domain functions
3 * LuaSocket toolkit
4 *
5 * RCS ID: $Id: inet.c,v 1.28 2005/10/07 04:40:59 diego Exp $
6 \*=========================================================================*/
7 #include <stdio.h>
8 #include <string.h>
9
10 #include "lua.h"
11 #include "lauxlib.h"
12
13 #include "inet.h"
14
15 /*=========================================================================*\
16 * Internal function prototypes.
17 \*=========================================================================*/
18 static int inet_global_toip(lua_State *L);
19 static int inet_global_tohostname(lua_State *L);
20 static void inet_pushresolved(lua_State *L, struct hostent *hp);
21 static int inet_global_gethostname(lua_State *L);
22
23 /* DNS functions */
24 static luaL_reg func[] = {
25 { "toip", inet_global_toip },
26 { "tohostname", inet_global_tohostname },
27 { "gethostname", inet_global_gethostname},
28 { NULL, NULL}
29 };
30
31 /*=========================================================================*\
32 * Exported functions
33 \*=========================================================================*/
34 /*-------------------------------------------------------------------------*\
35 * Initializes module
36 \*-------------------------------------------------------------------------*/
37 int inet_open(lua_State *L)
38 {
39 lua_pushstring(L, "dns");
40 lua_newtable(L);
41 luaL_openlib(L, NULL, func, 0);
42 lua_settable(L, -3);
43 return 0;
44 }
45
46 /*=========================================================================*\
47 * Global Lua functions
48 \*=========================================================================*/
49 /*-------------------------------------------------------------------------*\
50 * Returns all information provided by the resolver given a host name
51 * or ip address
52 \*-------------------------------------------------------------------------*/
53 static int inet_gethost(const char *address, struct hostent **hp) {
54 struct in_addr addr;
55 if (inet_aton(address, &addr))
56 return socket_gethostbyaddr((char *) &addr, sizeof(addr), hp);
57 else
58 return socket_gethostbyname(address, hp);
59 }
60
61 /*-------------------------------------------------------------------------*\
62 * Returns all information provided by the resolver given a host name
63 * or ip address
64 \*-------------------------------------------------------------------------*/
65 static int inet_global_tohostname(lua_State *L) {
66 const char *address = luaL_checkstring(L, 1);
67 struct hostent *hp = NULL;
68 int err = inet_gethost(address, &hp);
69 if (err != IO_DONE) {
70 lua_pushnil(L);
71 lua_pushstring(L, socket_hoststrerror(err));
72 return 2;
73 }
74 lua_pushstring(L, hp->h_name);
75 inet_pushresolved(L, hp);
76 return 2;
77 }
78
79 /*-------------------------------------------------------------------------*\
80 * Returns all information provided by the resolver given a host name
81 * or ip address
82 \*-------------------------------------------------------------------------*/
83 static int inet_global_toip(lua_State *L)
84 {
85 const char *address = luaL_checkstring(L, 1);
86 struct hostent *hp = NULL;
87 int err = inet_gethost(address, &hp);
88 if (err != IO_DONE) {
89 lua_pushnil(L);
90 lua_pushstring(L, socket_hoststrerror(err));
91 return 2;
92 }
93 lua_pushstring(L, inet_ntoa(*((struct in_addr *) hp->h_addr)));
94 inet_pushresolved(L, hp);
95 return 2;
96 }
97
98
99 /*-------------------------------------------------------------------------*\
100 * Gets the host name
101 \*-------------------------------------------------------------------------*/
102 static int inet_global_gethostname(lua_State *L)
103 {
104 char name[257];
105 name[256] = '\0';
106 if (gethostname(name, 256) < 0) {
107 lua_pushnil(L);
108 lua_pushstring(L, "gethostname failed");
109 return 2;
110 } else {
111 lua_pushstring(L, name);
112 return 1;
113 }
114 }
115
116
117
118 /*=========================================================================*\
119 * Lua methods
120 \*=========================================================================*/
121 /*-------------------------------------------------------------------------*\
122 * Retrieves socket peer name
123 \*-------------------------------------------------------------------------*/
124 int inet_meth_getpeername(lua_State *L, p_socket ps)
125 {
126 struct sockaddr_in peer;
127 socklen_t peer_len = sizeof(peer);
128 if (getpeername(*ps, (SA *) &peer, &peer_len) < 0) {
129 lua_pushnil(L);
130 lua_pushstring(L, "getpeername failed");
131 } else {
132 lua_pushstring(L, inet_ntoa(peer.sin_addr));
133 lua_pushnumber(L, ntohs(peer.sin_port));
134 }
135 return 2;
136 }
137
138 /*-------------------------------------------------------------------------*\
139 * Retrieves socket local name
140 \*-------------------------------------------------------------------------*/
141 int inet_meth_getsockname(lua_State *L, p_socket ps)
142 {
143 struct sockaddr_in local;
144 socklen_t local_len = sizeof(local);
145 if (getsockname(*ps, (SA *) &local, &local_len) < 0) {
146 lua_pushnil(L);
147 lua_pushstring(L, "getsockname failed");
148 } else {
149 lua_pushstring(L, inet_ntoa(local.sin_addr));
150 lua_pushnumber(L, ntohs(local.sin_port));
151 }
152 return 2;
153 }
154
155 /*=========================================================================*\
156 * Internal functions
157 \*=========================================================================*/
158 /*-------------------------------------------------------------------------*\
159 * Passes all resolver information to Lua as a table
160 \*-------------------------------------------------------------------------*/
161 static void inet_pushresolved(lua_State *L, struct hostent *hp)
162 {
163 char **alias;
164 struct in_addr **addr;
165 int i, resolved;
166 lua_newtable(L); resolved = lua_gettop(L);
167 lua_pushstring(L, "name");
168 lua_pushstring(L, hp->h_name);
169 lua_settable(L, resolved);
170 lua_pushstring(L, "ip");
171 lua_pushstring(L, "alias");
172 i = 1;
173 alias = hp->h_aliases;
174 lua_newtable(L);
175 if (alias) {
176 while (*alias) {
177 lua_pushnumber(L, i);
178 lua_pushstring(L, *alias);
179 lua_settable(L, -3);
180 i++; alias++;
181 }
182 }
183 lua_settable(L, resolved);
184 i = 1;
185 lua_newtable(L);
186 addr = (struct in_addr **) hp->h_addr_list;
187 if (addr) {
188 while (*addr) {
189 lua_pushnumber(L, i);
190 lua_pushstring(L, inet_ntoa(**addr));
191 lua_settable(L, -3);
192 i++; addr++;
193 }
194 }
195 lua_settable(L, resolved);
196 }
197
198 /*-------------------------------------------------------------------------*\
199 * Tries to create a new inet socket
200 \*-------------------------------------------------------------------------*/
201 const char *inet_trycreate(p_socket ps, int type) {
202 return socket_strerror(socket_create(ps, AF_INET, type, 0));
203 }
204
205 /*-------------------------------------------------------------------------*\
206 * Tries to connect to remote address (address, port)
207 \*-------------------------------------------------------------------------*/
208 const char *inet_tryconnect(p_socket ps, const char *address,
209 unsigned short port, p_timeout tm)
210 {
211 struct sockaddr_in remote;
212 int err;
213 memset(&remote, 0, sizeof(remote));
214 remote.sin_family = AF_INET;
215 remote.sin_port = htons(port);
216 if (strcmp(address, "*")) {
217 if (!inet_aton(address, &remote.sin_addr)) {
218 struct hostent *hp = NULL;
219 struct in_addr **addr;
220 err = socket_gethostbyname(address, &hp);
221 if (err != IO_DONE) return socket_hoststrerror(err);
222 addr = (struct in_addr **) hp->h_addr_list;
223 memcpy(&remote.sin_addr, *addr, sizeof(struct in_addr));
224 }
225 } else remote.sin_family = AF_UNSPEC;
226 err = socket_connect(ps, (SA *) &remote, sizeof(remote), tm);
227 return socket_strerror(err);
228 }
229
230 /*-------------------------------------------------------------------------*\
231 * Tries to bind socket to (address, port)
232 \*-------------------------------------------------------------------------*/
233 const char *inet_trybind(p_socket ps, const char *address, unsigned short port)
234 {
235 struct sockaddr_in local;
236 int err;
237 memset(&local, 0, sizeof(local));
238 /* address is either wildcard or a valid ip address */
239 local.sin_addr.s_addr = htonl(INADDR_ANY);
240 local.sin_port = htons(port);
241 local.sin_family = AF_INET;
242 if (strcmp(address, "*") && !inet_aton(address, &local.sin_addr)) {
243 struct hostent *hp = NULL;
244 struct in_addr **addr;
245 err = socket_gethostbyname(address, &hp);
246 if (err != IO_DONE) return socket_hoststrerror(err);
247 addr = (struct in_addr **) hp->h_addr_list;
248 memcpy(&local.sin_addr, *addr, sizeof(struct in_addr));
249 }
250 err = socket_bind(ps, (SA *) &local, sizeof(local));
251 if (err != IO_DONE) socket_destroy(ps);
252 return socket_strerror(err);
253 }
254
255 /*-------------------------------------------------------------------------*\
256 * Some systems do not provide this so that we provide our own. It's not
257 * marvelously fast, but it works just fine.
258 \*-------------------------------------------------------------------------*/
259 #ifdef INET_ATON
260 int inet_aton(const char *cp, struct in_addr *inp)
261 {
262 unsigned int a = 0, b = 0, c = 0, d = 0;
263 int n = 0, r;
264 unsigned long int addr = 0;
265 r = sscanf(cp, "%u.%u.%u.%u%n", &a, &b, &c, &d, &n);
266 if (r == 0 || n == 0) return 0;
267 cp += n;
268 if (*cp) return 0;
269 if (a > 255 || b > 255 || c > 255 || d > 255) return 0;
270 if (inp) {
271 addr += a; addr <<= 8;
272 addr += b; addr <<= 8;
273 addr += c; addr <<= 8;
274 addr += d;
275 inp->s_addr = htonl(addr);
276 }
277 return 1;
278 }
279 #endif
280
281