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

Comparing AnyEvent-FastPing/FPing.xs (file contents):
Revision 1.5 by root, Fri May 4 15:33:56 2007 UTC vs.
Revision 1.7 by root, Fri May 4 16:17:25 2007 UTC

103 uint8_t dst[16]; 103 uint8_t dst[16];
104} IP6HDR; 104} IP6HDR;
105 105
106#define MAGIC 0xca4c 106#define MAGIC 0xca4c
107 107
108static uint16_t magic;
109
108typedef struct { 110typedef struct {
109 uint8_t type, code; 111 uint8_t type, code;
110 uint16_t cksum; 112 uint16_t cksum;
111 uint16_t id, seq; 113 uint16_t id, seq;
112 uint32_t payload; 114 uint32_t payload;
190 } 192 }
191 193
192 //TODO: bind to source address 194 //TODO: bind to source address
193 195
194 pkt.code = 0; 196 pkt.code = 0;
195 pkt.id = (uint16_t)MAGIC; 197 pkt.id = (uint16_t)magic;
196 pkt.seq = (uint16_t)~MAGIC; 198 pkt.seq = (uint16_t)~magic;
197 pkt.payload = req->payload; 199 pkt.payload = req->payload;
198 200
199 tstamp now = NOW (); 201 tstamp now = NOW ();
200 tstamp next = now; 202 tstamp next = now;
201 203
405BOOT: 407BOOT:
406{ 408{
407 HV *stash = gv_stashpv ("Net::FPing", 1); 409 HV *stash = gv_stashpv ("Net::FPing", 1);
408 410
409 cbs = get_av ("Net::FPing::CB", 1); 411 cbs = get_av ("Net::FPing::CB", 1);
412 magic = getpid () ^ MAGIC;
410 413
411 boot (); 414 boot ();
412 415
413 newCONSTSUB (stash, "ipv4_supported", newSViv (icmp4_fd >= 0)); 416 newCONSTSUB (stash, "ipv4_supported", newSViv (icmp4_fd >= 0));
414 newCONSTSUB (stash, "ipv6_supported", newSViv (icmp6_fd >= 0)); 417 newCONSTSUB (stash, "ipv6_supported", newSViv (icmp6_fd >= 0));
540 CODE: 543 CODE:
541{ 544{
542 char buf [512]; 545 char buf [512];
543 struct sockaddr_in sa; 546 struct sockaddr_in sa;
544 socklen_t sl = sizeof (sa); 547 socklen_t sl = sizeof (sa);
545 AV *res_av = newAV (); 548 AV *res_av = av_len (cbs) < 0 ? 0 : (AV *)sv_2mortal ((SV *)newAV ());
546 SV *res_rv = sv_2mortal (newRV_noinc ((SV *)res_av));
547 tstamp now = NOW (); 549 tstamp now = NOW ();
548 550
549 for (;;) 551 for (;;)
550 { 552 {
551 int len = recvfrom (icmp4_fd, buf, sizeof (buf), MSG_DONTWAIT | MSG_TRUNC, &sa, &sl); 553 int len = recvfrom (icmp4_fd, buf, sizeof (buf), MSG_DONTWAIT | MSG_TRUNC, &sa, &sl);
557 559
558 int hdrlen = (iphdr->version_ihl & 15) * 4; 560 int hdrlen = (iphdr->version_ihl & 15) * 4;
559 int totlen = ntohs (iphdr->tot_len); 561 int totlen = ntohs (iphdr->tot_len);
560 562
561 // packet corrupt? 563 // packet corrupt?
564 if (!res_av
562 if (totlen > len 565 || totlen > len
563 || iphdr->protocol != IPPROTO_ICMP 566 || iphdr->protocol != IPPROTO_ICMP
564 || hdrlen < HDR_SIZE_IP4 || hdrlen + sizeof (PKT) != totlen) 567 || hdrlen < HDR_SIZE_IP4 || hdrlen + sizeof (PKT) != totlen)
565 continue; 568 continue;
566 569
567 PKT *pkt = (PKT *)(buf + hdrlen); 570 PKT *pkt = (PKT *)(buf + hdrlen);
568 571
569 if (pkt->type != ICMP4_ECHO_REPLY 572 if (pkt->type != ICMP4_ECHO_REPLY
570 || pkt->id != (uint16_t) MAGIC 573 || pkt->id != (uint16_t) magic
571 || pkt->seq != (uint16_t)~MAGIC 574 || pkt->seq != (uint16_t)~magic
572 || !isnormal (pkt->stamp)) 575 || !isnormal (pkt->stamp))
573 continue; 576 continue;
574 577
575 AV *av = newAV (); 578 AV *av = newAV ();
576 av_push (av, newSVpvn ((char *)&sa.sin_addr, 4)); 579 av_push (av, newSVpvn ((char *)&sa.sin_addr, 4));
578 av_push (av, newSVuv (pkt->payload)); 581 av_push (av, newSVuv (pkt->payload));
579 582
580 av_push (res_av, newRV_noinc ((SV *)av)); 583 av_push (res_av, newRV_noinc ((SV *)av));
581 } 584 }
582 585
586 if (res_av)
583 feed_reply (res_av); 587 feed_reply (res_av);
584} 588}
585 589
586void 590void
587_recv_icmp6 (...) 591_recv_icmp6 (...)
588 CODE: 592 CODE:
589{ 593{
590 struct sockaddr_in6 sa; 594 struct sockaddr_in6 sa;
591 socklen_t sl = sizeof (sa); 595 socklen_t sl = sizeof (sa);
592 AV *res_av = (AV *)sv_2mortal ((SV *)newAV ()); 596 AV *res_av = av_len (cbs) < 0 ? 0 : (AV *)sv_2mortal ((SV *)newAV ());
593 PKT pkt; 597 PKT pkt;
594 tstamp now = NOW (); 598 tstamp now = NOW ();
595 599
596 for (;;) 600 for (;;)
597 { 601 {
598 int len = recvfrom (icmp6_fd, &pkt, sizeof (pkt), MSG_DONTWAIT | MSG_TRUNC, &sa, &sl); 602 int len = recvfrom (icmp6_fd, &pkt, sizeof (pkt), MSG_DONTWAIT | MSG_TRUNC, &sa, &sl);
599 603
600 if (len != sizeof (PKT)) 604 if (len != sizeof (PKT))
601 break; 605 break;
602 606
607 if (!res_av
603 if (pkt.type != ICMP6_ECHO_REPLY 608 || pkt.type != ICMP6_ECHO_REPLY
604 || pkt.id != (uint16_t) MAGIC 609 || pkt.id != (uint16_t) magic
605 || pkt.seq != (uint16_t)~MAGIC 610 || pkt.seq != (uint16_t)~magic
606 || !isnormal (pkt.stamp)) 611 || !isnormal (pkt.stamp))
607 continue; 612 continue;
608 613
609 AV *av = newAV (); 614 AV *av = newAV ();
610 av_push (av, newSVpvn ((char *)&sa.sin6_addr, 16)); 615 av_push (av, newSVpvn ((char *)&sa.sin6_addr, 16));
612 av_push (av, newSVuv (pkt.payload)); 617 av_push (av, newSVuv (pkt.payload));
613 618
614 av_push (res_av, newRV_noinc ((SV *)av)); 619 av_push (res_av, newRV_noinc ((SV *)av));
615 } 620 }
616 621
622 if (res_av)
617 feed_reply (res_av); 623 feed_reply (res_av);
618} 624}
619 625

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines