4 * This file is a part of the revinetd project
6 * Revinetd is copyright (c) 2003-2008 by Steven M. Gill
7 * and distributed under the GPL.
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
30 static const char cvsid
[] = "$Id: misc.c,v 1.26 2008/08/28 03:24:59 necrotaur Exp $";
33 read_from_client(int filedes
)
38 nbytes
= read(filedes
, buffer
, 1024);
43 } else if (nbytes
== 0) {
47 fprintf(stderr
, "Server: got message: `%s'\n", buffer
);
53 copy_between_ports(int src_file
, int dst_file
)
55 char buffer
[SZ_READ_BUFFER
];
58 nbytes
= read(src_file
, buffer
, SZ_READ_BUFFER
);
62 //old: exit(EXIT_FAILURE);
64 } else if (nbytes
== 0) {
68 /* fprintf (stderr, "Server: got message: `%s'\n", buffer); */
69 write(dst_file
, buffer
, nbytes
);
75 get_comm_message(int src_file
)
77 char buffer
[SZ_READ_BUFFER
];
80 nbytes
= read(src_file
, buffer
, SZ_READ_BUFFER
);
85 } else if (nbytes
== 0) {
89 /* fprintf (stderr, "Server: got message: `%s'\n", buffer); */
95 send_comm_message(int dst_file
, int message
)
97 char *buffer
= (char*)&message
;
98 int nbytes
= sizeof(buffer
);
100 write(dst_file
, buffer
, nbytes
);
106 make_socket_IPv4(const char *hostname
, unsigned short port
)
108 int sock
, sock_opt
= 1;
109 struct sockaddr_in name
;
110 struct hostent
*hostinfo
;
111 struct in_addr saddr
;
113 /* Create the socket. */
114 sock
= socket(PF_INET
, SOCK_STREAM
, 0);
120 /* Set SO_REUSEADDR */
121 setsockopt(sock
, SOL_SOCKET
, SO_REUSEADDR
, &sock_opt
, sizeof(sock_opt
));
124 /* Give the socket a name. */
125 name
.sin_family
= AF_INET
;
126 name
.sin_port
= htons(port
);
127 /* check if ip address or resolve hostname */
128 #ifdef HAVE_INET_ATON
129 if (!inet_aton(hostname
, &saddr
)) {
131 saddr
.s_addr
= inet_addr(hostname
);
132 if (saddr
.s_addr
== -1) {
134 hostinfo
= gethostbyname(hostname
);
135 if (hostinfo
== NULL
) {
136 fprintf(stderr
, "Unknown host %s.\n", hostname
);
139 name
.sin_addr
= *(struct in_addr
*)hostinfo
->h_addr
;
141 name
.sin_addr
= saddr
;
143 /* name.sin_addr.s_addr = htonl(INADDR_ANY); */
144 if (bind(sock
, (struct sockaddr
*)&name
, sizeof(name
)) < 0) {
153 make_socket_IPv6(const char *hostname
, unsigned short port
)
155 int sock6
, sock_opt
= 1;
156 struct sockaddr_in6 name
;
157 //struct hostent *hostinfo;
158 struct in6_addr saddr
;
159 // char str[INET6_ADDRSTRLEN];
161 /* Create the socket. */
162 sock6
= socket(AF_INET6
, SOCK_STREAM
, 0);
168 /* Set SO_REUSEADDR */
169 setsockopt(sock6
, SOL_SOCKET
, SO_REUSEADDR
, &sock_opt
, sizeof(sock_opt
));
172 /* Give the socket a name. */
173 //name.sin6_len = sizeof(name);
174 name
.sin6_family
= AF_INET6
;
175 name
.sin6_flowinfo
= 0;
176 name
.sin6_port
= htons(port
);
178 /* check if ip address or resolve hostname */
179 // https://man7.org/linux/man-pages/man3/inet_pton.3.html
180 if (inet_pton(AF_INET6
, hostname
, &saddr
) == 0)
182 //#ifdef HAVE_INET_ATON
183 // if (!inet_aton(hostname, &saddr)) {
185 // saddr.s_addr = inet_addr(hostname);
186 // if (saddr.s_addr == -1) {
188 fprintf(stderr
, "Not a valid IPv6 numeric address, and address lookup not implemented for supposed IPv6 hostname %s.\n", hostname
);
190 //hostinfo = gethostbyname(hostname);
191 //if (hostinfo == NULL) {
192 // fprintf(stderr, "Unknown host %s.\n", hostname);
193 // exit(EXIT_FAILURE);
195 //name.sin6_addr = *(struct in6_addr *)hostinfo->h_addr;
197 name
.sin6_addr
= saddr
;
199 /* name.sin_addr.s_addr = htonl(INADDR_ANY); */
200 if (bind(sock6
, (struct sockaddr
*)&name
, sizeof(name
)) < 0) {
208 // Returns AF_INET6 if hostname is a string of format "[...]" (i.e.
209 // something enclosed in square brackets, or AF_INET if not
210 // enclosed in square brackets. Returns -1 if the format is ambiguous
211 // due to only one bracket occuring.
212 // If AF_INET6 is returned, the hostname_stripped will contain the
213 // string value of hostname without the brackets. (Must have been allocated
214 // of sufficient size.)
216 detect_address_family(const char *hostname
, char *hostname_stripped
)
219 if ((x
=strlen(hostname
)) > 2) {
220 if (hostname
[0] == '[') {
221 if (hostname
[x
-1] == ']') {
222 strncpy(hostname_stripped
, &(hostname
[1]), x
-2);
223 hostname_stripped
[x
-2] = '\0';
235 init_sockaddr(struct sockaddr_in
*name
, const char *hostname
,
239 struct hostent
*hostinfo
;
240 struct in_addr saddr
;
242 /* Create the socket. */
243 sock
= socket(PF_INET
, SOCK_STREAM
, 0);
249 name
->sin_family
= AF_INET
;
250 name
->sin_port
= htons(port
);
251 #ifdef HAVE_INET_ATON
252 if (!inet_aton(hostname
, &saddr
)) {
254 saddr
.s_addr
= inet_addr(hostname
);
255 if (saddr
.s_addr
== -1) {
257 hostinfo
= gethostbyname(hostname
);
258 if (hostinfo
== NULL
) {
259 fprintf(stderr
, "Unknown host %s.\n", hostname
);
262 name
->sin_addr
= *(struct in_addr
*)hostinfo
->h_addr
;
264 name
->sin_addr
= saddr
;
266 memset(name
->sin_zero
, '\0', 8);
272 register_sock(int sock
)
274 OpenSockets
*open_sock
;
276 /* Get a new OpenSockets struct. */
277 open_sock
= malloc(sizeof(OpenSockets
));
278 if (open_sock
== NULL
) {
282 memset(open_sock
, 0, sizeof(OpenSockets
));
284 /* Fill the struct. */
285 open_sock
->sock
= sock
;
287 /* Insert the struct. */
288 open_sock
->prev
= NULL
;
289 open_sock
->next
= conf
.open_sock
;
290 if (conf
.open_sock
!= NULL
) {
291 conf
.open_sock
->prev
= open_sock
;
293 conf
.open_sock
= open_sock
;
299 unregister_sock(int sock
)
301 OpenSockets
*open_sock
;
303 open_sock
= conf
.open_sock
;
304 while (open_sock
!= NULL
) {
305 if (open_sock
->sock
== sock
) {
306 /* Remove link from previous or first entry. */
307 if (open_sock
->prev
!= NULL
)
308 open_sock
->prev
->next
= open_sock
->next
;
310 conf
.open_sock
= open_sock
->next
;
311 /* Remove link from next entry. */
312 if (open_sock
->next
!= NULL
)
313 open_sock
->next
->prev
= open_sock
->prev
;
314 /* Free OpenSockets struct. */
317 if (shutdown(sock
, SHUT_RDWR
) == -1)
318 return 0; /* Socket couldn't be closed. */
320 /* Return success. */
323 open_sock
= open_sock
->next
;
326 /* Socket not found. */