summaryrefslogtreecommitdiff
path: root/other/grabbb
diff options
context:
space:
mode:
Diffstat (limited to 'other/grabbb')
-rw-r--r--other/grabbb/Makefile12
-rw-r--r--other/grabbb/README19
-rw-r--r--other/grabbb/grabbb.c849
3 files changed, 880 insertions, 0 deletions
diff --git a/other/grabbb/Makefile b/other/grabbb/Makefile
new file mode 100644
index 0000000..545ea2e
--- /dev/null
+++ b/other/grabbb/Makefile
@@ -0,0 +1,12 @@
1CFLAGS=-Wall
2CC=gcc
3OBJS=grabbb.o
4
5all: grabbb
6
7clean:
8 rm -f *.o grabbb
9
10arptool: $(OBJS)
11 $(CC) $(CFLAGS) -o grabbb $(OBJS)
12 strip grabbb
diff --git a/other/grabbb/README b/other/grabbb/README
new file mode 100644
index 0000000..64357bb
--- /dev/null
+++ b/other/grabbb/README
@@ -0,0 +1,19 @@
1grabbb
2readme file
3
4 1. description
5
6 grabbb is a very fast banner grabbing program, which will test an entire
7 range of ip addresses on a single or multiple ports, and if successful
8 it will capture the first line the remote daemon sends.
9
10 this can be useful for statistical purposes.
11
12 note this can be used for protocols such as ssh, ftp, smtp, nntp, ...
13 but not for things such as telnet, which is not as "simple" as you
14 may have thought.
15
16
17 have fun,
18 scut of teso
19
diff --git a/other/grabbb/grabbb.c b/other/grabbb/grabbb.c
new file mode 100644
index 0000000..ed4b3e8
--- /dev/null
+++ b/other/grabbb/grabbb.c
@@ -0,0 +1,849 @@
1/* grabbb - elite banner scanner
2 *
3 * by scut of teso (http://teso.scene.at/)
4 *
5 * nearly all of this code wouldn't have been possible without w. richard stevens
6 * excellent network coding book. if you are interested in network coding,
7 * there is no way around it. wherever you are now, you showed me how to aquire one
8 * of my best skills, and my programs are the result of your teaching abilities.
9 *
10 * oh yeah, special greetz for this one go to random, who will once be a great
11 * socket warrior, promised. :)
12 *
13 * compilation (successfully tested on any listed platform):
14 *
15 * OSF1 Tru64 Unix V4.0/V5.0 ...: cc -o grabbb grabbb.c
16 * Linux 2.x.x .................: gcc -o grabbb grabbb.c -Wall
17 * Free-, Open-, NetBSD, BSDI ..: gcc -o grabbb grabbb.c -Wall
18 * SunOS, Solaris ..............: cc -o grabbb grabbb.c -lsocket -lnsl
19 * generic .....................: cc -o grabbb grabbb.c
20 */
21
22
23#include <sys/types.h>
24#include <sys/ioctl.h>
25#include <sys/socket.h>
26#include <sys/time.h>
27#include <netinet/in.h>
28#include <arpa/inet.h>
29#include <netdb.h>
30#include <errno.h>
31#include <fcntl.h>
32#include <ctype.h>
33#include <stdarg.h>
34#include <stdio.h>
35#include <stdlib.h>
36#include <string.h>
37#include <unistd.h>
38
39
40#define VERSION "0.1.0"
41#define AUTHORS "scut of teso"
42
43#define NET_CONNTIMEOUT 30
44
45
46int net_conntimeout = NET_CONNTIMEOUT;
47int sb_timeout = 30;
48
49
50typedef struct {
51 struct timeval tv; /* first time the socket was used */
52 struct in_addr ip; /* ip we're connecting to */
53 int already;
54 int portcount;
55 unsigned short int *port; /* remote port */
56 int socket; /* phear */
57 int state;
58 int printed;
59#define ST_CONNECTING 1
60#define ST_CONNECTED 2
61#define ST_CONNECTME 3
62
63} sock_buck;
64
65
66/* for accessibility we go for a struct array, instead of a pointer array or a
67 * linked list. if we want to be even faster, we'd have to do fd_set
68 * multiplexing, which can be done with threads and jields in unportable code,
69 * sorry. mhh... (later) thinking about doing fd_set multiplexing with fork()
70 * and fpipe.
71 */
72
73#define GRABBB_OPEN_MAX 250 /* hehe, don't mess with the mighty fdset's limits */
74int open_max = GRABBB_OPEN_MAX;
75int sock_free = GRABBB_OPEN_MAX;
76sock_buck sockets[GRABBB_OPEN_MAX];
77
78/* in_addr structures needed for scanning
79 */
80struct in_addr ip_src,
81 ip_dst_s,
82 ip_dst_e,
83 ip_dst_cur;
84
85
86unsigned long int ip_list_count = 0;
87unsigned long int ip_list_step = 0;
88struct in_addr *ip_list = NULL;
89
90
91unsigned short int port = 21;
92unsigned long int stat_hostcount = 0;
93unsigned long int stat_hosts = 0;
94unsigned long int stat_conn = 0;
95unsigned long int hostcount = 0;
96int verbose = 0;
97int rangemode = 0;
98
99unsigned char *netmsg = NULL;
100unsigned long int netmsg_s = 0;
101int multiline = 0;
102
103unsigned short int *portrange = NULL;
104int portcount = 0;
105
106
107void usage (char *prg_name);
108unsigned short int *portrange_do (char *portlist);
109void sb_mainloop (void);
110void sb_check (sock_buck *sb_r, int sb_count, fd_set *readset,
111 fd_set *writeset);
112void sb_timecheck (sock_buck *sb);
113void sb_print (sock_buck *sb, unsigned char *buf);
114void sb_cfree (sock_buck *sb);
115void sb_free (sock_buck *sb);
116int sb_assign (int sb_count);
117sock_buck *sb_ip_new_g (struct in_addr *ip, unsigned short int *port);
118sock_buck *sb_ip_new (sock_buck *sb, struct in_addr *ip,
119 unsigned short int *port);
120sock_buck *sb_fd_findactive (sock_buck *sb_r, int sb_count, fd_set *fds);
121sock_buck *sb_getnew (sock_buck *sb_r, int sb_count);
122fd_set *sb_trigger (sock_buck *sb_r, int sb_count, int *max_fd, int wr);
123fd_set *sb_prepare (fd_set *fds, sock_buck *sb, int *max_fd, int wr);
124void sb_init (sock_buck *sb);
125char *net_getlocalip (void);
126/* char *net_peername (int socket); */
127unsigned long int net_resolve (char *host);
128int net_rtimeout (int fd, int sec);
129int net_printip (struct in_addr *ia, char *str);
130void *xcalloc (int factor, size_t size);
131void *xrealloc (void *mem, size_t newsize);
132
133int
134main (int argc, char **argv)
135{
136 int summary = 0;
137 char chr;
138 FILE *ip_file = NULL;
139 int ip_start_flag = 0,
140 ip_end_flag = 0;
141
142 if (argc < 4)
143 usage (argv[0]);
144
145 while ((chr = getopt (argc - 1, argv, "x:t:i:a:b:mvs")) != EOF) {
146 switch (chr) {
147 case 'x': open_max = atoi (optarg);
148 sock_free = open_max;
149 break;
150 case 't': sb_timeout = atoi (optarg);
151 break;
152 case 'i': ip_file = fopen (optarg, "r");
153 break;
154 case 'a': ip_dst_s.s_addr = net_resolve (optarg);
155 ip_start_flag = 1;
156 break;
157 case 'b': ip_dst_e.s_addr = net_resolve (optarg);
158 ip_end_flag = 1;
159 break;
160 case 'm': multiline = 1;
161 break;
162 case 'v': verbose = 1;
163 break;
164 case 's': summary = 1;
165 break;
166 default: break;
167 }
168 }
169
170 if (net_rtimeout (STDIN_FILENO, 1) == 1) {
171 unsigned char *fooptr;
172 int foolen = 1;
173
174 for (netmsg_s = 128 ; foolen != 0 ; netmsg_s += 128) {
175 netmsg = xrealloc (netmsg, netmsg_s);
176 fooptr = netmsg + netmsg_s - 128;
177 foolen = read (STDIN_FILENO, fooptr, 127);
178 if (foolen == -1) {
179 fprintf (stderr, "failed to read from stdin\n");
180 exit (EXIT_FAILURE);
181 }
182 netmsg_s -= (128 - foolen);
183 }
184 netmsg_s -= 128;
185 if (verbose)
186 printf ("printing to sockets (size = %li):\n%s\n", netmsg_s, netmsg);
187 }
188
189 /* sanity checking
190 */
191 if (ip_start_flag ^ ip_end_flag) {
192 printf ("you must supply either an iprange through using both options,\n"
193 "-a and -b, or you should supply an iprange file through -i.\n\n");
194 exit (EXIT_FAILURE);
195 }
196 if (ip_start_flag == 1 && ip_end_flag == 1 &&
197 (ip_dst_s.s_addr == 0 || ip_dst_e.s_addr == 0))
198 {
199 printf ("when using the range mode you should supply valid ip ranges, lamer\n\n");
200 exit (EXIT_FAILURE);
201 }
202 if (ip_start_flag == 1 && ip_end_flag == 1) {
203 rangemode = 1;
204 } else if (ip_file == NULL) {
205 printf ("supply a valid ip file if you don't use the range mode, lamer\n\n");
206 exit (EXIT_FAILURE);
207 } else {
208 char line[128];
209
210 memset (line, '\0', sizeof (line));
211 for (ip_list_count = 1 ;
212 fgets (line, sizeof (line) - 1, ip_file) != NULL ; )
213 {
214 while (strlen (line) && (line[strlen (line) - 1] == '\n' || line[strlen (line) - 1] == '\r'))
215 line[strlen (line) - 1] = '\0';
216
217 ip_list = xrealloc (ip_list, ip_list_count * sizeof (struct in_addr));
218 if (verbose) {
219 printf ("(%8li) adding %s\n", ip_list_count, line);
220 }
221
222 ip_list[ip_list_count - 1].s_addr = net_resolve (line);
223#ifdef DEBUG
224 printf ("ip_list[ip_list_count - 1].s_addr = %08x\n", ip_list[ip_list_count - 1].s_addr);
225#endif
226 if (ip_list[ip_list_count - 1].s_addr != 0)
227 ++ip_list_count;
228 memset (line, '\0', sizeof (line));
229 }
230
231 ip_list_count--;
232 rangemode = 0;
233 }
234
235 if (rangemode) {
236 hostcount = (ntohl (ip_dst_e.s_addr) - ntohl (ip_dst_s.s_addr)) + 1;
237 } else {
238 hostcount = ip_list_count;
239 }
240
241 if (hostcount < open_max) {
242 sock_free = open_max = hostcount;
243 if (verbose)
244 printf ("truncated maximum number of open sockets to %d\n", open_max);
245 }
246
247 portrange = portrange_do (argv[optind]);
248 if (verbose)
249 printf ("%d ports to scan per host, thats %lu connects\n", portcount, portcount * hostcount);
250
251 if (rangemode)
252 ip_dst_cur.s_addr = ip_dst_s.s_addr;
253
254 sb_mainloop ();
255
256 if (summary) {
257 printf ("finished scanning %lu hosts.\ngot %lu response%s from %lu host%s.\n",
258 stat_hosts, stat_conn, (stat_conn > 1) ? "s" : "", stat_hostcount,
259 (stat_hostcount > 1) ? "s" : "");
260 }
261
262 exit (EXIT_SUCCESS);
263}
264
265
266
267unsigned short int *
268portrange_do (char *portlist)
269{
270 char *parse_ptr = portlist;
271 unsigned short int *new = NULL;
272
273 for (portcount = 1 ;
274 (new = realloc (new, (portcount + 1) * sizeof (unsigned short int))) != NULL ;
275 ++portcount)
276 {
277 unsigned short int port = 0;
278
279 new[portcount - 1] = new[portcount] = 0;
280
281 while (isdigit (*parse_ptr)) {
282 port *= 10;
283 port += (*parse_ptr - '0');
284 parse_ptr++;
285 }
286
287 if (*parse_ptr == ':') {
288 new[portcount - 1] = port;
289 parse_ptr++;
290 } else if (*parse_ptr == '\0') {
291 new[portcount - 1] = port;
292 return (new);
293 } else {
294 printf ("illegal portlist supplied, check your eyes, lamer\n\n");
295 exit (EXIT_FAILURE);
296 }
297 }
298
299 printf ("generic error on portlist parsing\n\n");
300
301 exit (EXIT_FAILURE);
302}
303
304
305void
306usage (char *prg_name)
307{
308 printf ("grabbb "VERSION" by "AUTHORS"\n\n"
309 "usage: %s [options] <port>[:port2[:port3[...]]]\n\n"
310 "__options\n"
311 "\t-x <maxsock> maximum number of sockets to use (default 250)\n"
312 "\t-t <seconds> connection timeout\n"
313 "\t-i <file> file to get ip's from (ip's, not names)\n"
314 "\t-a <startip> range scanning (startip)\n"
315 "\t-b <endip> range scanning (endip)\n"
316 "\t-m multiline mode (grab not just the first line)\n"
317 "\t-v be more verbose\n"
318 "\t-s print summary information after scan\n\n"
319 "you can also pipe something to the program, which will be printed to any\n"
320 "successful connection the program experiences\n\n", prg_name);
321
322 exit (EXIT_SUCCESS);
323}
324
325
326void
327sb_mainloop (void)
328{
329 int n;
330 fd_set *fds_r, *fds_w;
331 int max_fd;
332 struct timeval tv = { 2, 0 }; /* 2 seconds timeout */
333 int eoscan;
334
335 while (1) {
336 eoscan = sb_assign (open_max);
337#ifdef DEBUG
338 printf ("eoscan = %d -- sock_free = %d -- open_max = %d\n", eoscan, sock_free, open_max);
339#endif
340 if (eoscan == -1 && sock_free == open_max) {
341 return;
342 }
343
344 fds_r = fds_w = NULL;
345 fds_r = sb_trigger (sockets, open_max, &max_fd, 0);
346 fds_w = sb_trigger (sockets, open_max, &max_fd, 1);
347
348#ifdef DEBUG
349 printf ("fds_r = %08x -- fds_w = %08x -- eoscan = %d\n", fds_r, fds_w, eoscan);
350#endif
351 if (fds_r == NULL && fds_w == NULL && eoscan == -1)
352 return;
353 n = select (max_fd, fds_r, fds_w, NULL, &tv);
354#ifdef DEBUG
355 printf ("select() = %d\n", n);
356#endif
357 if (n == -1) {
358 perror ("select failed");
359 exit (EXIT_FAILURE);
360 }
361
362 sb_check (sockets, open_max, fds_r, fds_w);
363
364 free (fds_r);
365 free (fds_w);
366 }
367
368}
369
370
371/* please ignore the bad style exposed here
372 */
373
374void
375sb_check (sock_buck *sb_r, int sb_count, fd_set *readset, fd_set *writeset)
376{
377 int i,
378 error,
379 len = sizeof (error);
380 sock_buck *sb;
381
382 for (i = 0 ; i < sb_count ; ++i) {
383 sb = &(sb_r[i]);
384 if (sb->socket != 0 && sb->state == ST_CONNECTING) {
385 if (FD_ISSET (sb->socket, readset) || FD_ISSET (sb->socket, writeset)) {
386 if (FD_ISSET (sb->socket, readset) && FD_ISSET (sb->socket, writeset)) {
387 if (getsockopt (sb->socket, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
388 sb_cfree (sb);
389 } else if (error == 0) {
390 /* we experienced a successful connection
391 */
392 sb->state = ST_CONNECTED;
393 if (sb->already == 0)
394 stat_hostcount++;
395 sb->already = 1;
396 sb->printed = 0;
397 if (netmsg != NULL)
398 write (sb->socket, netmsg, netmsg_s);
399 } else {
400 sb_cfree (sb);
401 }
402 } else if (FD_ISSET (sb->socket, readset) == 0 && FD_ISSET (sb->socket, writeset) != 0) {
403 sb->state = ST_CONNECTED;
404 if (sb->already == 0)
405 stat_hostcount++;
406 sb->already = 1;
407 sb->printed = 0;
408 if (netmsg != NULL)
409 write (sb->socket, netmsg, netmsg_s);
410 }
411 }
412 } else if (sb->socket != 0 && sb->state == ST_CONNECTED && FD_ISSET (sb->socket, readset)) {
413 int n;
414 unsigned char buf[256];
415
416 memset (buf, '\0', sizeof (buf));
417 n = read (sb->socket, buf, sizeof (buf) - 1);
418 if (n <= 0) {
419 sb_cfree (sb);
420 } else {
421 sb_print (sb, buf);
422 }
423 }
424
425 sb_timecheck (sb);
426 }
427
428 return;
429}
430
431
432void
433sb_cfree (sock_buck *sb)
434{
435 sb->portcount++;
436 if (sb->portcount >= portcount) {
437 sb_free (sb);
438 } else {
439 if (sb->socket != 0)
440 close (sb->socket);
441 sb->socket = 0;
442 sb->state = ST_CONNECTME;
443 }
444
445 return;
446}
447
448
449void
450sb_timecheck (sock_buck *sb)
451{
452 unsigned long seconds,
453 microseconds;
454 struct timeval tv_cur;
455
456 gettimeofday (&tv_cur, NULL);
457
458 seconds = tv_cur.tv_sec - sb->tv.tv_sec;
459 if (tv_cur.tv_usec >= sb->tv.tv_usec) {
460 microseconds = tv_cur.tv_usec - sb->tv.tv_usec;
461 } else {
462 microseconds = sb->tv.tv_usec + tv_cur.tv_usec;
463 seconds--; /* seconds must be at least one, sapienta sat */
464 }
465
466 if (microseconds >= 500000)
467 seconds++;
468
469 if (seconds >= sb_timeout) {
470 if (sb->state == ST_CONNECTED) {
471 sb_print (sb, NULL);
472 }
473 sb_cfree (sb);
474 }
475
476 return;
477}
478
479
480void
481sb_print (sock_buck *sb, unsigned char *buf)
482{
483 unsigned char *foo;
484 char ip[64];
485
486 net_printip (&sb->ip, ip);
487
488 if (buf != NULL && multiline == 0 && strlen ((const char *) buf) > 0) {
489 for (foo = buf ;
490 ((unsigned long)((unsigned long)foo -
491 (unsigned long)buf) < strlen ((const char *) buf)) &&
492 *foo != '\r' && *foo != '\n' &&
493 *foo != '\x00'; ++foo)
494 ;
495 *foo = '\x00';
496 }
497
498 if (sb->printed == 0) {
499 sb->printed = 1;
500 stat_conn++;
501 if (buf != NULL) {
502 printf ("%s:%hu:%c%s%s", ip, sb->port[sb->portcount],
503 (multiline == 0) ? ' ' : '\n', buf,
504 (multiline == 0) ? "\n" : "");
505 } else {
506 printf ("%s:%hu:\n", ip, sb->port[sb->portcount]);
507 }
508 } else if (buf != NULL) {
509 printf ("%s", buf);
510 }
511
512
513 return;
514}
515
516
517void
518sb_free (sock_buck *sb)
519{
520 if (sb->socket != 0)
521 close (sb->socket);
522
523 sb_init (sb);
524
525 sock_free++;
526
527 return;
528}
529
530
531int
532sb_assign (int sb_count)
533{
534 int cnx = 0; /* number of connects issued */
535 sock_buck *sb;
536 int i;
537
538
539 for (i = 0 ; i < sb_count ; ++i) {
540 sb = &(sockets[i]);
541
542 if (sb->state == ST_CONNECTME) {
543 sb_ip_new (sb, &sb->ip, portrange);
544 }
545 }
546
547 while (sock_free > 0) {
548 sock_buck *sb;
549
550 if (ip_list_count > 0) {
551 if (ip_list_step >= ip_list_count)
552 return (-1);
553
554 sb = sb_ip_new_g (&(ip_list[ip_list_step]), portrange);
555 ip_list_step++;
556 } else {
557 if (ntohl (ip_dst_cur.s_addr) > ntohl (ip_dst_e.s_addr))
558 return (-1);
559
560 sb = sb_ip_new_g (&ip_dst_cur, portrange);
561 ip_dst_cur.s_addr = ntohl (ntohl (ip_dst_cur.s_addr) + 1);
562 }
563
564 stat_hosts++;
565 cnx++;
566 --sock_free;
567 }
568
569 return (cnx);
570}
571
572
573sock_buck *
574sb_ip_new_g (struct in_addr *ip, unsigned short int *port)
575{
576 sock_buck *new;
577
578 new = sb_getnew (sockets, open_max);
579 sb_init (new);
580 new->port = port;
581 new->portcount = 0;
582
583 return (sb_ip_new (new, ip, port));
584}
585
586
587sock_buck *
588sb_ip_new (sock_buck *sb, struct in_addr *ip, unsigned short int *port)
589{
590 int n;
591 sock_buck *new = sb;
592 struct sockaddr_in sa;
593
594 if (new == NULL)
595 return (NULL);
596
597 if (&new->ip != ip)
598 memcpy (&new->ip, ip, sizeof (struct in_addr));
599 memset (&sa, '\0', sizeof (struct sockaddr_in));
600 sa.sin_family = AF_INET;
601 sa.sin_port = htons (new->port[new->portcount]);
602
603 new->socket = socket (sa.sin_family, SOCK_STREAM, 0);
604
605 sa.sin_addr.s_addr = ip->s_addr;
606
607 /* fear this lame socket coding style =) (didn't learned this from stevens
608 * though :)
609 */
610 fcntl (new->socket, F_SETFL, (fcntl (new->socket, F_GETFL, 0) | O_NONBLOCK));
611
612 n = connect (new->socket, (struct sockaddr *) &sa, sizeof (struct sockaddr_in));
613 gettimeofday (&new->tv, NULL);
614 if (n < 0 && errno != EINPROGRESS) {
615 sb_cfree (new);
616 return (new);
617 } else if (n == 0) {
618 new->state = ST_CONNECTED;
619 if (new->already == 0)
620 stat_hostcount++;
621 new->already = 1;
622 return (new);
623 }
624
625 new->state = ST_CONNECTING;
626
627 return (new);
628}
629
630
631sock_buck *
632sb_fd_findactive (sock_buck *sb_r, int sb_count, fd_set *fds)
633{
634 int i;
635
636 for (i = 0 ; i < sb_count ; ++i) {
637 int socket = sb_r[i].socket;
638
639 if (socket != 0 && FD_ISSET (socket, fds) != 0)
640 return (&sb_r[i]);
641 }
642
643 return (NULL);
644}
645
646
647sock_buck *
648sb_getnew (sock_buck *sb_r, int sb_count)
649{
650 int i;
651
652 for (i = 0 ; i < sb_count ; ++i) {
653 if (sb_r[i].state == 0)
654 return (&sb_r[i]);
655 }
656
657 return (NULL);
658}
659
660
661fd_set *
662sb_trigger (sock_buck *sb_r, int sb_count, int *max_fd, int wr)
663{
664 int i;
665 fd_set *fds = NULL;
666
667 for (i = 0 ; i < sb_count ; ++i) {
668 fds = sb_prepare (fds, &sb_r[i], max_fd, wr);
669 }
670
671 *max_fd = *max_fd + 1;
672
673 return (fds);
674}
675
676
677fd_set *
678sb_prepare (fd_set *fds, sock_buck *sb, int *max_fd, int wr)
679{
680 /* if socket is empty or socket is already part of fd_set,
681 * which means we fucked the structs somehow, then skip
682 */
683 if (sb->socket == 0)
684 return (fds);
685
686 if (sb->state == ST_CONNECTED && wr == 1)
687 return (fds);
688
689 if (fds == NULL) {
690 fds = xcalloc (1, sizeof (fd_set));
691 FD_ZERO (fds);
692 *max_fd = 0;
693 }
694
695 if (FD_ISSET (sb->socket, fds) != 0)
696 return (fds);
697
698 FD_SET (sb->socket, fds);
699 if (sb->socket > *max_fd)
700 *max_fd = sb->socket;
701
702 return (fds);
703}
704
705
706void
707sb_init (sock_buck *sb)
708{
709 memset (&sb->ip, '\0', sizeof (struct in_addr));
710 sb->port = NULL;
711 sb->socket = 0;
712 sb->state = 0;
713 sb->already = 0;
714 sb->printed = 0;
715
716 return;
717}
718
719
720char *
721net_getlocalip (void)
722{
723 struct sockaddr_in pf;
724 char name[255];
725
726 memset (name, '\0', sizeof (name));
727
728 if (gethostname (name, sizeof (name) - 1) == -1) {
729 return (NULL);
730 }
731
732 pf.sin_addr.s_addr = net_resolve (name);
733
734 return (strdup (inet_ntoa (pf.sin_addr)));;
735}
736
737
738unsigned long int
739net_resolve (char *host)
740{
741 long i;
742 struct hostent *he;
743
744 i = inet_addr (host);
745 if (i == -1) {
746 he = gethostbyname (host);
747 if (he == NULL) {
748 return (0);
749 } else {
750 return (*(unsigned long *) he->h_addr);
751 }
752 }
753 return (i);
754}
755
756
757int
758net_rtimeout (int fd, int sec)
759{
760 fd_set rset;
761 struct timeval tv;
762 int n, error, flags;
763
764 error = 0;
765 flags = fcntl(fd, F_GETFL, 0);
766 n = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
767 if (n == -1)
768 return (-1);
769
770 FD_ZERO(&rset);
771 FD_SET(fd, &rset);
772 tv.tv_sec = sec;
773 tv.tv_usec = 0;
774
775 /* now we wait until more data is received then the tcp low level watermark,
776 * which should be setted to 1 in this case (1 is default)
777 */
778
779 n = select(fd + 1, &rset, NULL, NULL, &tv);
780 if (n == 0) {
781 n = fcntl(fd, F_SETFL, flags);
782 if (n == -1)
783 return (-1);
784 errno = ETIMEDOUT;
785 return (-1);
786 }
787 if (n == -1) {
788 return (-1);
789 }
790 /* socket readable ? */
791 if (FD_ISSET(fd, &rset)) {
792 n = fcntl(fd, F_SETFL, flags);
793 if (n == -1)
794 return (-1);
795 return (1);
796 } else {
797 n = fcntl(fd, F_SETFL, flags);
798 if (n == -1)
799 return (-1);
800 errno = ETIMEDOUT;
801 return (-1);
802 }
803}
804
805
806int
807net_printip (struct in_addr *ia, char *str)
808{
809 unsigned char *ipp;
810
811 ipp = (unsigned char *) &ia->s_addr;
812 sprintf (str, "%d.%d.%d.%d", ipp[0], ipp[1], ipp[2], ipp[3]);
813
814 return (0);
815}
816
817
818void *
819xcalloc (int factor, size_t size)
820{
821 void *bla;
822
823 bla = calloc (factor, size);
824
825 if (bla == NULL) {
826 fprintf (stderr, "no memory left\n");
827 exit (EXIT_FAILURE);
828 }
829
830 return (bla);
831}
832
833
834void *
835xrealloc (void *mem, size_t newsize)
836{
837 void *bla;
838
839 bla = realloc (mem, newsize);
840
841 if (bla == NULL) {
842 fprintf (stderr, "no memory left\n");
843 exit (EXIT_FAILURE);
844 }
845
846 return (bla);
847}
848
849