summaryrefslogtreecommitdiff
path: root/other/ldistfp/src
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
parent073fe4bf9fca6bf40cef2886d75df832ef4b6fca (diff)
initial
Diffstat (limited to 'other/ldistfp/src')
-rw-r--r--other/ldistfp/src/Makefile16
-rw-r--r--other/ldistfp/src/common.c373
-rw-r--r--other/ldistfp/src/common.h33
-rw-r--r--other/ldistfp/src/ldistfp.c368
-rw-r--r--other/ldistfp/src/network.c712
-rw-r--r--other/ldistfp/src/network.h287
6 files changed, 1789 insertions, 0 deletions
diff --git a/other/ldistfp/src/Makefile b/other/ldistfp/src/Makefile
new file mode 100644
index 0000000..f571820
--- /dev/null
+++ b/other/ldistfp/src/Makefile
@@ -0,0 +1,16 @@
1
2#DFLAGS=-O2
3DFLAGS=-g -ggdb
4CC=cc
5CFLAGS=$(DFLAGS) -Wall
6OBJS=common.o network.o
7
8all: ldistfp
9
10clean:
11 rm -f *.o ldistfp
12
13ldistfp: $(OBJS)
14 $(CC) $(CFLAGS) -o ldistfp ldistfp.c $(OBJS)
15# strip ldistfp
16 mv ldistfp ../bin
diff --git a/other/ldistfp/src/common.c b/other/ldistfp/src/common.c
new file mode 100644
index 0000000..bae7ebc
--- /dev/null
+++ b/other/ldistfp/src/common.c
@@ -0,0 +1,373 @@
1
2#include <sys/types.h>
3#include <sys/wait.h>
4#include <sys/time.h>
5#include <netinet/in.h>
6#include <unistd.h>
7#include <time.h>
8#include <stdarg.h>
9#include <stdio.h>
10#include <string.h>
11#include <stdlib.h>
12#include <unistd.h>
13#include "common.h"
14
15
16#ifdef DEBUG
17void
18debugp (char *filename, const char *str, ...)
19{
20 FILE *fp; /* temporary file pointer */
21 va_list vl;
22
23 fp = fopen (filename, "a");
24 if (fp == NULL)
25 return;
26
27 va_start (vl, str);
28 vfprintf (fp, str, vl);
29 va_end (vl);
30
31 fclose (fp);
32
33 return;
34}
35
36void
37hexdump (char *filename, unsigned char *data, unsigned int amount)
38{
39 FILE *fp; /* temporary file pointer */
40 unsigned int dp, p; /* data pointer */
41 const char trans[] =
42 "................................ !\"#$%&'()*+,-./0123456789"
43 ":;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklm"
44 "nopqrstuvwxyz{|}~...................................."
45 "....................................................."
46 "........................................";
47
48 fp = fopen (filename, "a");
49 if (fp == NULL)
50 return;
51
52 fprintf (fp, "\n-packet-\n");
53
54 for (dp = 1; dp <= amount; dp++) {
55 fprintf (fp, "%02x ", data[dp-1]);
56 if ((dp % 8) == 0)
57 fprintf (fp, " ");
58 if ((dp % 16) == 0) {
59 fprintf (fp, "| ");
60 p = dp;
61 for (dp -= 16; dp < p; dp++)
62 fprintf (fp, "%c", trans[data[dp]]);
63 fflush (fp);
64 fprintf (fp, "\n");
65 }
66 fflush (fp);
67 }
68 if ((amount % 16) != 0) {
69 p = dp = 16 - (amount % 16);
70 for (dp = p; dp > 0; dp--) {
71 fprintf (fp, " ");
72 if (((dp % 8) == 0) && (p != 8))
73 fprintf (fp, " ");
74 fflush (fp);
75 }
76 fprintf (fp, " | ");
77 for (dp = (amount - (16 - p)); dp < amount; dp++)
78 fprintf (fp, "%c", trans[data[dp]]);
79 fflush (fp);
80 }
81 fprintf (fp, "\n");
82
83 fclose (fp);
84 return;
85}
86
87#endif
88
89
90/* z_fork
91 *
92 * fork and detach forked client completely to avoid zombies.
93 * taken from richard stevens excellent system programming book :) thanks,
94 * whereever you are now.
95 *
96 * caveat: the pid of the child has already died, it can just be used to
97 * differentiate between parent and not parent, the pid of the
98 * child is inaccessibly.
99 *
100 * return pid of child for old process
101 * return 0 for child
102 */
103
104pid_t
105z_fork (void)
106{
107 pid_t pid;
108
109 pid = fork ();
110 if (pid < 0) {
111 return (pid);
112 } else if (pid == 0) {
113 /* let the child fork again
114 */
115
116 pid = fork ();
117 if (pid < 0) {
118 return (pid);
119 } else if (pid > 0) {
120 /* let the child and parent of the second child
121 * exit
122 */
123 exit (EXIT_SUCCESS);
124 }
125
126 return (0);
127 }
128
129 waitpid (pid, NULL, 0);
130
131 return (pid);
132}
133
134
135/* m_random
136 *
137 * return a random number between `lowmark' and `highmark'
138 */
139
140int
141m_random (int lowmark, int highmark)
142{
143 long int rnd;
144
145 /* flip/swap them in case user messed up
146 */
147 if (lowmark > highmark) {
148 lowmark ^= highmark;
149 highmark ^= lowmark;
150 lowmark ^= highmark;
151 }
152 rnd = lowmark;
153
154 rnd += (random () % (highmark - lowmark));
155
156 /* this is lame, i know :)
157 */
158 return (rnd);
159}
160
161
162/* set_tv
163 *
164 * initializes a struct timeval pointed to by `tv' to a second value of
165 * `seconds'
166 *
167 * return in any case
168 */
169
170void
171set_tv (struct timeval *tv, int seconds)
172{
173 tv->tv_sec = seconds;
174 tv->tv_usec = 0;
175
176 return;
177}
178
179
180/* xstrupper
181 *
182 * uppercase a string `str'
183 *
184 * return in any case
185 */
186
187void
188xstrupper (char *str)
189{
190 for (; *str != '\0'; ++str) {
191 if (*str >= 'a' && *str <= 'z') {
192 *str -= ('a' - 'A');
193 }
194 }
195
196 return;
197}
198
199
200/* concating snprintf
201 *
202 * determines the length of the string pointed to by `os', appending formatted
203 * string to a maximium length of `len'.
204 *
205 */
206
207void
208scnprintf (char *os, size_t len, const char *str, ...)
209{
210 va_list vl;
211 char *ostmp = os + strlen (os);
212
213 va_start (vl, str);
214 vsnprintf (ostmp, len - strlen (os) - 1, str, vl);
215 va_end (vl);
216
217 return;
218}
219
220unsigned long int
221tdiff (struct timeval *old, struct timeval *new)
222{
223 unsigned long int time1;
224
225 if (new->tv_sec >= old->tv_sec) {
226 time1 = new->tv_sec - old->tv_sec;
227 if ((new->tv_usec - 500000) >= old->tv_usec)
228 time1++;
229 } else {
230 time1 = old->tv_sec - new->tv_sec;
231 if ((old->tv_usec - 500000) >= new->tv_usec)
232 time1++;
233 }
234
235 return (time1);
236}
237
238
239/* ipv4_print
240 *
241 * padding = 0 -> don't padd
242 * padding = 1 -> padd with zeros
243 * padding = 2 -> padd with spaces
244 */
245
246char *
247ipv4_print (char *dest, struct in_addr in, int padding)
248{
249 unsigned char *ipp;
250
251 ipp = (unsigned char *) &in.s_addr;
252
253 strcpy (dest, "");
254
255 switch (padding) {
256 case (0):
257 sprintf (dest, "%d.%d.%d.%d",
258 ipp[0], ipp[1], ipp[2], ipp[3]);
259 break;
260 case (1):
261 sprintf (dest, "%03d.%03d.%03d.%03d",
262 ipp[0], ipp[1], ipp[2], ipp[3]);
263 break;
264 case (2):
265 sprintf (dest, "%3d.%3d.%3d.%3d",
266 ipp[0], ipp[1], ipp[2], ipp[3]);
267 break;
268 default:
269 break;
270 }
271
272 return (dest);
273}
274
275
276void *
277xrealloc (void *m_ptr, size_t newsize)
278{
279 void *n_ptr;
280
281 n_ptr = realloc (m_ptr, newsize);
282 if (n_ptr == NULL) {
283 fprintf (stderr, "realloc failed\n");
284 exit (EXIT_FAILURE);
285 }
286
287 return (n_ptr);
288}
289
290
291char *
292xstrdup (char *str)
293{
294 char *b;
295
296 b = strdup (str);
297 if (b == NULL) {
298 fprintf (stderr, "strdup failed\n");
299 exit (EXIT_FAILURE);
300 }
301
302 return (b);
303}
304
305
306void *
307xcalloc (int factor, size_t size)
308{
309 void *bla;
310
311 bla = calloc (factor, size);
312
313 if (bla == NULL) {
314 fprintf (stderr, "no memory left\n");
315 exit (EXIT_FAILURE);
316 }
317
318 return (bla);
319}
320
321/* source by dk
322 */
323
324char *
325allocncat (char **to, char *from, size_t len)
326{
327 int rlen = strlen (from);
328 int null = (*to == NULL);
329
330 len = rlen < len ? rlen : len;
331 *to = xrealloc (*to, (null ? 0 : strlen (*to)) + len + 1);
332 if (null)
333 **to = '\0';
334
335 return (strncat (*to, from, len));
336}
337
338
339char *
340alloccat (char **to, char *from)
341{
342 return (allocncat (to, from, strlen (from)));
343}
344
345
346char *
347file_load (char *pathname)
348{
349 FILE * fp;
350 char * new;
351
352 if (pathname == NULL)
353 return (NULL);
354
355 fp = fopen (pathname, "r");
356 if (fp == NULL)
357 return (NULL);
358
359 new = NULL;
360 while (feof (fp) == 0) {
361 unsigned long int rpos;
362
363 rpos = (new == NULL) ? 0 : strlen (new);
364 new = xrealloc (new, rpos + 1024);
365 memset (new + rpos, '\x00', 1024);
366 fread (new + rpos, sizeof (char), 1023, fp);
367 }
368 fclose (fp);
369 new = xrealloc (new, strlen (new) + 1);
370
371 return (new);
372}
373
diff --git a/other/ldistfp/src/common.h b/other/ldistfp/src/common.h
new file mode 100644
index 0000000..48e28e4
--- /dev/null
+++ b/other/ldistfp/src/common.h
@@ -0,0 +1,33 @@
1
2#ifndef Z_COMMON_H
3#define Z_COMMON_H
4
5
6#include <sys/types.h>
7#include <sys/time.h>
8#include <netinet/in.h>
9#include <unistd.h>
10
11
12#ifdef DEBUG
13void debugp (char *filename, const char *str, ...);
14void hexdump (char *filename, unsigned char *data, unsigned int amount);
15#endif
16pid_t z_fork (void);
17int m_random (int lowmark, int highmark);
18void set_tv (struct timeval *tv, int seconds);
19void xstrupper (char *str);
20void scnprintf (char *os, size_t len,
21 const char *str, ...);
22unsigned long int tdiff (struct timeval *old, struct timeval *new);
23char * ipv4_print (char *dest, struct in_addr in,
24 int padding);
25void * xrealloc (void *m_ptr, size_t newsize);
26char * xstrdup (char *str);
27void * xcalloc (int factor, size_t size);
28char * allocncat (char **to, char *from, size_t len);
29char * alloccat (char **to, char *from);
30char * file_load (char *pathname);
31
32#endif
33
diff --git a/other/ldistfp/src/ldistfp.c b/other/ldistfp/src/ldistfp.c
new file mode 100644
index 0000000..c1f1068
--- /dev/null
+++ b/other/ldistfp/src/ldistfp.c
@@ -0,0 +1,368 @@
1/* ldistfp - linux distribution fingerprinting
2 *
3 * by scut / teso
4 */
5
6#include <stdio.h>
7#include <stdlib.h>
8#include <string.h>
9#include "common.h"
10#include "network.h"
11
12#define AUTHORS "-sc/teso"
13#define VERSION "0.1.4"
14
15#define FP_URL "http://www.team-teso.net/data/ldistfp-auth-fingerprints"
16#define SUBMIT_URL "http://www.team-teso.net/ldistfp.php"
17
18typedef struct fingerprint {
19 char * distname;
20 char * distversion;
21 char * substring;
22 char * auth_version;
23 int exact;
24} fingerprint;
25
26fingerprint ** fp_list = NULL;
27char * fp_filename = "ldistfp-auth-fingerprints";
28char * fp_url = FP_URL;
29int fp_count = 0;
30
31int strictsure = 0;
32int machineoutput = 0;
33FILE * newfile = NULL; /* file to save new fingerprints to */
34
35
36void usage (char *prog);
37void host_print (char *host, char *bogus, fingerprint *fp);
38void fp_det (char *host, char *buf);
39void fp_list_read (char *filename);
40void fp_update (char *fname, char *url);
41
42
43void
44usage (char *prog)
45{
46 fprintf (stderr, "usage: %s [-rsmu] [-n <file>] [-U <url>] <host|ip>\n\n", prog);
47 fprintf (stderr, " -r rawmode, read from stdin in format [^ ] (buf$)\n");
48 fprintf (stderr, " -n <file> output new fingerprint information to this file\n");
49 fprintf (stderr, " -s only print host information if properly identified\n");
50 fprintf (stderr, " -m machine output\n");
51 fprintf (stderr, "\nupdate options\n");
52 fprintf (stderr, " -u update from " FP_URL "\n");
53 fprintf (stderr, " -U <url> update from given URL (http://<host>[:<port>]/<file>)\n\n");
54
55 exit (EXIT_FAILURE);
56}
57
58int
59main (int argc, char *argv[])
60{
61 int sock,
62 n;
63 int rawmode = 0;
64 int update_only = 0;
65 char c;
66 char * rbuf;
67 char * target;
68
69
70 fprintf (stderr, "ldistfp "VERSION" - remote identd fingerprinting tool. "AUTHORS"\n\n");
71
72 if (argc < 2)
73 usage (argv[0]);
74
75 while ((c = getopt (argc, argv, "rn:smf:uU:")) != EOF) {
76 switch (c) {
77 case 'r':
78 rawmode = 1;
79 break;
80 case 'n':
81 newfile = fopen (optarg, "a");
82 if (newfile == NULL) {
83 perror ("fopen");
84 exit (EXIT_FAILURE);
85 }
86 break;
87 case 's':
88 strictsure = 1;
89 break;
90 case 'm':
91 machineoutput = 1;
92 break;
93 case 'f':
94 fp_filename = optarg;
95 break;
96 case 'u':
97 update_only = 1;
98 break;
99 case 'U':
100 update_only = 1;
101 fp_url = optarg;
102 break;
103 default:
104 usage ("ldistfp");
105 break;
106 }
107 }
108
109 if (update_only == 1) {
110 fp_update (fp_filename, fp_url);
111 exit (EXIT_SUCCESS);
112 }
113
114 target = argv[argc - 1];
115 if (target[0] == '-')
116 usage ("ldistfp");
117
118 fp_list_read (fp_filename);
119 fprintf (stderr, "read %d fingerprints\n", fp_count);
120
121 if (rawmode) {
122 unsigned char tgt[200];
123 unsigned char ibuf[1024];
124
125 while (fgets (ibuf, sizeof (ibuf), stdin) != NULL) {
126 memset (tgt, '\0', sizeof (tgt));
127 sscanf (ibuf, "%199[^ :]", tgt);
128 tgt[sizeof (tgt) - 1] = '\0';
129 fp_det (tgt, ibuf);
130 }
131 } else {
132
133 sock = net_connect (NULL, target, 113, NULL, 0, 30);
134 if (sock == -1) {
135 perror ("net_connect");
136 exit (EXIT_FAILURE);
137 }
138
139 net_write (sock, "VERSION\n");
140 n = net_rlineta (sock, &rbuf, 15);
141 if (n < 0 && strictsure == 0) {
142 printf ("%s: failed to determine remote version\n", argv[1]);
143 } else {
144 fp_det (target, rbuf);
145 }
146
147 fprintf (stderr, "\n");
148 close (sock);
149 }
150
151 if (newfile != NULL)
152 fclose (newfile);
153
154
155 exit (EXIT_SUCCESS);
156}
157
158
159void
160fp_det (char *host, char *buf)
161{
162 int i;
163
164
165 for (i = 0 ; fp_list[i] != NULL ; ++i) {
166 if (strstr (buf, fp_list[i]->substring) != NULL) {
167
168 /* if it is an exact hit, then we print it and return,
169 * since there cannot be any other hit
170 */
171 if (fp_list[i]->exact != 0) {
172 host_print (host, "", fp_list[i]);
173 return;
174 } else if (strictsure == 0) {
175 host_print (host, "possible ", fp_list[i]);
176 }
177 }
178 }
179
180 if (machineoutput == 0 && newfile == NULL) {
181 printf ("\nunknown, if you know it write down the following line and submit it\n"
182 "at " SUBMIT_URL ", thanks.\n\n%s\n", buf);
183 return;
184 }
185
186 if (newfile == NULL)
187 return;
188
189 /* write new fingerprint to newfile */
190 fprintf (newfile, "%s: %s", host, buf);
191
192 return;
193}
194
195
196void
197host_print (char *host, char *bogus, fingerprint *fp)
198{
199 if (machineoutput == 1) {
200 printf ("%s/%s/%s/%s/%s\n",
201 host,
202 bogus,
203 fp->distname,
204 fp->distversion,
205 fp->auth_version);
206 } else {
207 printf ("%s: %s%s %s running %s\n",
208 host,
209 bogus,
210 fp->distname,
211 fp->distversion,
212 fp->auth_version);
213 }
214
215 return;
216}
217
218void
219fp_list_read (char *filename)
220{
221 int n,
222 fpc = 1;
223 FILE * fpl;
224 unsigned char * fpl_fg;
225
226 fpl = fopen (filename, "r");
227 if (fpl == NULL) {
228 perror ("finger print file");
229 exit (EXIT_FAILURE);
230 }
231
232 do {
233 fingerprint * new = xcalloc (1, sizeof (fingerprint));
234
235 fpc += 1;
236 fp_list = xrealloc (fp_list, fpc * sizeof (fingerprint *));
237 fp_list[fpc - 1] = NULL;
238 fp_list[fpc - 2] = new;
239
240 new->distname = xcalloc (1, 128);
241 new->distversion = xcalloc (1, 128);
242 new->substring = xcalloc (1, 128);
243 new->auth_version = xcalloc (1, 128);
244
245 /* format: "substring" "dist name" "dist version" "identd version" 0|1
246 */
247 do {
248 unsigned char buf[256];
249
250 n = 1;
251 fpl_fg = fgets (buf, sizeof (buf), fpl);
252 if (fpl_fg != NULL && strlen (buf) > 1 && buf[0] != '#') {
253 n = sscanf (buf, "\"%127[^\"]\"%*[\t ]\"%127[^\"]\"%*[\t ]"
254 "\"%127[^\"]\"%*[\t ]\"%127[^\"]\"%*[\t ]%d\n",
255 new->distname, new->distversion, new->substring,
256 new->auth_version, &new->exact);
257 }
258 } while (n != 5 && fpl_fg != NULL);
259
260 if (fpl_fg == NULL) {
261 free (new->distname);
262 free (new->distversion);
263 free (new->substring);
264 free (new->auth_version);
265 free (new);
266 fp_list[fpc - 2] = NULL;
267 } else {
268 fp_count++;
269 }
270 } while (fpl_fg != NULL);
271
272 fclose (fpl);
273}
274
275
276/* mini http/1.0 client, assume non-chunked transfer oh my.
277 * who invented chunking anyway ?
278 */
279void
280fp_update (char *fname, char *url)
281{
282 int fp_dataflag = 2;
283 int fp_updated_size = 0;
284 FILE * fp_updated;
285 char line_buf[2048];
286
287 int cs;
288 char host[128];
289 char hostfile[128];
290 unsigned short int port;
291
292
293 /* first open file, else we may not need to get the file if we can't
294 * open the file at all
295 */
296 fp_updated = fopen (fname, "w");
297 if (fp_updated == NULL) {
298 perror ("fp_update:fopen");
299 exit (EXIT_FAILURE);
300 }
301
302 memset (host, '\0', sizeof (host));
303 memset (hostfile, '\0', sizeof (hostfile));
304
305 if (sscanf (url, "http://%127[^/]%127s", host, hostfile) != 2) {
306 fprintf (stderr, "invalid URL: %s\n", url);
307 exit (EXIT_FAILURE);
308 }
309 host[sizeof (host) - 1] = '\0';
310 hostfile[sizeof (hostfile) - 1] = '\0';
311
312
313 /* find possible port suffix */
314 if (sscanf (host, "%*[^:]:%hu", &port) != 1)
315 port = 80;
316 if (strchr (host, ':') != NULL)
317 *(strchr (host, ':')) = '\0';
318
319 printf ("fetching:\n");
320 printf ("%s [%hu]: %s\n", host, port, hostfile);
321 cs = net_connect (NULL, host, port, NULL, 0, 15);
322 if (cs <= 0) {
323 perror ("fp_update:net_connect");
324 exit (EXIT_FAILURE);
325 }
326 printf ("GET [%s]\n", hostfile);
327
328 /* send request with special User-Agent (to track ldistfp versions
329 * that are used (and for possible ldistfp fingerprint file format
330 * updates, so that new format could be send for new clients, and
331 * old for old ones :-)
332 */
333 net_write (cs, "GET %s HTTP/1.1\n", hostfile);
334 net_write (cs, "User-Agent: ldistfp/"VERSION"\n");
335 net_write (cs, "Host: %s\n", host);
336 net_write (cs, "Connection: close\n");
337 net_write (cs, "\n");
338
339 do {
340 int n;
341
342 memset (line_buf, '\0', sizeof (line_buf));
343 n = net_rlinet (cs, line_buf, sizeof (line_buf), 15);
344 if (n <= 0)
345 break;
346
347 line_buf[sizeof (line_buf) - 1] = '\0';
348
349 if (fp_dataflag != 0) {
350 while (strlen (line_buf) > 0 &&
351 (line_buf[strlen (line_buf) - 1] == '\r' ||
352 line_buf[strlen (line_buf) - 1] == '\n'))
353 line_buf[strlen (line_buf) - 1] = '\0';
354 }
355
356 if (fp_dataflag == 2 && strstr (line_buf, " 200 OK") != NULL)
357 fp_dataflag = 1;
358 else if (fp_dataflag == 1 && strcmp (line_buf, "") == 0)
359 fp_dataflag = 0;
360 else if (fp_dataflag == 0 && n > 0) {
361 fp_updated_size += n;
362 fprintf (fp_updated, "%s", line_buf);
363 }
364 } while (1);
365
366 fclose (fp_updated);
367}
368
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
diff --git a/other/ldistfp/src/network.h b/other/ldistfp/src/network.h
new file mode 100644
index 0000000..253ecc9
--- /dev/null
+++ b/other/ldistfp/src/network.h
@@ -0,0 +1,287 @@
1/* scut's leet network library ;)
2 * 1999 (c) scut
3 *
4 * networking code
5 */
6
7#ifndef SCUT_NETWORK_H
8#define SCUT_NETWORK_H
9
10#include <sys/socket.h>
11#include <netinet/in.h>
12#include <stdio.h>
13
14#define NET_READTIMEOUT 180
15#define NET_CONNTIMEOUT 60
16#define NET_IDENTTIMEOUT 15
17
18
19typedef struct bound {
20 int bs; /* bound socket */
21 unsigned short port; /* port we bound to */
22 struct sockaddr bsa; /* bs_in */
23} bound;
24
25extern int net_readtimeout;
26extern int net_conntimeout;
27extern int net_identtimeout;
28
29
30/* net_socks_connect
31 *
32 * relays through an open socks 5 server (NO AUTH type)
33 * returns a socket descriptor which is already connected
34 */
35
36int net_socks_connect (char *socks, unsigned short int sport,
37 char *server, unsigned short int port, int sec);
38
39
40/* net_socks_put_s5info
41 *
42 * insert socks 5 compatible relay information into socket s5s,
43 * used to relay over more then just one socks server
44 */
45
46int net_socks_put_s5info (int s5s, char *server,
47 unsigned short int port, int sec);
48
49
50/* net_parseip
51 *
52 * read an ip in the format "1.1.1.1:299" or "blabla:481" into
53 * the char pointer *ip and into the port *port
54 *
55 * return 0 on failure
56 * return 1 on success
57 */
58
59int net_parseip (char *inp, char **ip, unsigned short int *port);
60
61
62/* net_getlocalip
63 *
64 * give back the main IP of the local machine
65 *
66 * return the local IP address as string on success
67 * return NULL on failure
68 */
69
70char *net_getlocalip (void);
71
72
73/* net_peeraddress
74 *
75 * return a pointer to a string representation of the remote IP address of
76 * the already connected socket `socket'
77 *
78 * return NULL on failure
79 * return string pointer on succes
80 */
81
82char * net_peeraddress (int socket);
83
84
85/* net_descriptify
86 *
87 * descriptify a socket `socket' ;)
88 *
89 * return -1 on failure
90 * return file descriptor on success
91 */
92
93FILE *net_descriptify (int socket);
94
95
96/* net_ident
97 *
98 * ident a connection identified by the host:port pairs on both sides,
99 * returning the ident in *ident
100 *
101 * return 1 on success
102 * return -1 on failure
103 */
104
105int net_ident (char **ident, struct sockaddr_in *locals, unsigned short int localport,
106 struct sockaddr_in *remotes, unsigned short int remoteport);
107
108
109/* net_accept
110 *
111 * accept a connection from socket s, and stores the connection
112 * into cs.
113 * wait a maximum amount of maxsec seconds for connections
114 * maxsec can also be zero (infinite wait, until connection)
115 *
116 * return 0 if no connection has been made within maxsec seconds
117 * return -1 if an error appears
118 * return the socket number if a connection has been made
119 */
120
121int net_accept (int s, struct sockaddr_in *cs, int maxsec);
122
123
124/* net_bind
125 *
126 * bind a socket to an ip:port on the local machine,
127 * `ip' can be either NULL (bind to all IP's on the host), or a pointer
128 * to a virtual host name, or a real IP, or "*" for any.
129 * `port' can be either 0 (ephemeral port), or any free port.
130 *
131 * return NULL on failure
132 * return pointer to bound structure on success
133 */
134
135bound *net_bind (char *ip, unsigned short int port);
136
137
138/* net_boundfree
139 *
140 * free the bound structure pointed to by `bf'
141 *
142 * return in any case
143 */
144
145void net_boundfree (bound *bf);
146
147
148/* net_resolve
149 *
150 * resolve a hostname pointed to by `host' into a s_addr return value
151 *
152 * return the correct formatted `s_addr' for this host on success
153 * return 0 on failure
154 */
155
156unsigned long int net_resolve (char *host);
157
158
159/* net_assignaddr
160 *
161 * assign an IP address and port to a socket
162 * sourceip can be an IP or hostname that is available on the local host,
163 * or NULL/"*" to let the kernel choose one, same applies to sourceport,
164 * it can either be zero (ephemeral port choosen by the kernel) or a
165 * valid port number
166 *
167 * return 1 on success
168 * return 0 on failure
169 */
170
171int net_assignaddr (int sd, char *sourceip, unsigned short int sourceport);
172
173
174/* net_connect
175 *
176 * connect to the given `server' and `port' with a max timeout of `sec'.
177 * initialize the sockaddr_in struct `cs' correctly (ipv4), accept any
178 * ip "123.123.123.123" or hostname "localhost", "www.yahoo.de" as hostname.
179 * create a new socket and return either -1 if failed or
180 * the connected socket if connection has been established within the
181 * timeout limit.
182 *
183 * the routine is still IPv4 biased :-/
184 * with `sourceip'/`sourceportÄ you MAY specify the source IP and source port
185 * to use for the connection, but you can set the ip or port to NULL/0,
186 * to choose the default IP and an ephemeral port. this was added later in
187 * this library, so please update your sources.
188 *
189 * return -1 on failure
190 * return socket if success
191 */
192
193int net_connect (struct sockaddr_in *cs, char *server, unsigned short int port, char *sourceip,
194 unsigned short int sourceport, int sec);
195
196
197/* net_rtimeout
198 *
199 * waits max `sec' seconds for fd to become readable
200 *
201 * return -1 on error (errno set)
202 * return 1 on readability
203 */
204
205int net_rtimeout (int fd, int sec);
206
207
208/* net_rbuf
209 *
210 * allocate memory and read socket data to `dst' until the connection
211 * gets closed.
212 *
213 * return n if success (n = number of bytes read)
214 * return -1 if failed
215 */
216
217long int net_rbuf (int fd, char **dst);
218#define NET_BSIZE 4096 /* blocksize for pre-allocation */
219
220
221/* net_rbuft
222 *
223 * read `dsize' bytes into `dst' from `fd', with timeout
224 *
225 * return 1 on success
226 * return -1 on failure
227 */
228int net_rbuft (int fd, char *dst, unsigned long int dsize);
229
230
231/* net_rlinet
232 *
233 * read a line from socket descriptor with timeout to buffer
234 * if sec = 0, then only a continuous stream of data is required, not
235 * an overall timeout.
236 *
237 * return -1 on timeout
238 * return 0 on connection close
239 * return length of readen line (including '\n')
240 *
241 * net_rlineta
242 * same as net_rlinet, but allocs the memory itself
243 */
244
245int net_rlineta (int fd, char **buf, int sec);
246int net_rlinet (int fd, char *buf, int bufsize, int sec);
247
248
249/* net_tline
250 *
251 * return length if string `buf' with a maximum length of `bufsize'
252 * contains '\n'
253 *
254 * return -1 if no '\n' in string
255 */
256
257int net_tline (char *buf, int bufsize);
258
259
260/* net_write
261 *
262 * print a formatted string to a socket, see syntax of printf
263 *
264 * return in any case
265 */
266
267void net_write (int fd, const char *str, ...);
268
269
270/* net_printip
271 *
272 * print an IP address stored in the struct in_addr pointed to by `ia' to a
273 * string `str' with a maximum length of `len'.
274 *
275 * return 0 on success
276 * return 1 on failure
277 *
278 * net_printipa behaves the same way, except it allocates memory and let
279 * `*str' point to the string
280 */
281
282int net_printip (struct in_addr *ia, char *str, size_t len);
283int net_printipa (struct in_addr *ia, char **str);
284
285
286#endif
287