]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/netkit-telnet-0.17-ipv6.diff
suricata: Fix amount of listened nfqueues
[ipfire-2.x.git] / src / patches / netkit-telnet-0.17-ipv6.diff
CommitLineData
b52f6eb2
DW
1diff -uNr netkit-telnet-0.17/telnetd/telnetd.c netkit-telnet-0.17.ipv6/telnetd/telnetd.c\r
2--- netkit-telnet-0.17/telnetd/telnetd.c 2006-07-13 08:37:18.000000000 +0200\r
3+++ netkit-telnet-0.17.ipv6/telnetd/telnetd.c 2006-07-14 08:36:11.000000000 +0200\r
4@@ -49,6 +49,7 @@\r
5 /* #include <netinet/ip.h> */ /* Don't think this is used at all here */\r
6 #include <arpa/inet.h>\r
7 #include <assert.h>\r
8+#include <sys/poll.h>\r
9 #include "telnetd.h"\r
10 #include "pathnames.h"\r
11 #include "setproctitle.h"\r
12@@ -68,7 +69,7 @@\r
13 #define HAS_IPPROTO_IP\r
14 #endif\r
15 \r
16-static void doit(struct sockaddr_in *who);\r
17+static void doit(struct sockaddr *who, socklen_t wholen);\r
18 static int terminaltypeok(const char *s);\r
19 \r
20 /*\r
21@@ -90,7 +91,7 @@\r
22 int\r
23 main(int argc, char *argv[], char *env[])\r
24 {\r
25- struct sockaddr_in from;\r
26+ struct sockaddr from;\r
27 int on = 1;\r
28 socklen_t fromlen;\r
29 register int ch;\r
30@@ -248,64 +249,89 @@\r
31 argc -= optind;\r
32 argv += optind;\r
33 \r
34- if (debug) {\r
35- int s, ns;\r
36- socklen_t foo;\r
37- struct servent *sp;\r
38- struct sockaddr_in sn;\r
39+ int s = 0;\r
40 \r
41- memset(&sn, 0, sizeof(sn));\r
42- sn.sin_family = AF_INET;\r
43+ if (debug) {\r
44+ struct addrinfo *ai;\r
45+ unsigned int nfds = 0;\r
46+ struct pollfd fds[2];\r
47 \r
48 if (argc > 1) {\r
49- usage();\r
50- /* NOTREACHED */\r
51- } else if (argc == 1) {\r
52- if ((sp = getservbyname(*argv, "tcp"))!=NULL) {\r
53- sn.sin_port = sp->s_port;\r
54- } \r
55- else {\r
56- int pt = atoi(*argv);\r
57- if (pt <= 0) {\r
58- fprintf(stderr, "telnetd: %s: bad port number\n",\r
59- *argv);\r
60- usage();\r
61- /* NOTREACHED */\r
62- }\r
63- sn.sin_port = htons(pt);\r
64- }\r
65+ usage();\r
66+ /* NOTREACHED */\r
67 } else {\r
68- sp = getservbyname("telnet", "tcp");\r
69- if (sp == 0) {\r
70- fprintf(stderr, "telnetd: tcp/telnet: unknown service\n");\r
71- exit(1);\r
72- }\r
73- sn.sin_port = sp->s_port;\r
74- }\r
75+ struct addrinfo hints;\r
76+\r
77+ memset (&hints, '\0', sizeof (hints));\r
78+ hints.ai_socktype = SOCK_STREAM;\r
79+ hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;\r
80+ hints.ai_protocol = IPPROTO_TCP;\r
81+\r
82+ if (argc == 0) {\r
83+ if (getaddrinfo(NULL, "telnet", &hints, &ai) != 0) {\r
84+ fprintf(stderr, "telnetd: %s: bad port number\n", *argv);\r
85+ usage();\r
86+ /* NOTREACHED */\r
87+ }\r
88+ } else {\r
89+ if (getaddrinfo(NULL, *argv, &hints, &ai) != 0) {\r
90+ fprintf(stderr, "telnetd: %s: bad port number\n", *argv);\r
91+ usage();\r
92+ /* NOTREACHED */\r
93+ }\r
94+ }\r
95+ } \r
96 \r
97- s = socket(AF_INET, SOCK_STREAM, 0);\r
98- if (s < 0) {\r
99+ struct addrinfo *runp;\r
100+ int b = 0;\r
101+ for (runp = ai; ((runp != NULL) && (nfds < sizeof (fds) / sizeof (fds[0]))); runp = runp->ai_next) {\r
102+ fds[nfds].fd = socket(runp->ai_family, runp->ai_socktype, runp->ai_protocol);\r
103+ if (fds[nfds].fd < 0) {\r
104 perror("telnetd: socket");;\r
105- exit(1);\r
106+ exit(1);\r
107+ }\r
108+ fds[nfds].events = POLLIN;\r
109+ (void) setsockopt(fds[nfds].fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));\r
110+\r
111+ if (bind(fds[nfds].fd, runp->ai_addr, runp->ai_addrlen) != 0) {\r
112+ // Unable to bind to given port. One of the reason can be\r
113+ // that we can't bind to both IPv4 and IPv6\r
114+ break;\r
115+ } else { \r
116+ b++;\r
117+ }\r
118+\r
119+ if (listen(fds[nfds].fd, 1) < 0) {\r
120+ perror("listen");\r
121+ exit(1);\r
122+ }\r
123+ nfds++;\r
124 }\r
125- (void) setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));\r
126- if (bind(s, (struct sockaddr *)&sn, sizeof(sn)) < 0) {\r
127- perror("bind");\r
128- exit(1);\r
129- }\r
130- if (listen(s, 1) < 0) {\r
131- perror("listen");\r
132- exit(1);\r
133+ freeaddrinfo(ai);\r
134+\r
135+ if (b == 0) {\r
136+ perror("bind");\r
137+ exit(1);\r
138 }\r
139- foo = sizeof(sn);\r
140- ns = accept(s, (struct sockaddr *)&sn, &foo);\r
141- if (ns < 0) {\r
142- perror("accept");\r
143- exit(1);\r
144+\r
145+ int n = poll (fds, nfds, -1);\r
146+ if (n > 0) {\r
147+ unsigned int i;\r
148+ for (i = 0; i < nfds; i++) {\r
149+ if (fds[i].revents & POLLIN) {\r
150+ struct sockaddr_storage rem;\r
151+ socklen_t remlen = sizeof(rem);\r
152+ int fd = accept(fds[i].fd, (struct sockaddr *) &rem, &remlen);\r
153+\r
154+ if (fd < 0) {\r
155+ perror("accept");\r
156+ exit(1);\r
157+ }\r
158+\r
159+ s = fd;\r
160+ }\r
161+ }\r
162 }\r
163- (void) dup2(ns, 0);\r
164- (void) close(ns);\r
165- (void) close(s);\r
166 } else if (argc > 0) {\r
167 usage();\r
168 /* NOT REACHED */\r
169@@ -313,13 +339,13 @@\r
170 \r
171 openlog("telnetd", LOG_PID | LOG_ODELAY, LOG_DAEMON);\r
172 fromlen = sizeof (from);\r
173- if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {\r
174+ if (getpeername(s, &from, &fromlen) < 0) {\r
175 fprintf(stderr, "%s: ", progname);\r
176 perror("getpeername");\r
177 _exit(1);\r
178 }\r
179 if (keepalive &&\r
180- setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof (on)) < 0) {\r
181+ setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof (on)) < 0) {\r
182 syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");\r
183 }\r
184 \r
185@@ -333,13 +359,13 @@\r
186 if (tos < 0)\r
187 tos = 020; /* Low Delay bit */\r
188 if (tos\r
189- && (setsockopt(0, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0)\r
190+ && (setsockopt(s, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0)\r
191 && (errno != ENOPROTOOPT) )\r
192 syslog(LOG_WARNING, "setsockopt (IP_TOS): %m");\r
193 }\r
194 #endif /* defined(HAS_IPPROTO_IP) && defined(IP_TOS) */\r
195- net = 0;\r
196- doit(&from);\r
197+ net = s;\r
198+ doit(&from, fromlen);\r
199 /* NOTREACHED */\r
200 return 0;\r
201 } /* end of main */\r
202@@ -608,10 +634,9 @@\r
203 * Get a pty, scan input lines.\r
204 */\r
205 static void\r
206-doit(struct sockaddr_in *who)\r
207+doit(struct sockaddr *who, socklen_t wholen)\r
208 {\r
209 const char *host;\r
210- struct hostent *hp;\r
211 int level;\r
212 char user_name[256];\r
213 \r
214@@ -623,12 +648,18 @@\r
215 fatal(net, "All network ports in use");\r
216 \r
217 /* get name of connected client */\r
218- hp = gethostbyaddr((char *)&who->sin_addr, sizeof (struct in_addr),\r
219- who->sin_family);\r
220- if (hp)\r
221- host = hp->h_name;\r
222- else\r
223- host = inet_ntoa(who->sin_addr);\r
224+ int error = -1;\r
225+ char namebuf[255];\r
226+\r
227+ error = getnameinfo(who, wholen, namebuf, sizeof(namebuf), NULL, 0, 0);\r
228+ \r
229+ if (error) {\r
230+ perror("getnameinfo: localhost");\r
231+ perror(gai_strerror(error));\r
232+ exit(1); \r
233+ }\r
234+ \r
235+ host = namebuf;\r
236 \r
237 /*\r
238 * We must make a copy because Kerberos is probably going\r
239@@ -649,13 +680,21 @@\r
240 \r
241 /* Get local host name */\r
242 {\r
243- struct hostent *h;\r
244+ struct addrinfo hints;\r
245+ struct addrinfo *res;\r
246+ int e;\r
247+\r
248+ memset(&hints, '\0', sizeof(hints));\r
249+ hints.ai_socktype = SOCK_STREAM;\r
250+ hints.ai_flags = AI_ADDRCONFIG;\r
251+\r
252 gethostname(host_name, sizeof(host_name));\r
253- h = gethostbyname(host_name);\r
254- if (h) {\r
255- strncpy(host_name, h->h_name, sizeof(host_name));\r
256- host_name[sizeof(host_name)-1] = 0;\r
257+ if ((e = getaddrinfo(host_name, NULL, &hints, &res)) != 0) {\r
258+ perror("getaddrinfo: localhost");\r
259+ perror(gai_strerror(e));\r
260+ exit(1);\r
261 }\r
262+ freeaddrinfo(res);\r
263 }\r
264 \r
265 #if defined(AUTHENTICATE) || defined(ENCRYPT)\r