1 | #define _POSIX_C_SOURCE 199309 |
1 | #define _POSIX_C_SOURCE 200112 |
2 | #define _GNU_SOURCE 1 |
2 | #define _XOPEN_SOURCE 600 |
|
|
3 | #define _LARGEFILE64_SOURCE 1 |
3 | |
4 | |
|
|
5 | #ifndef __APPLE__ |
|
|
6 | # define IPV6 0 |
|
|
7 | #else |
4 | #define IPV6 1 // if you get compilation problems try to disable IPv6 |
8 | # define IPV6 1 // if you get compilation problems try to disable IPv6 |
|
|
9 | #endif |
5 | |
10 | |
6 | #include "EXTERN.h" |
11 | #include "EXTERN.h" |
7 | #include "perl.h" |
12 | #include "perl.h" |
8 | #include "XSUB.h" |
13 | #include "XSUB.h" |
9 | |
14 | |
… | |
… | |
358 | |
363 | |
359 | if (pipe (thr_recv) < 0) |
364 | if (pipe (thr_recv) < 0) |
360 | croak ("AnyEvent::FastPing: unable to create receive pipe"); |
365 | croak ("AnyEvent::FastPing: unable to create receive pipe"); |
361 | |
366 | |
362 | icmp4_fd = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP); |
367 | icmp4_fd = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP); |
|
|
368 | fcntl (icmp4_fd, F_SETFL, O_NONBLOCK); |
363 | #ifdef ICMP_FILTER |
369 | #ifdef ICMP_FILTER |
364 | { |
370 | { |
365 | struct icmp_filter oval; |
371 | struct icmp_filter oval; |
366 | oval.data = 0xffffffff & ~(1 << ICMP4_ECHO_REPLY); |
372 | oval.data = 0xffffffff & ~(1 << ICMP4_ECHO_REPLY); |
367 | setsockopt (icmp4_fd, SOL_RAW, ICMP_FILTER, &oval, sizeof oval); |
373 | setsockopt (icmp4_fd, SOL_RAW, ICMP_FILTER, &oval, sizeof oval); |
368 | } |
374 | } |
369 | #endif |
375 | #endif |
370 | |
376 | |
371 | #if IPV6 |
377 | #if IPV6 |
372 | icmp6_fd = socket (AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); |
378 | icmp6_fd = socket (AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); |
|
|
379 | fcntl (icmp6_fd, F_SETFL, O_NONBLOCK); |
373 | # ifdef ICMP6_FILTER |
380 | # ifdef ICMP6_FILTER |
374 | { |
381 | { |
375 | struct icmp6_filter oval; |
382 | struct icmp6_filter oval; |
376 | ICMP6_FILTER_SETBLOCKALL (&oval); |
383 | ICMP6_FILTER_SETBLOCKALL (&oval); |
377 | ICMP6_FILTER_SETPASS (ICMP6_ECHO_REPLY, &oval); |
384 | ICMP6_FILTER_SETPASS (ICMP6_ECHO_REPLY, &oval); |
… | |
… | |
548 | AV *res_av = av_len (cbs) < 0 ? 0 : (AV *)sv_2mortal ((SV *)newAV ()); |
555 | AV *res_av = av_len (cbs) < 0 ? 0 : (AV *)sv_2mortal ((SV *)newAV ()); |
549 | tstamp now = NOW (); |
556 | tstamp now = NOW (); |
550 | |
557 | |
551 | for (;;) |
558 | for (;;) |
552 | { |
559 | { |
553 | int len = recvfrom (icmp4_fd, buf, sizeof (buf), MSG_DONTWAIT | MSG_TRUNC, &sa, &sl); |
560 | int len = recvfrom (icmp4_fd, buf, sizeof (buf), MSG_TRUNC, (struct sockaddr *)&sa, &sl); |
554 | |
561 | |
555 | if (len <= HDR_SIZE_IP4) |
562 | if (len <= HDR_SIZE_IP4) |
556 | break; |
563 | break; |
557 | |
564 | |
558 | IP4HDR *iphdr = (IP4HDR *)buf; |
565 | IP4HDR *iphdr = (IP4HDR *)buf; |
… | |
… | |
597 | PKT pkt; |
604 | PKT pkt; |
598 | tstamp now = NOW (); |
605 | tstamp now = NOW (); |
599 | |
606 | |
600 | for (;;) |
607 | for (;;) |
601 | { |
608 | { |
602 | int len = recvfrom (icmp6_fd, &pkt, sizeof (pkt), MSG_DONTWAIT | MSG_TRUNC, &sa, &sl); |
609 | int len = recvfrom (icmp6_fd, &pkt, sizeof (pkt), MSG_TRUNC, (struct sockaddr *)&sa, &sl); |
603 | |
610 | |
604 | if (len != sizeof (PKT)) |
611 | if (len != sizeof (PKT)) |
605 | break; |
612 | break; |
606 | |
613 | |
607 | if (!res_av |
614 | if (!res_av |