Mercurial > luasocket
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 |