1 /* ====================================================================
2  * The Kannel Software License, Version 1.0
3  *
4  * Copyright (c) 2001-2014 Kannel Group
5  * Copyright (c) 1998-2001 WapIT Ltd.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in
17  *    the documentation and/or other materials provided with the
18  *    distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  *    if any, must include the following acknowledgment:
22  *       "This product includes software developed by the
23  *        Kannel Group (http://www.kannel.org/)."
24  *    Alternately, this acknowledgment may appear in the software itself,
25  *    if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Kannel" and "Kannel Group" must not be used to
28  *    endorse or promote products derived from this software without
29  *    prior written permission. For written permission, please
30  *    contact org@kannel.org.
31  *
32  * 5. Products derived from this software may not be called "Kannel",
33  *    nor may "Kannel" appear in their name, without prior written
34  *    permission of the Kannel Group.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED.  IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS
40  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
41  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
42  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
43  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
44  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
45  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
46  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47  * ====================================================================
48  *
49  * This software consists of voluntary contributions made by many
50  * individuals on behalf of the Kannel Group.  For more information on
51  * the Kannel Group, please see <http://www.kannel.org/>.
52  *
53  * Portions of this software are based upon software originally written at
54  * WapIT Ltd., Helsinki, Finland for the Kannel project.
55  */
56 
57 #include <ctype.h>
58 #include <errno.h>
59 #include <stdarg.h>
60 #include <stdio.h>
61 #include <stdlib.h>
62 #include <string.h>
63 #include <time.h>
64 #include <unistd.h>
65 #include <fcntl.h>
66 
67 #include <sys/time.h>
68 #include <sys/types.h>
69 #include <sys/socket.h>
70 #include <netinet/in.h>
71 #include <netdb.h>
72 #include <arpa/inet.h>
73 #include <sys/utsname.h>
74 
75 #include "gwlib.h"
76 
77 
78 static Octstr *official_name = NULL;
79 static Octstr *official_ip = NULL;
80 
81 /*
82  * FreeBSD is not happy with our approach of allocating a sockaddr
83  * and then filling in the fields.  It has private fields that need
84  * to be initialized to 0.  This structure is used for that.
85  */
86 static const struct sockaddr_in empty_sockaddr_in;
87 
88 #ifndef UDP_PACKET_MAX_SIZE
89 #define UDP_PACKET_MAX_SIZE (64*1024)
90 #endif
91 
92 
make_server_socket(int port,const char * interface_name)93 int make_server_socket(int port, const char *interface_name)
94 {
95     struct sockaddr_in addr;
96     int s;
97     int reuse;
98     struct hostent hostinfo;
99     char *buff = NULL;
100 
101     s = socket(PF_INET, SOCK_STREAM, 0);
102     if (s == -1) {
103         error(errno, "socket failed");
104         goto error;
105     }
106 
107     addr = empty_sockaddr_in;
108     addr.sin_family = AF_INET;
109     addr.sin_port = htons(port);
110     if (interface_name == NULL || strcmp(interface_name, "*") == 0)
111         addr.sin_addr.s_addr = htonl(INADDR_ANY);
112     else {
113         if (gw_gethostbyname(&hostinfo, interface_name, &buff) == -1) {
114             error(errno, "gethostbyname failed");
115             goto error;
116         }
117         addr.sin_addr = *(struct in_addr *) hostinfo.h_addr;
118     }
119 
120     reuse = 1;
121     if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &reuse,
122                    sizeof(reuse)) == -1) {
123         error(errno, "setsockopt failed for server address");
124         goto error;
125     }
126 
127     if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) == -1) {
128         error(errno, "bind failed");
129         goto error;
130     }
131 
132     if (listen(s, 10) == -1) {
133         error(errno, "listen failed");
134         goto error;
135     }
136 
137     gw_free(buff);
138 
139     return s;
140 
141 error:
142     if (s >= 0)
143         (void) close(s);
144     gw_free(buff);
145     return -1;
146 }
147 
148 
tcpip_connect_to_server(char * hostname,int port,const char * source_addr)149 int tcpip_connect_to_server(char *hostname, int port, const char *source_addr)
150 {
151 
152     return tcpip_connect_to_server_with_port(hostname, port, 0, source_addr);
153 }
154 
155 
tcpip_connect_to_server_with_port(char * hostname,int port,int our_port,const char * source_addr)156 int tcpip_connect_to_server_with_port(char *hostname, int port, int our_port, const char *source_addr)
157 {
158     struct sockaddr_in addr;
159     struct sockaddr_in o_addr;
160     struct hostent hostinfo;
161     struct hostent o_hostinfo;
162     int s, rc = -1, i;
163     char *buff, *buff1;
164 
165     buff = buff1 = NULL;
166 
167     s = socket(PF_INET, SOCK_STREAM, 0);
168     if (s == -1) {
169         error(errno, "Couldn't create new socket.");
170         goto error;
171     }
172 
173     if (gw_gethostbyname(&hostinfo, hostname, &buff) == -1) {
174         error(errno, "gethostbyname failed");
175         goto error;
176     }
177 
178     if (our_port > 0 || (source_addr != NULL && strcmp(source_addr, "*") != 0))  {
179         int reuse;
180 
181         o_addr = empty_sockaddr_in;
182         o_addr.sin_family = AF_INET;
183         o_addr.sin_port = htons(our_port);
184         if (source_addr == NULL || strcmp(source_addr, "*") == 0)
185             o_addr.sin_addr.s_addr = htonl(INADDR_ANY);
186         else {
187             if (gw_gethostbyname(&o_hostinfo, source_addr, &buff1) == -1) {
188                 error(errno, "gethostbyname failed");
189                 goto error;
190             }
191             o_addr.sin_addr = *(struct in_addr *) o_hostinfo.h_addr;
192         }
193 
194         reuse = 1;
195         if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &reuse, sizeof(reuse)) == -1) {
196             error(errno, "setsockopt failed before bind");
197             goto error;
198         }
199         if (bind(s, (struct sockaddr *) &o_addr, sizeof(o_addr)) == -1) {
200             error(errno, "bind to local port %d failed", our_port);
201             goto error;
202         }
203     }
204 
205     i = 0;
206     do {
207         Octstr *ip2;
208 
209         addr = empty_sockaddr_in;
210         addr.sin_family = AF_INET;
211         addr.sin_port = htons(port);
212         addr.sin_addr = *(struct in_addr *) hostinfo.h_addr_list[i];
213 
214         ip2 = gw_netaddr_to_octstr(AF_INET, &addr.sin_addr);
215 
216         debug("gwlib.socket", 0, "Connecting to <%s>", octstr_get_cstr(ip2));
217 
218         rc = connect(s, (struct sockaddr *) &addr, sizeof(addr));
219         if (rc == -1) {
220             error(errno, "connect to <%s> failed", octstr_get_cstr(ip2));
221         }
222         octstr_destroy(ip2);
223     } while (rc == -1 && hostinfo.h_addr_list[++i] != NULL);
224 
225     if (rc == -1)
226         goto error;
227 
228     gw_free(buff);
229     gw_free(buff1);
230     return s;
231 
232 error:
233     error(0, "error connecting to server `%s' at port `%d'", hostname, port);
234     if (s >= 0)
235         close(s);
236     gw_free(buff);
237     gw_free(buff1);
238     return -1;
239 }
240 
tcpip_connect_nb_to_server(char * hostname,int port,const char * source_addr,int * done)241 int tcpip_connect_nb_to_server(char *hostname, int port, const char *source_addr, int *done)
242 {
243     return tcpip_connect_nb_to_server_with_port(hostname, port, 0, source_addr, done);
244 }
245 
tcpip_connect_nb_to_server_with_port(char * hostname,int port,int our_port,const char * source_addr,int * done)246 int tcpip_connect_nb_to_server_with_port(char *hostname, int port, int our_port, const char *source_addr, int *done)
247 {
248     struct sockaddr_in addr;
249     struct sockaddr_in o_addr;
250     struct hostent hostinfo;
251     struct hostent o_hostinfo;
252     int s, flags, rc = -1, i;
253     char *buff, *buff1;
254 
255     *done = 1;
256     buff = buff1 = NULL;
257 
258     s = socket(PF_INET, SOCK_STREAM, 0);
259     if (s == -1) {
260         error(errno, "Couldn't create new socket.");
261         goto error;
262     }
263 
264     if (gw_gethostbyname(&hostinfo, hostname, &buff) == -1) {
265         error(errno, "gethostbyname failed");
266         goto error;
267     }
268 
269     if (our_port > 0 || (source_addr != NULL && strcmp(source_addr, "*") != 0)) {
270         int reuse;
271 
272         o_addr = empty_sockaddr_in;
273         o_addr.sin_family = AF_INET;
274         o_addr.sin_port = htons(our_port);
275         if (source_addr == NULL || strcmp(source_addr, "*") == 0)
276             o_addr.sin_addr.s_addr = htonl(INADDR_ANY);
277         else {
278             if (gw_gethostbyname(&o_hostinfo, source_addr, &buff1) == -1) {
279                 error(errno, "gethostbyname failed");
280                 goto error;
281             }
282             o_addr.sin_addr = *(struct in_addr *) o_hostinfo.h_addr;
283         }
284 
285         reuse = 1;
286         if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &reuse, sizeof(reuse)) == -1) {
287             error(errno, "setsockopt failed before bind");
288             goto error;
289         }
290         if (bind(s, (struct sockaddr *) &o_addr, sizeof(o_addr)) == -1) {
291             error(errno, "bind to local port %d failed", our_port);
292             goto error;
293         }
294     }
295 
296     flags = fcntl(s, F_GETFL, 0);
297     fcntl(s, F_SETFL, flags | O_NONBLOCK);
298 
299     i = 0;
300     do {
301         Octstr *ip2;
302 
303         addr = empty_sockaddr_in;
304         addr.sin_family = AF_INET;
305         addr.sin_port = htons(port);
306         addr.sin_addr = *(struct in_addr *) hostinfo.h_addr_list[i];
307 
308         ip2 = gw_netaddr_to_octstr(AF_INET, &addr.sin_addr);
309 
310         debug("gwlib.socket", 0, "Connecting nonblocking to <%s>", octstr_get_cstr(ip2));
311 
312         if ((rc = connect(s, (struct sockaddr *) &addr, sizeof(addr))) < 0) {
313             if (errno != EINPROGRESS) {
314                 error(errno, "nonblocking connect to <%s> failed", octstr_get_cstr(ip2));
315             }
316         }
317         octstr_destroy(ip2);
318     } while (rc == -1 && errno != EINPROGRESS && hostinfo.h_addr_list[++i] != NULL);
319 
320     if (rc == -1 && errno != EINPROGRESS)
321         goto error;
322 
323     /* May be connected immediatly
324      * (if we connecting to localhost for example)
325      */
326     if (rc == 0) {
327         *done = 0;
328     }
329 
330     gw_free(buff);
331     gw_free(buff1);
332 
333     return s;
334 
335 error:
336     error(0, "error connecting to server `%s' at port `%d'", hostname, port);
337     if (s >= 0)
338         close(s);
339     gw_free(buff);
340     gw_free(buff1);
341     return -1;
342 }
343 
344 
write_to_socket(int socket,char * str)345 int write_to_socket(int socket, char *str)
346 {
347     size_t len;
348     int ret;
349 
350     len = strlen(str);
351     while (len > 0) {
352         ret = write(socket, str, len);
353         if (ret == -1) {
354             if (errno == EAGAIN) continue;
355             if (errno == EINTR) continue;
356             error(errno, "Writing to socket failed");
357             return -1;
358         }
359         /* ret may be less than len, if the writing was interrupted
360            by a signal. */
361         len -= ret;
362         str += ret;
363     }
364     return 0;
365 }
366 
367 
socket_set_blocking(int fd,int blocking)368 int socket_set_blocking(int fd, int blocking)
369 {
370     int flags, newflags;
371 
372     flags = fcntl(fd, F_GETFL);
373     if (flags < 0) {
374         error(errno, "cannot get flags for fd %d", fd);
375         return -1;
376     }
377 
378     if (blocking)
379         newflags = flags & ~O_NONBLOCK;
380     else
381         newflags = flags | O_NONBLOCK;
382 
383     if (newflags != flags) {
384         if (fcntl(fd, F_SETFL, newflags) < 0) {
385             error(errno, "cannot set flags for fd %d", fd);
386             return -1;
387         }
388     }
389 
390     return 0;
391 }
392 
393 
socket_set_nodelay(int fd,int on)394 int socket_set_nodelay(int fd, int on)
395 {
396     int rc;
397 
398     rc = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof (on));
399     if (rc == -1)
400         error(errno, "Unable set TCP_NODELAY(%d)", on);
401 
402     return rc;
403 }
404 
405 
read_available(int fd,long wait_usec)406 int read_available(int fd, long wait_usec)
407 {
408     fd_set rf;
409     struct timeval to;
410     int ret;
411     div_t waits;
412 
413     gw_assert(fd >= 0);
414 
415     FD_ZERO(&rf);
416     FD_SET(fd, &rf);
417     waits = div(wait_usec, 1000000);
418     to.tv_sec = waits.quot;
419     to.tv_usec = waits.rem;
420 retry:
421     ret = select(fd + 1, &rf, NULL, NULL, &to);
422     if (ret > 0 && FD_ISSET(fd, &rf))
423         return 1;
424     if (ret < 0) {
425         /* In most select() implementations, to will now contain the
426          * remaining time rather than the original time.  That is exactly
427          * what we want when retrying after an interrupt. */
428         switch (errno) {
429             /*The first two entries here are OK*/
430         case EINTR:
431             goto retry;
432         case EAGAIN:
433             return 1;
434             /* We are now sucking mud, figure things out here
435              * as much as possible before it gets lost under
436              * layers of abstraction.  */
437         case EBADF:
438             if (!FD_ISSET(fd, &rf)) {
439                 warning(0, "Tried to select on fd %d, not in the set!\n", fd);
440             } else {
441                 warning(0, "Tried to select on invalid fd %d!\n", fd);
442             }
443             break;
444         case EINVAL:
445             /* Solaris catchall "It didn't work" error, lets apply
446              * some tests and see if we can catch it. */
447 
448             /* First up, try invalid timeout*/
449             if (to.tv_sec > 10000000)
450                 warning(0, "Wait more than three years for a select?\n");
451             if (to.tv_usec > 1000000)
452                 warning(0, "There are only 1000000 usec in a second...\n");
453             break;
454 
455 
456         }
457         return -1; 	/* some error */
458     }
459     return 0;
460 }
461 
462 
463 
udp_client_socket(void)464 int udp_client_socket(void)
465 {
466     int s;
467 
468     s = socket(PF_INET, SOCK_DGRAM, 0);
469     if (s == -1) {
470         error(errno, "Couldn't create a UDP socket");
471         return -1;
472     }
473 
474     return s;
475 }
476 
477 
udp_bind(int port,const char * source_addr)478 int udp_bind(int port, const char *source_addr)
479 {
480     int s;
481     struct sockaddr_in sa;
482     struct hostent hostinfo;
483     char *buff = NULL;
484 
485     s = socket(PF_INET, SOCK_DGRAM, 0);
486     if (s == -1) {
487         error(errno, "Couldn't create a UDP socket");
488         return -1;
489     }
490 
491     sa = empty_sockaddr_in;
492     sa.sin_family = AF_INET;
493     sa.sin_port = htons(port);
494     if (strcmp(source_addr, "*") == 0)
495         sa.sin_addr.s_addr = htonl(INADDR_ANY);
496     else {
497         if (gw_gethostbyname(&hostinfo, source_addr, &buff) == -1) {
498             error(errno, "gethostbyname failed");
499             gw_free(buff);
500             return -1;
501         }
502         sa.sin_addr = *(struct in_addr *) hostinfo.h_addr;
503     }
504 
505     if (bind(s, (struct sockaddr *) &sa, (int) sizeof(sa)) == -1) {
506         error(errno, "Couldn't bind a UDP socket to port %d", port);
507         (void) close(s);
508         return -1;
509     }
510 
511     gw_free(buff);
512 
513     return s;
514 }
515 
516 
udp_create_address(Octstr * host_or_ip,int port)517 Octstr *udp_create_address(Octstr *host_or_ip, int port)
518 {
519     struct sockaddr_in sa;
520     struct hostent h;
521     char *buff = NULL;
522     Octstr *ret;
523 
524     sa = empty_sockaddr_in;
525     sa.sin_family = AF_INET;
526     sa.sin_port = htons(port);
527 
528     if (strcmp(octstr_get_cstr(host_or_ip), "*") == 0) {
529         sa.sin_addr.s_addr = INADDR_ANY;
530     } else {
531         if (gw_gethostbyname(&h, octstr_get_cstr(host_or_ip), &buff) == -1) {
532             error(0, "Couldn't find the IP number of `%s'",
533                   octstr_get_cstr(host_or_ip));
534             gw_free(buff);
535             return NULL;
536         }
537         sa.sin_addr = *(struct in_addr *) h.h_addr;
538     }
539 
540     ret = octstr_create_from_data((char *) &sa, sizeof(sa));
541     gw_free(buff);
542 
543     return ret;
544 }
545 
546 
udp_get_port(Octstr * addr)547 int udp_get_port(Octstr *addr)
548 {
549     struct sockaddr_in sa;
550 
551     gw_assert(octstr_len(addr) == sizeof(sa));
552     memcpy(&sa, octstr_get_cstr(addr), sizeof(sa));
553     return ntohs(sa.sin_port);
554 }
555 
556 
udp_get_ip(Octstr * addr)557 Octstr *udp_get_ip(Octstr *addr)
558 {
559     struct sockaddr_in sa;
560 
561     gw_assert(octstr_len(addr) == sizeof(sa));
562     memcpy(&sa, octstr_get_cstr(addr), sizeof(sa));
563     return gw_netaddr_to_octstr(AF_INET, &sa.sin_addr);
564 }
565 
566 
udp_sendto(int s,Octstr * datagram,Octstr * addr)567 int udp_sendto(int s, Octstr *datagram, Octstr *addr)
568 {
569     struct sockaddr_in sa;
570 
571     gw_assert(octstr_len(addr) == sizeof(sa));
572     memcpy(&sa, octstr_get_cstr(addr), sizeof(sa));
573     if (sendto(s, octstr_get_cstr(datagram), octstr_len(datagram), 0,
574                (struct sockaddr *) &sa, (int) sizeof(sa)) == -1) {
575         error(errno, "Couldn't send UDP packet");
576         return -1;
577     }
578     return 0;
579 }
580 
581 
udp_recvfrom(int s,Octstr ** datagram,Octstr ** addr)582 int udp_recvfrom(int s, Octstr **datagram, Octstr **addr)
583 {
584     return udp_recvfrom_flags(s, datagram, addr, 0);
585 }
586 
587 
udp_recvfrom_flags(int s,Octstr ** datagram,Octstr ** addr,int sockrcvflags)588 int udp_recvfrom_flags(int s, Octstr **datagram, Octstr **addr, int sockrcvflags)
589 {
590     struct sockaddr_in sa;
591     socklen_t salen;
592     char *buf;
593     int bytes;
594 
595     buf = gw_malloc(UDP_PACKET_MAX_SIZE);
596 
597     salen = sizeof(sa);
598     bytes = recvfrom(s, buf, UDP_PACKET_MAX_SIZE, sockrcvflags, (struct sockaddr *) &sa, &salen);
599     if (bytes == -1) {
600         if (errno != EAGAIN)
601             error(errno, "Couldn't receive UDP packet");
602 	gw_free(buf);
603         return -1;
604     }
605 
606     *datagram = octstr_create_from_data(buf, bytes);
607     *addr = octstr_create_from_data((char *) &sa, salen);
608 
609     gw_free(buf);
610 
611     return 0;
612 }
613 
614 
host_ip(struct sockaddr_in addr)615 Octstr *host_ip(struct sockaddr_in addr)
616 {
617     return gw_netaddr_to_octstr(AF_INET, &addr.sin_addr);
618 }
619 
620 
host_port(struct sockaddr_in addr)621 int host_port(struct sockaddr_in addr)
622 {
623     return ntohs(addr.sin_port);
624 }
625 
626 
get_official_name(void)627 Octstr *get_official_name(void)
628 {
629     gw_assert(official_name != NULL);
630     return official_name;
631 }
632 
633 
get_official_ip(void)634 Octstr *get_official_ip(void)
635 {
636     gw_assert(official_ip != NULL);
637     return official_ip;
638 }
639 
640 
setup_official_name(void)641 static void setup_official_name(void)
642 {
643     struct utsname u;
644     struct hostent h;
645     char *buff = NULL;
646 
647     gw_assert(official_name == NULL);
648     if (uname(&u) == -1)
649         panic(0, "uname failed - can't happen, unless " GW_NAME " is buggy.");
650     if (gw_gethostbyname(&h, u.nodename, &buff) == -1) {
651         error(0, "Can't find out official hostname for this host, "
652               "using `%s' instead.", u.nodename);
653         official_name = octstr_create(u.nodename);
654         official_ip = octstr_create("127.0.0.1");
655     } else {
656         official_name = octstr_create(h.h_name);
657         official_ip = gw_netaddr_to_octstr(AF_INET, h.h_addr);
658     }
659     gw_free(buff);
660 }
661 
662 
socket_init(void)663 void socket_init(void)
664 {
665     setup_official_name();
666 }
667 
socket_shutdown(void)668 void socket_shutdown(void)
669 {
670     octstr_destroy(official_name);
671     official_name = NULL;
672     octstr_destroy(official_ip);
673     official_ip = NULL;
674 }
675 
676 
gw_netaddr_to_octstr(int af,void * src)677 Octstr *gw_netaddr_to_octstr(int af, void *src)
678 {
679     switch (af) {
680     case AF_INET: {
681         char straddr[INET_ADDRSTRLEN];
682         inet_ntop(AF_INET, src, straddr, sizeof(straddr));
683         return octstr_create(straddr);
684     }
685 
686 #ifdef AF_INET6
687     case AF_INET6: {
688         char straddr[INET6_ADDRSTRLEN];
689         inet_ntop(AF_INET6, src, straddr, sizeof(straddr));
690         return octstr_create(straddr);
691     }
692 #endif
693 
694     default:
695         return NULL;
696     }
697 }
698 
699 
gw_accept(int fd,Octstr ** client_addr)700 int gw_accept(int fd, Octstr **client_addr)
701 {
702     struct sockaddr_in addr;
703     socklen_t addrlen;
704     int new_fd;
705 
706     if (gwthread_pollfd(fd, POLLIN, -1.0) != POLLIN) {
707 	debug("gwlib.socket", 0, "gwthread_pollfd interrupted or failed");
708 	return -1;
709     }
710     addrlen = sizeof(addr);
711     new_fd = accept(fd, (struct sockaddr *) &addr, &addrlen);
712     if (new_fd == -1) {
713 	error(errno, "accept system call failed.");
714 	return -1;
715     }
716     *client_addr = host_ip(addr);
717     debug("test_smsc", 0, "accept() succeeded, client from %s",
718 	  octstr_get_cstr(*client_addr));
719     return new_fd;
720 }
721