summaryrefslogtreecommitdiff
path: root/other/grabbb/grabbb.c
diff options
context:
space:
mode:
Diffstat (limited to 'other/grabbb/grabbb.c')
-rw-r--r--other/grabbb/grabbb.c849
1 files changed, 849 insertions, 0 deletions
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