summaryrefslogtreecommitdiff
path: root/other/ldistfp/src/network.c
diff options
context:
space:
mode:
authorRoot THC2026-02-24 12:42:47 +0000
committerRoot THC2026-02-24 12:42:47 +0000
commitc9cbeced5b3f2bdd7407e29c0811e65954132540 (patch)
treeaefc355416b561111819de159ccbd86c3004cf88 /other/ldistfp/src/network.c
parent073fe4bf9fca6bf40cef2886d75df832ef4b6fca (diff)
initial
Diffstat (limited to 'other/ldistfp/src/network.c')
-rw-r--r--other/ldistfp/src/network.c712
1 files changed, 712 insertions, 0 deletions
diff --git a/other/ldistfp/src/network.c b/other/ldistfp/src/network.c
new file mode 100644
index 0000000..56f954a
--- /dev/null
+++ b/other/ldistfp/src/network.c
@@ -0,0 +1,712 @@
1
2/* scut's leet network library ;)
3 * 1999 (c) scut
4 *
5 * networking routines
6 * based on my hbot networking sources,
7 * revised, extended and adapted 990405
8 * extended, improved and fixed 990430
9 *
10 * nearly all of this code wouldn't have been possible without w. richard stevens
11 * excellent network coding book. if you are interested in network coding,
12 * there is no way around it.
13 */
14
15#include <sys/types.h>
16#include <sys/ioctl.h>
17#include <sys/socket.h>
18#include <sys/time.h>
19#include <netinet/in.h>
20#include <arpa/inet.h>
21#include <netdb.h>
22#include <net/if.h>
23#include <errno.h>
24#include <fcntl.h>
25#include <stdarg.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#include <unistd.h>
30#include "network.h"
31
32int net_readtimeout = NET_READTIMEOUT;
33int net_conntimeout = NET_CONNTIMEOUT;
34int net_identtimeout = NET_IDENTTIMEOUT;
35
36
37int
38net_socks_connect (char *socks, unsigned short int sport, char *server, unsigned short int port, int sec)
39{
40 int s5s;
41 struct sockaddr_in cs;
42
43 s5s = net_connect (&cs, socks, sport, NULL, 0, sec);
44 if (s5s == -1)
45 return (-1);
46
47 if (net_socks_put_s5info (s5s, server, port, sec) == -1) {
48 close (s5s);
49 return (-1);
50 }
51 return (s5s);
52}
53
54
55int
56net_socks_put_s5info (int s5s, char *server, unsigned short int port, int sec)
57{
58 int n;
59 char buff[1024];
60
61 /* v5 + noauth */
62 net_write (s5s, "\x05\x01%c", 0);
63 if (net_rtimeout (s5s, sec) == -1)
64 return (-1);
65 recv (s5s, buff, sizeof (buff), 0);
66
67 /* chain us =) */
68 net_write (s5s, "\x05\x01%c\x03%c%s%c%c", 0, strlen (server), server, (port >> 8) & 0xff, port & 0xff);
69 if (net_rtimeout (s5s, sec) == -1)
70 return (-1);
71 n = recv (s5s, buff, sizeof (buff), 0);
72 if (buff[1] != 0x00) {
73 return (-1);
74 }
75 return (1);
76}
77
78
79int
80net_parseip (char *inp, char **ip, unsigned short int *port)
81{
82 int n;
83
84 if (inp == NULL)
85 return (0);
86 if (strchr (inp, ':') == NULL)
87 return (0);
88
89 *ip = calloc (1, 256);
90 if (*ip == NULL)
91 return (0);
92
93 n = sscanf (inp, "%[^:]:%hu", *ip, port);
94 if (n != 2)
95 return (0);
96
97 *ip = realloc (*ip, strlen (*ip) + 1);
98 if (*ip == NULL || (*port < 1 || *port > 65535))
99 return (0);
100
101 return (1);
102}
103
104
105char *
106net_getlocalip (void)
107{
108 struct sockaddr_in pf;
109 char name[255];
110
111 memset (name, '\0', sizeof (name));
112
113 if (gethostname (name, sizeof (name) - 1) == -1) {
114 return (NULL);
115 }
116
117 pf.sin_addr.s_addr = net_resolve (name);
118
119 return (strdup (inet_ntoa (pf.sin_addr)));;
120}
121
122
123char *
124net_peeraddress (int socket)
125{
126 char * hip;
127 struct sockaddr_in peeraddr;
128 size_t size = sizeof (struct sockaddr_in);
129
130 if (getpeername (socket, (struct sockaddr *) &peeraddr, &size) == -1)
131 return (NULL);
132
133 net_printipa (&peeraddr.sin_addr, &hip);
134
135 return (hip);
136}
137
138
139FILE *
140net_descriptify (int socket)
141{
142 FILE *fp;
143
144 fp = fdopen (socket, "r+");
145 return ((fp == NULL) ? (NULL) : (fp));
146}
147
148
149/* loosely based on rfc931.c */
150
151int
152net_ident (char **ident, struct sockaddr_in *locals, unsigned short int localport,
153 struct sockaddr_in *remotes, unsigned short int remoteport)
154{
155 int is; /* ident socket */
156 struct sockaddr_in isa;
157 int n;
158 char identreply[512], *cp;
159 unsigned int rmt_port, our_port;
160
161
162 *ident = NULL;
163
164 is = net_connect (&isa, inet_ntoa (remotes->sin_addr), 113, NULL, 0, net_identtimeout);
165 if (is == -1)
166 return (-1);
167
168 /* ident request */
169 net_write (is, "%u,%u\r\n", remoteport, localport);
170 memset (identreply, '\0', sizeof (identreply));
171
172 n = net_rlinet (is, identreply, sizeof(identreply) -1, net_identtimeout);
173 if (n == -1) {
174 close (is);
175 return (-1);
176 }
177 close (is);
178
179 *ident = calloc (1, 256);
180#ifdef DEBUG
181 printf("%s\n", identreply);
182#endif
183 n = sscanf (identreply, "%u , %u : USERID :%*[^:]:%255s", &rmt_port, &our_port, *ident);
184 if (n != 3) {
185 free (*ident);
186 *ident = NULL;
187 return (-1);
188 }
189
190 /* check the ports 'man */
191 if ((rmt_port != remoteport) || (our_port != localport)) {
192 free (*ident);
193 *ident = NULL;
194 return (-1);
195 }
196
197 /* strip character and save some memory */
198 if ((cp = strchr (*ident, '\r')))
199 *cp = '\0';
200 n = strlen (*ident);
201 *ident = realloc (*ident, n + 1);
202 (*ident)[n] = '\0';
203
204#ifdef DEBUG
205 printf("ident-return: %s\n", *ident);
206#endif
207 return (1);
208}
209
210
211int
212net_accept (int s, struct sockaddr_in *cs, int maxsec)
213{
214 int flags, n;
215 fd_set ac_s;
216 int len;
217 struct timeval tval;
218
219 flags = fcntl(s, F_GETFL, 0);
220 if (flags == -1)
221 return (-1);
222 n = fcntl(s, F_SETFL, flags | O_NONBLOCK);
223 if (n == -1)
224 return (-1);
225
226 FD_ZERO(&ac_s);
227 FD_SET(s, &ac_s);
228 tval.tv_sec = maxsec;
229 tval.tv_usec = 0;
230
231 n = select(s + 1, &ac_s, NULL, NULL, maxsec ? &tval : NULL);
232 if (n == 0)
233 return (0);
234
235 if (FD_ISSET(s, &ac_s)) {
236 len = sizeof(struct sockaddr_in);
237 n = accept(s, (struct sockaddr *) cs, &len);
238 if (n == -1) {
239 switch (errno) {
240 case EWOULDBLOCK:
241 case ECONNABORTED:
242 case EINTR: if (fcntl(s, F_SETFL, flags) == -1)
243 return (-1);
244 return (0);
245 default: return (-1);
246 }
247 }
248 if (fcntl(s, F_SETFL, flags) == -1)
249 return (-1);
250 return (n);
251 }
252 if (fcntl(s, F_SETFL, flags) == -1)
253 return (-1);
254 return (0);
255}
256
257
258void
259net_boundfree (bound *bf)
260{
261 close (bf->bs);
262 free (bf);
263 return;
264}
265
266
267bound *
268net_bind (char *ip, unsigned short int port)
269{
270 bound *b;
271 int br, gsnr, lr;
272 int len, reusetmp;
273 struct sockaddr_in *sap;
274
275 if (port >= 65536)
276 return (NULL);
277
278 b = calloc(1, sizeof (bound));
279 if (b == NULL)
280 return (NULL);
281 b->bs = socket (AF_INET, SOCK_STREAM, 0);
282 if (b->bs == -1)
283 goto berror;
284
285 reusetmp = 1;
286#ifdef SO_REUSEPORT
287 if (setsockopt (b->bs, SOL_SOCKET, SO_REUSEPORT, &reusetmp, sizeof (reusetmp)) == -1)
288 goto berror;
289#else
290 if (setsockopt (b->bs, SOL_SOCKET, SO_REUSEADDR, &reusetmp, sizeof (reusetmp)) == -1)
291 goto berror;
292#endif
293
294 sap = (struct sockaddr_in *) &b->bsa;
295 sap->sin_family = AF_INET;
296 sap->sin_port = htons (port); /* 0 = ephemeral */
297
298 if (ip != NULL) {
299 if (strcmp (ip, "*") == 0) {
300 sap->sin_addr.s_addr = htonl (INADDR_ANY);
301 } else {
302 if (!(sap->sin_addr.s_addr = net_resolve (ip))) {
303 goto berror;
304 }
305 }
306 } else {
307 sap->sin_addr.s_addr = htonl (INADDR_ANY);
308 }
309
310 br = bind (b->bs, (struct sockaddr *) &b->bsa, sizeof (struct sockaddr));
311 if (br == -1)
312 goto berror;
313
314 len = sizeof (struct sockaddr);
315 gsnr = getsockname (b->bs, (struct sockaddr *) &b->bsa, &len);
316 b->port = ntohs (sap->sin_port);
317 if (gsnr == -1)
318 goto berror;
319
320 lr = listen (b->bs, 16);
321 if (lr == -1) {
322 goto berror;
323 }
324 return (b);
325
326berror:
327 free (b);
328
329 return(NULL);
330}
331
332
333unsigned long int
334net_resolve (char *host)
335{
336 long i;
337 struct hostent *he;
338
339 i = inet_addr(host);
340 if (i == -1) {
341 he = gethostbyname(host);
342 if (he == NULL) {
343 return (0);
344 } else {
345 return (*(unsigned long *) he->h_addr);
346 }
347 }
348 return (i);
349}
350
351
352int
353net_assignaddr (int sd, char *sourceip, unsigned short int sourceport)
354{
355 struct sockaddr_in sourcedef;
356
357 if (sourceip && strcmp (sourceip, "*") == 0)
358 sourceip = NULL;
359
360 if (sourceip == NULL && sourceport == 0)
361 return (1);
362
363 memset (&sourcedef, '\0', sizeof (struct sockaddr_in));
364
365 /* if sourceip is specified, set it */
366 if (sourceip) {
367 sourcedef.sin_addr.s_addr = net_resolve (sourceip);
368 } else {
369 sourcedef.sin_addr.s_addr = htonl (INADDR_ANY);
370 }
371 if (sourceport)
372 sourcedef.sin_port = htons (sourceport);
373
374 /* now set the source on the socket by binding it */
375 if (bind (sd, (struct sockaddr *) &sourcedef, sizeof (struct sockaddr_in)) == -1) {
376 return (0);
377 }
378
379 return (1);
380}
381
382
383int
384net_connect (struct sockaddr_in *cs, char *server, unsigned short int port, char *sourceip,
385 unsigned short int sourceport, int sec)
386{
387 int n,
388 len,
389 error,
390 flags;
391 int fd;
392 struct timeval tv;
393 fd_set rset, wset;
394 struct sockaddr_in csa;
395
396 if (cs == NULL)
397 cs = &csa;
398
399 /* first allocate a socket */
400 cs->sin_family = AF_INET;
401 cs->sin_port = htons (port);
402 fd = socket (cs->sin_family, SOCK_STREAM, 0);
403 if (fd == -1)
404 return (-1);
405
406 /* check wether we should change the defaults */
407 if (net_assignaddr (fd, sourceip, sourceport) == 0) {
408 close (fd);
409 return (-1);
410 }
411
412 if (!(cs->sin_addr.s_addr = net_resolve (server))) {
413 close (fd);
414 return (-1);
415 }
416
417 flags = fcntl (fd, F_GETFL, 0);
418 if (flags == -1) {
419 close (fd);
420 return (-1);
421 }
422 n = fcntl (fd, F_SETFL, flags | O_NONBLOCK);
423 if (n == -1) {
424 close (fd);
425 return (-1);
426 }
427
428 error = 0;
429
430 n = connect (fd, (struct sockaddr *) cs, sizeof (struct sockaddr_in));
431 if (n < 0) {
432 if (errno != EINPROGRESS) {
433 close (fd);
434 return (-1);
435 }
436 }
437 if (n == 0)
438 goto done;
439
440 FD_ZERO(&rset);
441 FD_ZERO(&wset);
442 FD_SET(fd, &rset);
443 FD_SET(fd, &wset);
444 tv.tv_sec = sec;
445 tv.tv_usec = 0;
446
447 n = select(fd + 1, &rset, &wset, NULL, &tv);
448 if (n == 0) {
449 close(fd);
450 errno = ETIMEDOUT;
451 return (-1);
452 }
453 if (n == -1)
454 return (-1);
455
456 if (FD_ISSET(fd, &rset) || FD_ISSET(fd, &wset)) {
457 if (FD_ISSET(fd, &rset) && FD_ISSET(fd, &wset)) {
458 len = sizeof(error);
459 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
460 errno = ETIMEDOUT;
461 return (-1);
462 }
463 if (error == 0) {
464 goto done;
465 } else {
466 errno = error;
467 return (-1);
468 }
469 }
470 } else
471 return (-1);
472
473done:
474 n = fcntl(fd, F_SETFL, flags);
475 if (n == -1)
476 return (-1);
477 return (fd);
478}
479
480
481int
482net_tline (char *buf, int bufsize)
483{
484 int p;
485
486 for (p = 0; p < bufsize; p++) {
487 if (buf[p] == '\n')
488 return (p + 1);
489 }
490 return (-1);
491}
492
493#define LINET_A 1024
494
495
496int
497net_rlineta (int fd, char **buf, int sec)
498{
499 int n; /* return value */
500 int bufsize = 0;
501
502 *buf = NULL;
503
504 do {
505 bufsize += LINET_A;
506 *buf = realloc (*buf, bufsize);
507 if (*buf == NULL)
508 return (-1);
509
510 n = net_rlinet (fd, *buf + bufsize - LINET_A, LINET_A, sec);
511
512 if (n == -1)
513 goto rlinetaerr;
514 if (n >= 0)
515 goto rlinetastrip;
516 } while (n == -2);
517
518rlinetastrip:
519 *buf = realloc (*buf, strlen (*buf) + 1);
520 return (strlen (*buf));
521
522rlinetaerr:
523 free (*buf);
524 return (-1);
525}
526
527
528int
529net_rlinet (int fd, char *buf, int bufsize, int sec)
530{
531 int n;
532 unsigned long int rb = 0;
533 struct timeval tv_start, tv_cur;
534
535 memset(buf, '\0', bufsize);
536 (void) gettimeofday(&tv_start, NULL);
537
538 do {
539 (void) gettimeofday(&tv_cur, NULL);
540 if (sec > 0) {
541 if ((((tv_cur.tv_sec * 1000000) + (tv_cur.tv_usec)) -
542 ((tv_start.tv_sec * 1000000) + (tv_start.tv_usec))) > (sec * 1000000)) {
543 return (-1);
544 }
545 }
546 n = net_rtimeout(fd, net_readtimeout);
547 if (n <= 0) {
548 return (-1);
549 }
550 n = read(fd, buf, 1);
551 if (n <= 0) {
552 return (n);
553 }
554 rb++;
555 if (*buf == '\n')
556 return (rb);
557 buf++;
558 if (rb >= bufsize)
559 return (-2); /* buffer full */
560 } while (1);
561}
562
563
564long int
565net_rbuf (int fd, char **dst)
566{
567 long int ml = 0;
568 long int read_bytes;
569 int p;
570
571 *dst = NULL;
572
573 while ((p = net_rtimeout(fd, net_readtimeout)) == 1) {
574 *dst = (char *) realloc(*dst, ml + NET_BSIZE);
575 if (*dst == NULL)
576 return (-1);
577 ml += read_bytes = read(fd, *dst + ml, NET_BSIZE);
578 if (read_bytes == 0) {
579 *dst = (char *) realloc(*dst, ml);
580 if ((*dst == NULL) && (ml == 0)) {
581 return (1);
582 } else if (*dst == NULL) {
583 return (-1);
584 } else {
585 return (ml);
586 }
587 }
588 }
589 return (-1);
590}
591
592
593int
594net_rbuft (int fd, char *dst, unsigned long int dsize)
595{
596 unsigned long int bl = 0, m;
597 int p;
598
599 while (bl < dsize) {
600 p = net_rtimeout(fd, net_readtimeout);
601 if ((p == 0) || (p == -1)) {
602 return (-1);
603 }
604
605 m = read(fd, dst + bl, (dsize - bl));
606 if ((m == 0) || (m == -1)) {
607 return (-1);
608 }
609 bl += m;
610 }
611 return (1);
612}
613
614
615int
616net_rtimeout (int fd, int sec)
617{
618 fd_set rset;
619 struct timeval tv;
620 int n, error, flags;
621
622 error = 0;
623 flags = fcntl(fd, F_GETFL, 0);
624 n = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
625 if (n == -1)
626 return (-1);
627
628 FD_ZERO(&rset);
629 FD_SET(fd, &rset);
630 tv.tv_sec = sec;
631 tv.tv_usec = 0;
632
633 /* now we wait until more data is received then the tcp low level watermark,
634 * which should be setted to 1 in this case (1 is default)
635 */
636
637 n = select(fd + 1, &rset, NULL, NULL, &tv);
638 if (n == 0) {
639 n = fcntl(fd, F_SETFL, flags);
640 if (n == -1)
641 return (-1);
642 errno = ETIMEDOUT;
643 return (-1);
644 }
645 if (n == -1) {
646 return (-1);
647 }
648 /* socket readable ? */
649 if (FD_ISSET(fd, &rset)) {
650 n = fcntl(fd, F_SETFL, flags);
651 if (n == -1)
652 return (-1);
653 return (1);
654 } else {
655 n = fcntl(fd, F_SETFL, flags);
656 if (n == -1)
657 return (-1);
658 errno = ETIMEDOUT;
659 return (-1);
660 }
661}
662
663
664void
665net_write (int fd, const char *str, ...)
666{
667 char tmp[1025];
668 va_list vl;
669 int i;
670
671 va_start(vl, str);
672 memset(tmp, 0, sizeof(tmp));
673 i = vsnprintf(tmp, sizeof(tmp), str, vl);
674 va_end(vl);
675
676#ifdef DEBUG
677 printf("[snd] %s\n", tmp);
678#endif
679
680 send(fd, tmp, i, 0);
681 return;
682}
683
684
685int
686net_printip (struct in_addr *ia, char *str, size_t len)
687{
688 unsigned char *ipp;
689
690 ipp = (unsigned char *) &ia->s_addr;
691 snprintf (str, len - 1, "%d.%d.%d.%d", ipp[0], ipp[1], ipp[2], ipp[3]);
692
693 return (0);
694}
695
696
697int
698net_printipa (struct in_addr *ia, char **str)
699{
700 unsigned char *ipp;
701
702 ipp = (unsigned char *) &ia->s_addr;
703 *str = calloc (1, 256);
704 if (*str == NULL)
705 return (1);
706
707 snprintf (*str, 255, "%d.%d.%d.%d", ipp[0], ipp[1], ipp[2], ipp[3]);
708 *str = realloc (*str, strlen (*str) + 1);
709
710 return ((*str == NULL) ? 1 : 0);
711}
712