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