6 Copyright (C) 1999,2004 by Wolfgang Zekoll <wzk@quietsche-entchen.de>
8 This source is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 1, or (at your option)
13 This source is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
33 #include <sys/types.h>
34 #include <sys/socket.h>
36 #include <netinet/in.h>
46 unsigned int get_interface_info(int pfd, peer_t *sock)
49 struct sockaddr_in saddr;
52 if (getsockname(pfd, (struct sockaddr *) &saddr, &size) < 0)
53 printerror(1, "-ERR", "can't get sockname, error= %s", strerror(errno));
55 copy_string(sock->ipnum, (char *) inet_ntoa(saddr.sin_addr), sizeof(sock->ipnum));
56 sock->port = ntohs(saddr.sin_port);
57 copy_string(sock->name, sock->ipnum, sizeof(sock->name));
63 static void alarm_handler()
69 * This version of openip() was copied+pasted from ftp.proxy -- 28OCT04wzk
72 int openip(char *host, unsigned int port, char *srcip, unsigned int srcport)
75 struct sockaddr_in server;
76 struct hostent *hostp, *gethostbyname();
78 socketd = socket(AF_INET, SOCK_STREAM, 0);
82 if (srcip != NULL && *srcip != 0) {
83 struct sockaddr_in laddr;
89 setsockopt (socketd, SOL_SOCKET, SO_REUSEADDR, (int *) &one, sizeof(one));
93 * Bind local socket to srcport and srcip
96 memset(&laddr, 0, sizeof(laddr));
97 laddr.sin_family = AF_INET;
98 laddr.sin_port = htons(srcport);
100 if (srcip == NULL || *srcip == 0)
101 srcip = "0.0.0.0"; /* Can't happen but who cares. */
105 ifp = gethostbyname(srcip);
107 printerror(1, "-ERR", "can't lookup %s", srcip);
109 memcpy(&laddr.sin_addr, ifp->h_addr, ifp->h_length);
112 if (bind(socketd, (struct sockaddr *) &laddr, sizeof(laddr)))
113 printerror(1, "-ERR", "can't bind to %s:%u", srcip, ntohs(laddr.sin_port));
117 server.sin_family = AF_INET;
118 hostp = gethostbyname(host);
122 memcpy(&server.sin_addr, hostp->h_addr, hostp->h_length);
123 server.sin_port = htons(port);
125 signal(SIGALRM, alarm_handler);
127 if (connect(socketd, (struct sockaddr *) &server, sizeof(server)) < 0)
131 signal(SIGALRM, SIG_DFL);
136 unsigned int getportnum(char *name)
139 struct servent *portdesc;
141 if (isdigit(*name) != 0)
144 portdesc = getservbyname(name, "tcp");
145 if (portdesc == NULL)
146 printerror(1, "-ERR", "service not found: %s", name);
148 port = ntohs(portdesc->s_port);
150 printerror(1, "-ERR", "port error: %s", name);
156 unsigned int get_port(char *server, unsigned int def_port)
161 if ((p = strchr(server, ':')) == NULL)
165 port = getportnum(p);
170 int bind_to_port(char *interface, unsigned int port)
172 struct sockaddr_in saddr;
175 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
176 printerror(1, "-ERR", "can't create socket: %s", strerror(errno));
181 setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
185 memset(&saddr, 0, sizeof(saddr));
186 saddr.sin_family = AF_INET;
187 saddr.sin_port = htons(port);
189 if (interface == NULL || *interface == 0)
190 interface = "0.0.0.0";
194 ifp = gethostbyname(interface);
196 printerror(1, "-ERR", "can't lookup %s", interface);
198 memcpy(&saddr.sin_addr, ifp->h_addr, ifp->h_length);
202 if (bind(sock, (struct sockaddr *) &saddr, sizeof(saddr)))
203 printerror(1, "-ERR", "can't bind to %s:%u", interface, port);
205 if (listen(sock, 5) < 0)
206 printerror(1, "-ERR", "listen error: %s", strerror(errno));
211 int acceptloop(int sock)
213 int connect, pid, len;
214 struct sockaddr_in client;
218 else if ((pid = fork()) > 0)
222 fprintf (stderr, "%u: entering daemon mode ...\n", getpid());
225 len = sizeof(client);
226 if ((connect = accept(sock, (struct sockaddr *) &client, &len)) < 0) {
227 if (errno == EINTR || errno == ECONNABORTED)
230 fprintf (stderr, "%u: accept error: %s\n", getpid(), strerror(errno));
234 if ((pid = fork()) < 0) {
235 fprintf (stderr, "%u: can't fork process: %s\n", getpid(), strerror(errno));
240 struct linger linger;
244 optlen = sizeof(linger);
245 if (setsockopt(connect, SOL_SOCKET, SO_LINGER, &linger, optlen) != 0)
246 fprintf (stderr, "%u: can't set linger\n", getpid());
261 fprintf (stderr, "%u: terminating\n", getpid());
267 int getpeerinfo(int pfd, char *ipnum, int ipsize, char *name, int namesize, int interface)
270 struct sockaddr_in saddr;
271 struct in_addr *addr;
272 struct hostent *hostp = NULL;
275 size = sizeof(saddr);
277 rc = getpeername(pfd, (struct sockaddr *) &saddr, &size);
279 rc = getsockname(pfd, (struct sockaddr *) &saddr, &size);
283 copy_string(ipnum, isatty(pfd) == 0? "127.0.0.2": "127.0.0.1", ipsize - 2);
285 copy_string(ipnum, "127.0.0.1", ipsize - 2);
288 copy_string(name, "localhost", namesize);
293 copy_string(ipnum, (char *) inet_ntoa(saddr.sin_addr), ipsize);
295 addr = &saddr.sin_addr,
296 hostp = gethostbyaddr((char *) addr,
297 sizeof (saddr.sin_addr.s_addr), AF_INET);
300 copy_string(name, ipnum, namesize - 2);
302 copy_string(name, hostp->h_name, namesize - 2);