00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include <ubixos/types.h>
00037
00038 #include "net/debug.h"
00039 #include "net/api.h"
00040
00041 #include "net/sockets.h"
00042
00043 #define NUM_SOCKETS 10
00044
00045 struct lwip_socket {
00046 struct netconn *conn;
00047 struct netbuf *lastdata;
00048 uInt16 lastoffset;
00049 };
00050
00051 static struct lwip_socket sockets[NUM_SOCKETS];
00052
00053
00054 static struct lwip_socket *
00055 get_socket(int s)
00056 {
00057 struct lwip_socket *sock;
00058
00059 if(s > NUM_SOCKETS) {
00060
00061 return NULL;
00062 }
00063
00064 sock = &sockets[s];
00065
00066 if(sock->conn == NULL) {
00067
00068 return NULL;
00069 }
00070 return sock;
00071 }
00072
00073 static int
00074 alloc_socket(struct netconn *newconn)
00075 {
00076 int i;
00077
00078
00079 for(i = 0; i < NUM_SOCKETS; ++i) {
00080 if(sockets[i].conn == NULL) {
00081 sockets[i].conn = newconn;
00082 sockets[i].lastdata = NULL;
00083 sockets[i].lastoffset = 0;
00084 return i;
00085 }
00086 }
00087 return -1;
00088 }
00089
00090 int
00091 lwip_accept(int s, struct sockaddr *addr, int *addrlen)
00092 {
00093 struct lwip_socket *sock;
00094 struct netconn *newconn;
00095 struct ip_addr *naddr;
00096 uInt16 port;
00097 int newsock;
00098
00099 sock = get_socket(s);
00100 if(sock == NULL) {
00101 return -1;
00102 }
00103
00104 newconn = netconn_accept(sock->conn);
00105
00106
00107 netconn_peer(newconn, &naddr, &port);
00108
00109 ((struct sockaddr_in *)addr)->sin_addr.s_addr = naddr->addr;
00110 ((struct sockaddr_in *)addr)->sin_port = port;
00111
00112 newsock = alloc_socket(newconn);
00113 if(newsock == -1) {
00114 netconn_delete(newconn);
00115
00116 }
00117 return newsock;
00118 }
00119
00120 int
00121 lwip_bind(int s, struct sockaddr *name, int namelen)
00122 {
00123 struct lwip_socket *sock;
00124 struct ip_addr remote_addr;
00125 uInt16 remote_port;
00126 err_t err;
00127
00128 sock = get_socket(s);
00129 if(sock == NULL) {
00130 return -1;
00131 }
00132
00133 remote_addr.addr = ((struct sockaddr_in *)name)->sin_addr.s_addr;
00134 remote_port = ((struct sockaddr_in *)name)->sin_port;
00135
00136 err = netconn_bind(sock->conn, &remote_addr, ntohs(remote_port));
00137
00138 if(err != ERR_OK) {
00139
00140 return -1;
00141 }
00142
00143 return 0;
00144 }
00145
00146 int
00147 lwip_close(int s)
00148 {
00149 struct lwip_socket *sock;
00150
00151 DEBUGF(SOCKETS_DEBUG, ("close: socket %d\n", s));
00152 sock = get_socket(s);
00153 if(sock == NULL) {
00154 return -1;
00155 }
00156
00157
00158 netconn_delete(sock->conn);
00159 if(sock->lastdata != NULL) {
00160 netbuf_delete(sock->lastdata);
00161 }
00162 sock->lastdata = NULL;
00163 sock->lastoffset = 0;
00164 sock->conn = NULL;
00165 return 0;
00166 }
00167
00168 int
00169 lwip_connect(int s, struct sockaddr *name, int namelen)
00170 {
00171 struct lwip_socket *sock;
00172 struct ip_addr remote_addr;
00173 uInt16 remote_port;
00174 err_t err;
00175
00176 sock = get_socket(s);
00177 if(sock == NULL) {
00178 return -1;
00179 }
00180
00181 remote_addr.addr = ((struct sockaddr_in *)name)->sin_addr.s_addr;
00182 remote_port = ((struct sockaddr_in *)name)->sin_port;
00183
00184 err = netconn_connect(sock->conn, &remote_addr, ntohs(remote_port));
00185
00186 if(err != ERR_OK) {
00187
00188 return -1;
00189 }
00190
00191 return 0;
00192 }
00193
00194 int
00195 lwip_listen(int s, int backlog)
00196 {
00197 struct lwip_socket *sock;
00198 err_t err;
00199
00200 sock = get_socket(s);
00201 if(sock == NULL) {
00202 return -1;
00203 }
00204
00205 err = netconn_listen(sock->conn);
00206
00207 if(err != ERR_OK) {
00208
00209 return -1;
00210 }
00211
00212 return 0;
00213 }
00214
00215 int
00216 lwip_recvfrom(int s, void *mem, int len, unsigned int flags,
00217 struct sockaddr *from, int *fromlen)
00218 {
00219 struct lwip_socket *sock;
00220 struct netbuf *buf;
00221 uInt16 buflen, copylen;
00222 struct ip_addr *addr;
00223 uInt16 port;
00224
00225
00226 sock = get_socket(s);
00227 if(sock == NULL) {
00228 return -1;
00229 }
00230
00231
00232 if(sock->lastdata != NULL) {
00233 buf = sock->lastdata;
00234 } else {
00235
00236
00237 buf = netconn_recv(sock->conn);
00238
00239 if(buf == NULL) {
00240
00241 return 0;
00242 }
00243 }
00244
00245 buflen = netbuf_len(buf);
00246
00247 buflen -= sock->lastoffset;
00248
00249 if(len > buflen) {
00250 copylen = buflen;
00251 } else {
00252 copylen = len;
00253 }
00254
00255
00256
00257 netbuf_copy_partial(buf, mem, copylen, sock->lastoffset);
00258
00259
00260
00261
00262 if(netconn_type(sock->conn) == NETCONN_TCP && buflen - copylen > 0) {
00263 sock->lastdata = buf;
00264 sock->lastoffset = buflen - copylen;
00265 } else {
00266 sock->lastdata = NULL;
00267 sock->lastoffset = 0;
00268 netbuf_delete(buf);
00269 }
00270
00271
00272 if(from != NULL && fromlen != NULL) {
00273 addr = netbuf_fromaddr(buf);
00274 port = htons(netbuf_fromport(buf));
00275 ((struct sockaddr_in *)from)->sin_addr.s_addr = addr->addr;
00276 ((struct sockaddr_in *)from)->sin_port = port;
00277 *fromlen = sizeof(struct sockaddr_in);
00278 }
00279
00280
00281
00282
00283
00284
00285 if(len > copylen) {
00286 return copylen;
00287 } else {
00288 return len;
00289 }
00290 }
00291
00292 int
00293 lwip_read(int s, void *mem, int len)
00294 {
00295 return lwip_recv(s, mem, len, 0);
00296 }
00297
00298 int
00299 lwip_recv(int s, void *mem, int len, unsigned int flags)
00300 {
00301 return lwip_recvfrom(s, mem, len, flags, NULL, NULL);
00302 }
00303
00304 int
00305 lwip_send(int s, void *data, int size, unsigned int flags)
00306 {
00307 struct lwip_socket *sock;
00308 struct netbuf *buf;
00309 err_t err;
00310
00311 DEBUGF(SOCKETS_DEBUG, ("send: socket %d, size %d\n", s, size));
00312
00313 sock = get_socket(s);
00314 if(sock == NULL) {
00315 return -1;
00316 }
00317
00318 switch(netconn_type(sock->conn)) {
00319 case NETCONN_UDP:
00320
00321 buf = netbuf_new();
00322
00323 if(buf == NULL) {
00324
00325 return -1;
00326 }
00327
00328
00329
00330 netbuf_ref(buf, data, size);
00331
00332
00333 err = netconn_send(sock->conn, buf);
00334
00335
00336 netbuf_delete(buf);
00337 break;
00338 case NETCONN_TCP:
00339 err = netconn_write(sock->conn, data, size, NETCONN_COPY);
00340 break;
00341 default:
00342 err = ERR_ARG;
00343 break;
00344 }
00345 if(err != ERR_OK) {
00346
00347 return -1;
00348 }
00349
00350 return size;
00351 }
00352
00353 int
00354 lwip_sendto(int s, void *data, int size, unsigned int flags,
00355 struct sockaddr *to, int tolen)
00356 {
00357 struct lwip_socket *sock;
00358 struct ip_addr remote_addr, *addr;
00359 uInt16 remote_port, port;
00360 int ret;
00361
00362 sock = get_socket(s);
00363 if(sock == NULL) {
00364 return -1;
00365 }
00366
00367
00368 netconn_peer(sock->conn, &addr, &port);
00369
00370 remote_addr.addr = ((struct sockaddr_in *)to)->sin_addr.s_addr;
00371 remote_port = ((struct sockaddr_in *)to)->sin_port;
00372 netconn_connect(sock->conn, &remote_addr, remote_port);
00373
00374 ret = lwip_send(s, data, size, flags);
00375
00376
00377
00378 netconn_connect(sock->conn, addr, port);
00379 return ret;
00380 }
00381
00382 int
00383 lwip_socket(int domain, int type, int protocol)
00384 {
00385 struct netconn *conn;
00386 int i;
00387
00388
00389 switch(type) {
00390 case SOCK_DGRAM:
00391 conn = netconn_new(NETCONN_UDP);
00392 break;
00393 case SOCK_STREAM:
00394 conn = netconn_new(NETCONN_TCP);
00395 break;
00396 default:
00397
00398 return -1;
00399 }
00400
00401 if(conn == NULL) {
00402 DEBUGF(SOCKETS_DEBUG, ("socket: could not create netconn.\n"));
00403
00404 return -1;
00405 }
00406
00407 i = alloc_socket(conn);
00408
00409 if(i == -1) {
00410
00411 netconn_delete(conn);
00412 }
00413 return i;
00414 }
00415
00416 int
00417 lwip_write(int s, void *data, int size)
00418 {
00419 struct lwip_socket *sock;
00420 err_t err;
00421
00422 DEBUGF(SOCKETS_DEBUG, ("write: socket %d, size %d\n", s, size));
00423
00424 sock = get_socket(s);
00425 if(sock == NULL) {
00426 return -1;
00427 }
00428
00429 switch(netconn_type(sock->conn)) {
00430 case NETCONN_UDP:
00431 return lwip_send(s, data, size, 0);
00432
00433 case NETCONN_TCP:
00434 err = netconn_write(sock->conn, data, size, NETCONN_COPY);
00435 break;
00436 default:
00437 err = ERR_ARG;
00438 break;
00439 }
00440 if(err != ERR_OK) {
00441
00442 return -1;
00443 }
00444 return size;
00445 }
00446