ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent-FastPing/FastPing.xs
(Generate patch)

Comparing AnyEvent-FastPing/FastPing.xs (file contents):
Revision 1.4 by root, Sun Mar 29 20:07:03 2009 UTC vs.
Revision 1.5 by root, Fri Jul 3 09:26:19 2009 UTC

1#define _POSIX_C_SOURCE 200112 1#if defined(__linux)
2#define _XOPEN_SOURCE 600 2# define ENABLE_IPV6 1 // if you get compilation problems try to disable IPv6
3#define _LARGEFILE64_SOURCE 1
4
5#ifdef __APPLE__
6# define IPV6 0
7#else 3#else
8# define IPV6 1 // if you get compilation problems try to disable IPv6 4# define ENABLE_IPV6 0
9#endif 5#endif
10 6
11#include "EXTERN.h" 7#include "EXTERN.h"
12#include "perl.h" 8#include "perl.h"
13#include "XSUB.h" 9#include "XSUB.h"
34#include <arpa/inet.h> 30#include <arpa/inet.h>
35 31
36#ifdef __linux 32#ifdef __linux
37# include <linux/icmp.h> 33# include <linux/icmp.h>
38#endif 34#endif
39#if IPV6 35#if ENABLE_IPV6
40# include <netinet/icmp6.h> 36# include <netinet/icmp6.h>
41#endif 37#endif
42 38
43#define ICMP4_ECHO 8 39#define ICMP4_ECHO 8
44#define ICMP4_ECHO_REPLY 0 40#define ICMP4_ECHO_REPLY 0
55 51
56typedef uint8_t addr_t[16]; 52typedef uint8_t addr_t[16];
57 53
58typedef double tstamp; 54typedef double tstamp;
59 55
60tstamp 56static tstamp
61NOW () 57NOW (void)
62{ 58{
63 struct timeval tv; 59 struct timeval tv;
64 gettimeofday (&tv, 0); 60 gettimeofday (&tv, 0);
65 return tv.tv_sec + tv.tv_usec * 0.000001; 61 return tv.tv_sec + tv.tv_usec * 0.000001;
66} 62}
166static void * 162static void *
167ping_proc (void *unused) 163ping_proc (void *unused)
168{ 164{
169 PKT pkt; 165 PKT pkt;
170 struct sockaddr_in sa4; 166 struct sockaddr_in sa4;
171#if IPV6 167#if ENABLE_IPV6
172 struct sockaddr_in6 sa6; 168 struct sockaddr_in6 sa6;
173#endif 169#endif
174 170
175 memset (&pkt, 0, sizeof (pkt)); 171 memset (&pkt, 0, sizeof (pkt));
176 172
177 memset (&sa4, 0, sizeof (sa4)); 173 memset (&sa4, 0, sizeof (sa4));
178 sa4.sin_family = AF_INET; 174 sa4.sin_family = AF_INET;
179 sa4.sin_port = 0; 175 sa4.sin_port = 0;
180#if IPV6 176#if ENABLE_IPV6
181 memset (&sa6, 0, sizeof (sa6)); 177 memset (&sa6, 0, sizeof (sa6));
182 sa6.sin6_family = AF_INET6; 178 sa6.sin6_family = AF_INET6;
183 sa6.sin6_port = 0; 179 sa6.sin6_port = 0;
184#endif 180#endif
185 181
260 if (sendto (icmp4_fd, &pkt, sizeof (pkt), 0, (struct sockaddr *)&sa4, sizeof (sa4)) > 0) 256 if (sendto (icmp4_fd, &pkt, sizeof (pkt), 0, (struct sockaddr *)&sa4, sizeof (sa4)) > 0)
261 errno = 0; 257 errno = 0;
262 } 258 }
263 else 259 else
264 { 260 {
265#if IPV6 261#if ENABLE_IPV6
266 pkt.type = ICMP6_ECHO; 262 pkt.type = ICMP6_ECHO;
267 263
268 memcpy (&sa6.sin6_addr, 264 memcpy (&sa6.sin6_addr,
269 sizeof (addr_t) - sizeof (sa6.sin6_addr) + (char *)&range->lo, 265 sizeof (addr_t) - sizeof (sa6.sin6_addr) + (char *)&range->lo,
270 sizeof (sa6.sin6_addr)); 266 sizeof (sa6.sin6_addr));
372 oval.data = 0xffffffff & ~(1 << ICMP4_ECHO_REPLY); 368 oval.data = 0xffffffff & ~(1 << ICMP4_ECHO_REPLY);
373 setsockopt (icmp4_fd, SOL_RAW, ICMP_FILTER, &oval, sizeof oval); 369 setsockopt (icmp4_fd, SOL_RAW, ICMP_FILTER, &oval, sizeof oval);
374 } 370 }
375#endif 371#endif
376 372
377#if IPV6 373#if ENABLE_IPV6
378 icmp6_fd = socket (AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); 374 icmp6_fd = socket (AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
379 fcntl (icmp6_fd, F_SETFL, O_NONBLOCK); 375 fcntl (icmp6_fd, F_SETFL, O_NONBLOCK);
380# ifdef ICMP6_FILTER 376# ifdef ICMP6_FILTER
381 { 377 {
382 struct icmp6_filter oval; 378 struct icmp6_filter oval;
471 memset (&r->hi, 0, sizeof (addr_t)); 467 memset (&r->hi, 0, sizeof (addr_t));
472 468
473 if (SvPOKp (lo) && SvPOKp (hi)) 469 if (SvPOKp (lo) && SvPOKp (hi))
474 { 470 {
475 if (SvCUR (lo) != SvCUR (hi)) 471 if (SvCUR (lo) != SvCUR (hi))
476 croak ("addresses in range must be of the same size (either 4 or 16 bytes)"); 472 croak ("all addresses in range must be of the same size (either 4 or 16 bytes)");
477 473
478 if (SvCUR (lo) == 4) 474 if (SvCUR (lo) == 4)
479 { 475 {
480 r->family = AF_INET; 476 r->family = AF_INET;
481 memcpy (sizeof (addr_t) - 4 + (char *)&r->lo, SvPVX (lo), 4); 477 memcpy (sizeof (addr_t) - 4 + (char *)&r->lo, SvPVX (lo), 4);
482 memcpy (sizeof (addr_t) - 4 + (char *)&r->hi, SvPVX (hi), 4); 478 memcpy (sizeof (addr_t) - 4 + (char *)&r->hi, SvPVX (hi), 4);
483 } 479 }
484 else if (SvCUR (lo) == 16) 480 else if (SvCUR (lo) == 16)
485 { 481 {
486#if IPV6 482#if ENABLE_IPV6
487 r->family = AF_INET6; 483 r->family = AF_INET6;
488 memcpy (&r->lo, SvPVX (lo), sizeof (addr_t)); 484 memcpy (&r->lo, SvPVX (lo), sizeof (addr_t));
489 memcpy (&r->hi, SvPVX (hi), sizeof (addr_t)); 485 memcpy (&r->hi, SvPVX (hi), sizeof (addr_t));
490#else 486#else
491 croak ("IPv6 not supported in this configuration"); 487 croak ("IPv6 not supported in this configuration");
492#endif 488#endif
493 } 489 }
494 else 490 else
495 croak ("addresses in range must be either 4 (IPv4) or 16 (IPV6) bytes in length"); 491 croak ("addresses in range must be either 4 (IPv4) or 16 (IPv6) bytes in length");
496 } 492 }
497 else if (SvIOK (lo) && SvIOK (hi)) 493 else if (SvIOK (lo) && SvIOK (hi))
498 { 494 {
499 r->family = AF_INET; 495 r->family = AF_INET;
500 496

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines