Watt-32 tcp/ip  2.2 dev-rel.10
listen.c
Go to the documentation of this file.
1 
5 /* BSD sockets functionality for Watt-32 TCP/IP
6  *
7  * Copyright (c) 1997-2002 Gisle Vanem <gvanem@yahoo.no>
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in the
16  * documentation and/or other materials provided with the distribution.
17  * 3. All advertising materials mentioning features or use of this software
18  * must display the following acknowledgement:
19  * This product includes software developed by Gisle Vanem
20  * Bergen, Norway.
21  *
22  * THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED. IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
26  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
29  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  * Version
34  *
35  * 0.5 : Dec 18, 1997 : G. Vanem - created
36  * 0.6 : Aug 08, 2002 : G. Vanem - added AF_INET6 support
37  */
38 
39 #include "socket.h"
40 
41 #if defined(USE_BSD_API)
42 
43 int W32_CALL listen (int s, int backlog)
44 {
46 
47  SOCK_PROLOGUE (socket, "\nlisten:%d", s);
48 
49  if (!socket->local_addr) /* bind() not called */
50  {
51  SOCK_DEBUGF ((", EINVAL"));
52  SOCK_ERRNO (EINVAL);
53  return (-1);
54  }
55 
56  if (socket->so_type != SOCK_STREAM)
57  {
58  SOCK_DEBUGF ((", EOPNOTSUPP"));
59  SOCK_ERRNO (EOPNOTSUPP);
60  return (-1);
61  }
62 
63  _sock_set_syn_hook (_sock_append);
64 
65 #if defined(USE_IPV6)
66  if (socket->so_family == AF_INET6)
67  {
68  struct in6_addr addr;
69 
70  memset (&addr, 0, sizeof(addr)); /* unspecified addr */
71  _TCP6_listen (socket, &addr, socket->local_addr->sin_port);
72  }
73  else
74 #endif
75  {
76  struct in_addr addr;
77 
78  addr.s_addr = INADDR_ANY;
79  _TCP_listen (socket, addr, socket->local_addr->sin_port);
80  }
81 
82  SOCK_DEBUGF ((", port %d", ntohs(socket->local_addr->sin_port)));
83 
84  /* A listen socket should never time out unless
85  * setsockopt(SO_RCVTIMEOUT) is called prior to
86  * accept().
87  */
88  socket->timeout = 0;
89  socket->so_state |= SS_ISLISTENING;
90  socket->so_options |= SO_ACCEPTCONN;
91 
92  /* legal backlog range [1..SOMAXCONN>
93  */
94  socket->backlog = min (backlog, SOMAXCONN-1);
95  socket->backlog = max (socket->backlog, 1);
96  SOCK_DEBUGF ((", backlog %d ", socket->backlog));
97  return (0);
98 }
99 
100 #if defined(TEST_PROG) /* A simple finger server */
101 
102 #ifndef __CYGWIN__
103 #include <conio.h>
104 #endif
105 
106 #define FINGER_PORT 79
107 
108 int main (void)
109 {
110  struct sockaddr_in addr;
111  int serv_sock, cli_sock = -1;
112  BOOL quit = FALSE;
113 
114  dbug_init();
115 
116  serv_sock = socket (AF_INET, SOCK_STREAM, 0);
117  if (serv_sock < 0)
118  {
119  perror ("socket");
120  return (-1);
121  }
122 
123  memset (&addr, 0, sizeof(addr));
124  addr.sin_family = AF_INET;
125  addr.sin_port = htons (FINGER_PORT);
126  addr.sin_addr.s_addr = htonl (INADDR_ANY);
127 
128  if (bind(serv_sock, (struct sockaddr*)&addr, sizeof(addr)) < 0)
129  {
130  perror ("bind");
131  close_s (serv_sock);
132  return (-1);
133  }
134 
135  if (listen(serv_sock, 5) == -1)
136  {
137  perror ("listen");
138  close_s (serv_sock);
139  return (-1);
140  }
141 
142  printf ("Watt-32 finger server.\nPress ESC to quit\n");
143 
144  while (!quit)
145  {
146  struct timeval tv = { 1, 0 };
147  struct sockaddr_in peer;
148  const char *who = "Login Name Tty Idle Login Time\r\n"
149  "root root *1 Aug 22 10:15\r\n"
150  "guest guest *2 Aug 22 11:22\r\n";
151  fd_set rd;
152  int len = sizeof(peer);
153  int num;
154 
155  if (kbhit() && getch() == 27)
156  quit = TRUE;
157 
158  FD_ZERO (&rd);
159  FD_SET (serv_sock, &rd);
160 
161  num = select_s (serv_sock+1, &rd, NULL, NULL, &tv);
162  if (num < 0)
163  {
164  perror ("select_s");
165  break;
166  }
167  if (num == 0)
168  {
169  putchar ('.');
170  fflush (stdout);
171  continue;
172  }
173 
174  if (!FD_ISSET(serv_sock,&rd))
175  continue;
176 
177  cli_sock = accept (serv_sock, (struct sockaddr*)&peer, &len);
178  if (cli_sock < 0)
179  {
180  perror ("accept");
181  break;
182  }
183 
184  printf ("Finger request from %s (%u)\n",
185  inet_ntoa(peer.sin_addr), ntohs(peer.sin_port));
186 
187  if (send(cli_sock, who, strlen(who), 0) < 0)
188  {
189  perror ("write_s");
190  break;
191  }
192  close_s (cli_sock); /* ready for next client */
193  cli_sock = -1;
194  }
195 
196  if (cli_sock != -1)
197  close_s (cli_sock);
198  close_s (serv_sock);
199  return (0);
200 }
201 #endif /* TEST_PROG */
202 #endif /* USE_BSD_API */
Definition: wtypes.h:197
int W32_CALL select_s(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
The select_s() function.
Definition: select.c:112
int _sock_append(_tcp_Socket **tcp)
Called from tcp_fsm.c / tcp_listen_state() (via _bsd_socket_hook) to append a new connection to the l...
Definition: accept.c:418
Definition: socket.h:137
Definition: if.h:84
Socket * _socklist_find(int s)
Returns a pointer to the Socket structure associated with socket 's'.
Definition: socket.c:1534
Definition: in.h:153
Definition: in.h:146
Definition: wtime.h:38
int W32_CALL socket(int family, int type, int protocol)
socket().
Definition: socket.c:1794
int W32_CALL bind(int s, const struct sockaddr *myaddr, int namelen)
bind() - bind name to socket.
Definition: bind.c:63
int W32_CALL accept(int s, struct sockaddr *addr, int *addrlen)
Definition: accept.c:59
int _TCP6_listen(Socket *socket, const void *host, WORD loc_port)
Definition: socket.c:2202
int main(int argc, char **argv)
Definition: echo.c:223