ahobson-pcap 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/COPYING +340 -0
 - data/ChangeLog +145 -0
 - data/MANIFEST +46 -0
 - data/README +48 -0
 - data/README.ja +50 -0
 - data/Rakefile +17 -0
 - data/VERSION +1 -0
 - data/doc-ja/Capture.html +147 -0
 - data/doc-ja/Dumper.html +54 -0
 - data/doc-ja/Filter.html +112 -0
 - data/doc-ja/ICMPPacket.html +189 -0
 - data/doc-ja/IPAddress.html +60 -0
 - data/doc-ja/IPPacket.html +142 -0
 - data/doc-ja/Packet.html +101 -0
 - data/doc-ja/Pcap.html +111 -0
 - data/doc-ja/PcapError.html +21 -0
 - data/doc-ja/Pcaplet.html +113 -0
 - data/doc-ja/TCPPacket.html +148 -0
 - data/doc-ja/TruncatedPacket.html +22 -0
 - data/doc-ja/UDPPacket.html +73 -0
 - data/doc-ja/index.html +54 -0
 - data/doc/Capture.html +160 -0
 - data/doc/Dumper.html +60 -0
 - data/doc/Filter.html +109 -0
 - data/doc/ICMPPacket.html +184 -0
 - data/doc/IPAddress.html +60 -0
 - data/doc/IPPacket.html +142 -0
 - data/doc/Packet.html +98 -0
 - data/doc/Pcap.html +113 -0
 - data/doc/PcapError.html +21 -0
 - data/doc/Pcaplet.html +108 -0
 - data/doc/TCPPacket.html +147 -0
 - data/doc/TruncatedPacket.html +22 -0
 - data/doc/UDPPacket.html +73 -0
 - data/doc/index.html +53 -0
 - data/examples/httpdump.rb +27 -0
 - data/examples/tcpdump.rb +26 -0
 - data/examples/test.rb +11 -0
 - data/ext/Pcap.c +915 -0
 - data/ext/extconf.rb +16 -0
 - data/ext/icmp_packet.c +444 -0
 - data/ext/ip_packet.c +378 -0
 - data/ext/packet.c +328 -0
 - data/ext/ruby_pcap.h +134 -0
 - data/ext/tcp_packet.c +121 -0
 - data/ext/udp_packet.c +96 -0
 - data/lib/pcap_misc.rb +116 -0
 - data/lib/pcaplet.rb +123 -0
 - metadata +103 -0
 
    
        data/ext/ruby_pcap.h
    ADDED
    
    | 
         @@ -0,0 +1,134 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            /*
         
     | 
| 
      
 2 
     | 
    
         
            +
             *  ruby_pcap.h
         
     | 
| 
      
 3 
     | 
    
         
            +
             *
         
     | 
| 
      
 4 
     | 
    
         
            +
             *  $Id: ruby_pcap.h,v 1.4 2000/08/13 06:56:15 fukusima Exp $
         
     | 
| 
      
 5 
     | 
    
         
            +
             *
         
     | 
| 
      
 6 
     | 
    
         
            +
             *  Copyright (C) 1998-2000  Masaki Fukushima
         
     | 
| 
      
 7 
     | 
    
         
            +
             */
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            #ifndef RUBY_PCAP_H
         
     | 
| 
      
 10 
     | 
    
         
            +
            #define RUBY_PCAP_H
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            #include "ruby.h"
         
     | 
| 
      
 13 
     | 
    
         
            +
            #include <pcap.h>
         
     | 
| 
      
 14 
     | 
    
         
            +
            #include <stdio.h>
         
     | 
| 
      
 15 
     | 
    
         
            +
            #include <netinet/in.h>
         
     | 
| 
      
 16 
     | 
    
         
            +
            #include <netinet/in_systm.h>
         
     | 
| 
      
 17 
     | 
    
         
            +
            #include <netinet/ip.h>
         
     | 
| 
      
 18 
     | 
    
         
            +
            #include <arpa/inet.h>
         
     | 
| 
      
 19 
     | 
    
         
            +
            #ifndef IP_OFFMASK
         
     | 
| 
      
 20 
     | 
    
         
            +
            # define IP_OFFMASK 0x1fff
         
     | 
| 
      
 21 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 22 
     | 
    
         
            +
            #ifdef linux
         
     | 
| 
      
 23 
     | 
    
         
            +
            # define __FAVOR_BSD
         
     | 
| 
      
 24 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 25 
     | 
    
         
            +
            #include <netinet/tcp.h>
         
     | 
| 
      
 26 
     | 
    
         
            +
            #include <netinet/udp.h>
         
     | 
| 
      
 27 
     | 
    
         
            +
            #include <netinet/ip_icmp.h>
         
     | 
| 
      
 28 
     | 
    
         
            +
            #include <sys/socket.h>
         
     | 
| 
      
 29 
     | 
    
         
            +
            #include <netdb.h>
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            #ifdef DEBUG
         
     | 
| 
      
 32 
     | 
    
         
            +
            # define DEBUG_PRINT(x) do {\
         
     | 
| 
      
 33 
     | 
    
         
            +
                ((RTEST(ruby_debug) && RTEST(ruby_verbose))?\
         
     | 
| 
      
 34 
     | 
    
         
            +
                (fprintf(stderr, "%s\n", x),fflush(stderr)) : 0)\
         
     | 
| 
      
 35 
     | 
    
         
            +
            } while (0)
         
     | 
| 
      
 36 
     | 
    
         
            +
            #else
         
     | 
| 
      
 37 
     | 
    
         
            +
            # define DEBUG_PRINT(x) do {} while (0)
         
     | 
| 
      
 38 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
            #define UINT32_2_NUM(i) rb_uint2inum(i)
         
     | 
| 
      
 41 
     | 
    
         
            +
            #ifndef UINT2NUM
         
     | 
| 
      
 42 
     | 
    
         
            +
            # define UINT2NUM(i) rb_uint2inum(i)
         
     | 
| 
      
 43 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 44 
     | 
    
         
            +
            #define MIN(x, y)       ((x)<(y) ? (x) : (y))
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
            #define PACKET_MARSHAL_VERSION  1
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
            /* ruby config.h defines WORDS_BIGENDIAN if big-endian */
         
     | 
| 
      
 50 
     | 
    
         
            +
            struct packet_object_header {
         
     | 
| 
      
 51 
     | 
    
         
            +
            #ifdef WORDS_BIGENDIAN
         
     | 
| 
      
 52 
     | 
    
         
            +
                u_char version:4;           /* marshal format version       */
         
     | 
| 
      
 53 
     | 
    
         
            +
                u_char flags:4;             /* flags                        */
         
     | 
| 
      
 54 
     | 
    
         
            +
            #else
         
     | 
| 
      
 55 
     | 
    
         
            +
                u_char flags:4;             /* flags                        */
         
     | 
| 
      
 56 
     | 
    
         
            +
                u_char version:4;           /* marshal format version       */
         
     | 
| 
      
 57 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 58 
     | 
    
         
            +
            #define POH_UDATA 0x01          /* flag: user data exists       */
         
     | 
| 
      
 59 
     | 
    
         
            +
            #define POH_RSVD1 0x02          /*       (reserved)             */
         
     | 
| 
      
 60 
     | 
    
         
            +
            #define POH_RSVD2 0x03          /*       (reserved)             */
         
     | 
| 
      
 61 
     | 
    
         
            +
            #define POH_RSVD3 0x04          /*       (reserved)             */
         
     | 
| 
      
 62 
     | 
    
         
            +
                u_char dl_type;             /* data-link type (DLT_*)       */
         
     | 
| 
      
 63 
     | 
    
         
            +
                u_short layer3_off;         /* layer 3 header offset        */
         
     | 
| 
      
 64 
     | 
    
         
            +
                u_short layer4_off;         /* layer 4 header offset        */
         
     | 
| 
      
 65 
     | 
    
         
            +
                u_short layer5_off;         /* layer 5 header offset        */
         
     | 
| 
      
 66 
     | 
    
         
            +
            #define OFF_NONEXIST 0xffff     /* offset value for non-existent layer  */
         
     | 
| 
      
 67 
     | 
    
         
            +
                struct pcap_pkthdr pkthdr;  /* pcap packet header           */
         
     | 
| 
      
 68 
     | 
    
         
            +
            };
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
            struct packet_object {
         
     | 
| 
      
 71 
     | 
    
         
            +
                struct packet_object_header hdr;    /* packet object header */
         
     | 
| 
      
 72 
     | 
    
         
            +
                u_char *data;                       /* packet data          */
         
     | 
| 
      
 73 
     | 
    
         
            +
                VALUE udata;                        /* user data            */
         
     | 
| 
      
 74 
     | 
    
         
            +
            };
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
            #define PKTFLAG_TEST(pkt, flag) ((pkt)->hdr.flags & (flag))
         
     | 
| 
      
 77 
     | 
    
         
            +
            #define PKTFLAG_SET(pkt, flag, val) \
         
     | 
| 
      
 78 
     | 
    
         
            +
                ((val) ? ((pkt)->hdr.flags |= (flag)) : ((pkt)->hdr.flags &= ~(flag)))
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
            #define LAYER2_HDR(pkt) ((pkt)->data)
         
     | 
| 
      
 81 
     | 
    
         
            +
            #define LAYER3_HDR(pkt) ((pkt)->data + (pkt)->hdr.layer3_off)
         
     | 
| 
      
 82 
     | 
    
         
            +
            #define LAYER4_HDR(pkt) ((pkt)->data + (pkt)->hdr.layer4_off)
         
     | 
| 
      
 83 
     | 
    
         
            +
            #define LAYER5_HDR(pkt) ((pkt)->data + (pkt)->hdr.layer5_off)
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
            #define GetPacket(obj, pkt) Data_Get_Struct(obj, struct packet_object, pkt)
         
     | 
| 
      
 86 
     | 
    
         
            +
            #define Caplen(pkt, from) ((pkt)->hdr.pkthdr.caplen - (from))
         
     | 
| 
      
 87 
     | 
    
         
            +
            #define CheckTruncate(pkt, from, need, emsg) (\
         
     | 
| 
      
 88 
     | 
    
         
            +
                (from) + (need) > (pkt)->hdr.pkthdr.caplen ? \
         
     | 
| 
      
 89 
     | 
    
         
            +
                    rb_raise(eTruncatedPacket, (emsg)) : 0 \
         
     | 
| 
      
 90 
     | 
    
         
            +
            )
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
            #define IsKindOf(v, class) RTEST(rb_obj_is_kind_of(v, class))
         
     | 
| 
      
 93 
     | 
    
         
            +
            #define CheckClass(v, class) ((IsKindOf(v, class)) ? 0 :\
         
     | 
| 
      
 94 
     | 
    
         
            +
                rb_raise(rb_eTypeError, "wrong type %s (expected %s)",\
         
     | 
| 
      
 95 
     | 
    
         
            +
                    rb_class2name(CLASS_OF(v)), rb_class2name(class)))
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
            /* Pcap.c */
         
     | 
| 
      
 99 
     | 
    
         
            +
            extern VALUE mPcap, rbpcap_convert;
         
     | 
| 
      
 100 
     | 
    
         
            +
            extern VALUE ePcapError;
         
     | 
| 
      
 101 
     | 
    
         
            +
            extern VALUE eTruncatedPacket;
         
     | 
| 
      
 102 
     | 
    
         
            +
            extern VALUE cFilter;
         
     | 
| 
      
 103 
     | 
    
         
            +
            void Init_pcap(void);
         
     | 
| 
      
 104 
     | 
    
         
            +
            VALUE filter_match(VALUE self, VALUE v_pkt);
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
            /* packet.c */
         
     | 
| 
      
 107 
     | 
    
         
            +
            extern VALUE cPacket;
         
     | 
| 
      
 108 
     | 
    
         
            +
            void Init_packet(void);
         
     | 
| 
      
 109 
     | 
    
         
            +
            VALUE new_packet(const u_char *, const struct pcap_pkthdr *, int);
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
            /* ip_packet.c */
         
     | 
| 
      
 112 
     | 
    
         
            +
            #define IP_HDR(pkt)     ((struct ip *)LAYER3_HDR(pkt))
         
     | 
| 
      
 113 
     | 
    
         
            +
            #define IP_DATA(pkt)    ((u_char *)LAYER4_HDR(pkt))
         
     | 
| 
      
 114 
     | 
    
         
            +
            extern VALUE cIPPacket;
         
     | 
| 
      
 115 
     | 
    
         
            +
            void Init_ip_packet(void);
         
     | 
| 
      
 116 
     | 
    
         
            +
            VALUE setup_ip_packet(struct packet_object *, int);
         
     | 
| 
      
 117 
     | 
    
         
            +
            VALUE new_ipaddr(struct in_addr *);
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
            /* tcp_packet.c */
         
     | 
| 
      
 120 
     | 
    
         
            +
            extern VALUE cTCPPacket;
         
     | 
| 
      
 121 
     | 
    
         
            +
            void Init_tcp_packet(void);
         
     | 
| 
      
 122 
     | 
    
         
            +
            VALUE setup_tcp_packet(struct packet_object *, int);
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
      
 124 
     | 
    
         
            +
            /* udp_packet.c */
         
     | 
| 
      
 125 
     | 
    
         
            +
            extern VALUE cUDPPacket;
         
     | 
| 
      
 126 
     | 
    
         
            +
            void Init_udp_packet(void);
         
     | 
| 
      
 127 
     | 
    
         
            +
            VALUE setup_udp_packet(struct packet_object *, int);
         
     | 
| 
      
 128 
     | 
    
         
            +
             
     | 
| 
      
 129 
     | 
    
         
            +
            /* icmp_packet.c */
         
     | 
| 
      
 130 
     | 
    
         
            +
            extern VALUE cICMPPacket;
         
     | 
| 
      
 131 
     | 
    
         
            +
            void Init_icmp_packet(void);
         
     | 
| 
      
 132 
     | 
    
         
            +
            VALUE setup_icmp_packet(struct packet_object *, int);
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
            #endif /* RUBY_PCAP_H */
         
     | 
    
        data/ext/tcp_packet.c
    ADDED
    
    | 
         @@ -0,0 +1,121 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            /*
         
     | 
| 
      
 2 
     | 
    
         
            +
             *  tcp_packet.c
         
     | 
| 
      
 3 
     | 
    
         
            +
             *
         
     | 
| 
      
 4 
     | 
    
         
            +
             *  $Id: tcp_packet.c,v 1.1.1.1 1999/10/27 09:54:38 fukusima Exp $
         
     | 
| 
      
 5 
     | 
    
         
            +
             *
         
     | 
| 
      
 6 
     | 
    
         
            +
             *  Copyright (C) 1998, 1999  Masaki Fukushima
         
     | 
| 
      
 7 
     | 
    
         
            +
             */
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            #include "ruby_pcap.h"
         
     | 
| 
      
 10 
     | 
    
         
            +
            #include <limits.h>
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            #define TCP_HDR(pkt)    ((struct tcphdr *)LAYER4_HDR(pkt))
         
     | 
| 
      
 13 
     | 
    
         
            +
            #define TCP_DATA(pkt)   ((u_char *)LAYER5_HDR(pkt))
         
     | 
| 
      
 14 
     | 
    
         
            +
            #define TCP_DATALEN(pkt) (ntohs(IP_HDR(pkt)->ip_len) - \
         
     | 
| 
      
 15 
     | 
    
         
            +
                (IP_HDR(pkt)->ip_hl + TCP_HDR(pkt)->th_off) * 4)
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            VALUE cTCPPacket;
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            #define CheckTruncateTcp(pkt, need) \
         
     | 
| 
      
 20 
     | 
    
         
            +
                CheckTruncate(pkt, pkt->hdr.layer4_off, need, "truncated TCP")
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
            VALUE
         
     | 
| 
      
 23 
     | 
    
         
            +
            setup_tcp_packet(pkt, tl_len)
         
     | 
| 
      
 24 
     | 
    
         
            +
                 struct packet_object *pkt;
         
     | 
| 
      
 25 
     | 
    
         
            +
                 int tl_len;
         
     | 
| 
      
 26 
     | 
    
         
            +
            {
         
     | 
| 
      
 27 
     | 
    
         
            +
                VALUE class;
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                DEBUG_PRINT("setup_tcp_packet");
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                class = cTCPPacket;
         
     | 
| 
      
 32 
     | 
    
         
            +
                if (tl_len > 20) {
         
     | 
| 
      
 33 
     | 
    
         
            +
                    int hl = TCP_HDR(pkt)->th_off * 4;
         
     | 
| 
      
 34 
     | 
    
         
            +
                    int layer5_len = tl_len - hl;
         
     | 
| 
      
 35 
     | 
    
         
            +
                    if (layer5_len > 0) {
         
     | 
| 
      
 36 
     | 
    
         
            +
                        pkt->hdr.layer5_off = pkt->hdr.layer4_off + hl;
         
     | 
| 
      
 37 
     | 
    
         
            +
                        /* upper layer */
         
     | 
| 
      
 38 
     | 
    
         
            +
                    }
         
     | 
| 
      
 39 
     | 
    
         
            +
                }
         
     | 
| 
      
 40 
     | 
    
         
            +
                return class;
         
     | 
| 
      
 41 
     | 
    
         
            +
            }
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
            #define TCPP_METHOD(func, need, val) \
         
     | 
| 
      
 44 
     | 
    
         
            +
            static VALUE\
         
     | 
| 
      
 45 
     | 
    
         
            +
            (func)(self)\
         
     | 
| 
      
 46 
     | 
    
         
            +
                 VALUE self;\
         
     | 
| 
      
 47 
     | 
    
         
            +
            {\
         
     | 
| 
      
 48 
     | 
    
         
            +
                struct packet_object *pkt;\
         
     | 
| 
      
 49 
     | 
    
         
            +
                struct tcphdr *tcp;\
         
     | 
| 
      
 50 
     | 
    
         
            +
                DEBUG_PRINT(#func);\
         
     | 
| 
      
 51 
     | 
    
         
            +
                GetPacket(self, pkt);\
         
     | 
| 
      
 52 
     | 
    
         
            +
                CheckTruncateTcp(pkt, (need));\
         
     | 
| 
      
 53 
     | 
    
         
            +
                tcp = TCP_HDR(pkt);\
         
     | 
| 
      
 54 
     | 
    
         
            +
                return (val);\
         
     | 
| 
      
 55 
     | 
    
         
            +
            }
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
            TCPP_METHOD(tcpp_sport,   2, INT2FIX(ntohs(tcp->th_sport)))
         
     | 
| 
      
 58 
     | 
    
         
            +
            TCPP_METHOD(tcpp_dport,   4, INT2FIX(ntohs(tcp->th_dport)))
         
     | 
| 
      
 59 
     | 
    
         
            +
            TCPP_METHOD(tcpp_seq,     8, UINT32_2_NUM(ntohl(tcp->th_seq)))
         
     | 
| 
      
 60 
     | 
    
         
            +
            TCPP_METHOD(tcpp_acknum, 12, UINT32_2_NUM(ntohl(tcp->th_ack)))
         
     | 
| 
      
 61 
     | 
    
         
            +
            TCPP_METHOD(tcpp_off,    13, INT2FIX(tcp->th_off))
         
     | 
| 
      
 62 
     | 
    
         
            +
            TCPP_METHOD(tcpp_flags,  14, INT2FIX(tcp->th_flags))
         
     | 
| 
      
 63 
     | 
    
         
            +
            TCPP_METHOD(tcpp_win,    16, INT2FIX(ntohs(tcp->th_win)))
         
     | 
| 
      
 64 
     | 
    
         
            +
            TCPP_METHOD(tcpp_sum,    18, INT2FIX(ntohs(tcp->th_sum)))
         
     | 
| 
      
 65 
     | 
    
         
            +
            TCPP_METHOD(tcpp_urp,    20, INT2FIX(ntohs(tcp->th_urp)))
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
            #define TCPP_FLAG(func, flag) \
         
     | 
| 
      
 68 
     | 
    
         
            +
                TCPP_METHOD(func, 14, (tcp->th_flags & flag) ? Qtrue : Qfalse)
         
     | 
| 
      
 69 
     | 
    
         
            +
            TCPP_FLAG(tcpp_fin, TH_FIN)
         
     | 
| 
      
 70 
     | 
    
         
            +
            TCPP_FLAG(tcpp_syn, TH_SYN)
         
     | 
| 
      
 71 
     | 
    
         
            +
            TCPP_FLAG(tcpp_rst, TH_RST)
         
     | 
| 
      
 72 
     | 
    
         
            +
            TCPP_FLAG(tcpp_psh, TH_PUSH)
         
     | 
| 
      
 73 
     | 
    
         
            +
            TCPP_FLAG(tcpp_ack, TH_ACK)
         
     | 
| 
      
 74 
     | 
    
         
            +
            TCPP_FLAG(tcpp_urg, TH_URG)
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 77 
     | 
    
         
            +
            tcpp_data(self)
         
     | 
| 
      
 78 
     | 
    
         
            +
                 VALUE self;
         
     | 
| 
      
 79 
     | 
    
         
            +
            {
         
     | 
| 
      
 80 
     | 
    
         
            +
                struct packet_object *pkt;
         
     | 
| 
      
 81 
     | 
    
         
            +
                VALUE v_len;
         
     | 
| 
      
 82 
     | 
    
         
            +
                int len;
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                DEBUG_PRINT("tcpp_data");
         
     | 
| 
      
 85 
     | 
    
         
            +
                GetPacket(self, pkt);
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
                if (pkt->hdr.layer5_off == OFF_NONEXIST) return Qnil;
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
                len = MIN(Caplen(pkt, pkt->hdr.layer5_off), TCP_DATALEN(pkt));
         
     | 
| 
      
 90 
     | 
    
         
            +
                if (len < 1) return Qnil;
         
     | 
| 
      
 91 
     | 
    
         
            +
                return rb_str_new(TCP_DATA(pkt), len);
         
     | 
| 
      
 92 
     | 
    
         
            +
            }
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
            void
         
     | 
| 
      
 95 
     | 
    
         
            +
            Init_tcp_packet(void)
         
     | 
| 
      
 96 
     | 
    
         
            +
            {
         
     | 
| 
      
 97 
     | 
    
         
            +
                DEBUG_PRINT("Init_tcp_packet");
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
                /* define class TcpPacket */
         
     | 
| 
      
 100 
     | 
    
         
            +
                cTCPPacket = rb_define_class_under(mPcap, "TCPPacket", cIPPacket);
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
                rb_define_method(cTCPPacket, "tcp_sport", tcpp_sport, 0);
         
     | 
| 
      
 103 
     | 
    
         
            +
                rb_define_method(cTCPPacket, "sport", tcpp_sport, 0);
         
     | 
| 
      
 104 
     | 
    
         
            +
                rb_define_method(cTCPPacket, "tcp_dport", tcpp_dport, 0);
         
     | 
| 
      
 105 
     | 
    
         
            +
                rb_define_method(cTCPPacket, "dport", tcpp_dport, 0);
         
     | 
| 
      
 106 
     | 
    
         
            +
                rb_define_method(cTCPPacket, "tcp_seq", tcpp_seq, 0);
         
     | 
| 
      
 107 
     | 
    
         
            +
                rb_define_method(cTCPPacket, "tcp_ack", tcpp_acknum, 0);
         
     | 
| 
      
 108 
     | 
    
         
            +
                rb_define_method(cTCPPacket, "tcp_off", tcpp_off, 0);
         
     | 
| 
      
 109 
     | 
    
         
            +
                rb_define_method(cTCPPacket, "tcp_hlen", tcpp_off, 0);
         
     | 
| 
      
 110 
     | 
    
         
            +
                rb_define_method(cTCPPacket, "tcp_flags", tcpp_flags, 0);
         
     | 
| 
      
 111 
     | 
    
         
            +
                rb_define_method(cTCPPacket, "tcp_win", tcpp_win, 0);
         
     | 
| 
      
 112 
     | 
    
         
            +
                rb_define_method(cTCPPacket, "tcp_sum", tcpp_sum, 0);
         
     | 
| 
      
 113 
     | 
    
         
            +
                rb_define_method(cTCPPacket, "tcp_urp", tcpp_urp, 0);
         
     | 
| 
      
 114 
     | 
    
         
            +
                rb_define_method(cTCPPacket, "tcp_fin?", tcpp_fin, 0);
         
     | 
| 
      
 115 
     | 
    
         
            +
                rb_define_method(cTCPPacket, "tcp_syn?", tcpp_syn, 0);
         
     | 
| 
      
 116 
     | 
    
         
            +
                rb_define_method(cTCPPacket, "tcp_rst?", tcpp_rst, 0);
         
     | 
| 
      
 117 
     | 
    
         
            +
                rb_define_method(cTCPPacket, "tcp_psh?", tcpp_psh, 0);
         
     | 
| 
      
 118 
     | 
    
         
            +
                rb_define_method(cTCPPacket, "tcp_ack?", tcpp_ack, 0);
         
     | 
| 
      
 119 
     | 
    
         
            +
                rb_define_method(cTCPPacket, "tcp_urg?", tcpp_urg, 0);
         
     | 
| 
      
 120 
     | 
    
         
            +
                rb_define_method(cTCPPacket, "tcp_data", tcpp_data, 0);
         
     | 
| 
      
 121 
     | 
    
         
            +
            }
         
     | 
    
        data/ext/udp_packet.c
    ADDED
    
    | 
         @@ -0,0 +1,96 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            /*
         
     | 
| 
      
 2 
     | 
    
         
            +
             *  udp_packet.c
         
     | 
| 
      
 3 
     | 
    
         
            +
             *
         
     | 
| 
      
 4 
     | 
    
         
            +
             *  $Id: udp_packet.c,v 1.1.1.1 1999/10/27 09:54:38 fukusima Exp $
         
     | 
| 
      
 5 
     | 
    
         
            +
             *
         
     | 
| 
      
 6 
     | 
    
         
            +
             *  Copyright (C) 1999  Masaki Fukushima
         
     | 
| 
      
 7 
     | 
    
         
            +
             */
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            #include "ruby_pcap.h"
         
     | 
| 
      
 10 
     | 
    
         
            +
            #include <limits.h>
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            #define UDP_HDR(pkt)    ((struct udphdr *)LAYER4_HDR(pkt))
         
     | 
| 
      
 13 
     | 
    
         
            +
            #define UDP_DATA(pkt)   ((u_char *)LAYER5_HDR(pkt))
         
     | 
| 
      
 14 
     | 
    
         
            +
            #define UDP_LENGTH(pkt) (ntohs(UDP_HDR(pkt)->uh_ulen))
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            VALUE cUDPPacket;
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            #define CheckTruncateUdp(pkt, need) \
         
     | 
| 
      
 19 
     | 
    
         
            +
                CheckTruncate(pkt, pkt->hdr.layer4_off, need, "truncated UDP")
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            VALUE
         
     | 
| 
      
 22 
     | 
    
         
            +
            setup_udp_packet(pkt, tl_len)
         
     | 
| 
      
 23 
     | 
    
         
            +
                 struct packet_object *pkt;
         
     | 
| 
      
 24 
     | 
    
         
            +
                 int tl_len;
         
     | 
| 
      
 25 
     | 
    
         
            +
            {
         
     | 
| 
      
 26 
     | 
    
         
            +
                VALUE class;
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                DEBUG_PRINT("setup_udp_packet");
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                class = cUDPPacket;
         
     | 
| 
      
 31 
     | 
    
         
            +
                if (tl_len > 8) {
         
     | 
| 
      
 32 
     | 
    
         
            +
                    int hl = 8;
         
     | 
| 
      
 33 
     | 
    
         
            +
                    int layer5_len;
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                    tl_len = MIN(tl_len, UDP_LENGTH(pkt));
         
     | 
| 
      
 36 
     | 
    
         
            +
                    layer5_len = tl_len - hl;
         
     | 
| 
      
 37 
     | 
    
         
            +
                    if (layer5_len > 0) {
         
     | 
| 
      
 38 
     | 
    
         
            +
                        pkt->hdr.layer5_off = pkt->hdr.layer4_off + hl;
         
     | 
| 
      
 39 
     | 
    
         
            +
                        /* upper layer */
         
     | 
| 
      
 40 
     | 
    
         
            +
                    }
         
     | 
| 
      
 41 
     | 
    
         
            +
                }
         
     | 
| 
      
 42 
     | 
    
         
            +
                return class;
         
     | 
| 
      
 43 
     | 
    
         
            +
            }
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
            #define UDPP_METHOD(func, need, val) \
         
     | 
| 
      
 46 
     | 
    
         
            +
            static VALUE\
         
     | 
| 
      
 47 
     | 
    
         
            +
            (func)(self)\
         
     | 
| 
      
 48 
     | 
    
         
            +
                 VALUE self;\
         
     | 
| 
      
 49 
     | 
    
         
            +
            {\
         
     | 
| 
      
 50 
     | 
    
         
            +
                struct packet_object *pkt;\
         
     | 
| 
      
 51 
     | 
    
         
            +
                struct udphdr *udp;\
         
     | 
| 
      
 52 
     | 
    
         
            +
                DEBUG_PRINT(#func);\
         
     | 
| 
      
 53 
     | 
    
         
            +
                GetPacket(self, pkt);\
         
     | 
| 
      
 54 
     | 
    
         
            +
                CheckTruncateUdp(pkt, (need));\
         
     | 
| 
      
 55 
     | 
    
         
            +
                udp = UDP_HDR(pkt);\
         
     | 
| 
      
 56 
     | 
    
         
            +
                return (val);\
         
     | 
| 
      
 57 
     | 
    
         
            +
            }
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
            UDPP_METHOD(udpp_sport,   2, INT2FIX(ntohs(udp->uh_sport)))
         
     | 
| 
      
 60 
     | 
    
         
            +
            UDPP_METHOD(udpp_dport,   4, INT2FIX(ntohs(udp->uh_dport)))
         
     | 
| 
      
 61 
     | 
    
         
            +
            UDPP_METHOD(udpp_len,     6, INT2FIX(ntohs(udp->uh_ulen)))
         
     | 
| 
      
 62 
     | 
    
         
            +
            UDPP_METHOD(udpp_sum,     8, INT2FIX(ntohs(udp->uh_sum)))
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 65 
     | 
    
         
            +
            udpp_data(self)
         
     | 
| 
      
 66 
     | 
    
         
            +
                VALUE self;
         
     | 
| 
      
 67 
     | 
    
         
            +
            {
         
     | 
| 
      
 68 
     | 
    
         
            +
                struct packet_object *pkt;
         
     | 
| 
      
 69 
     | 
    
         
            +
                int len;
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                DEBUG_PRINT("udpp_data");
         
     | 
| 
      
 72 
     | 
    
         
            +
                GetPacket(self, pkt);
         
     | 
| 
      
 73 
     | 
    
         
            +
                CheckTruncateUdp(pkt, 8);
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                if (pkt->hdr.layer5_off == OFF_NONEXIST) return Qnil;
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                len = MIN(Caplen(pkt, pkt->hdr.layer5_off), UDP_LENGTH(pkt)-8);
         
     | 
| 
      
 78 
     | 
    
         
            +
                return rb_str_new(UDP_DATA(pkt), len);
         
     | 
| 
      
 79 
     | 
    
         
            +
            }
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
            void
         
     | 
| 
      
 82 
     | 
    
         
            +
            Init_udp_packet(void)
         
     | 
| 
      
 83 
     | 
    
         
            +
            {
         
     | 
| 
      
 84 
     | 
    
         
            +
                DEBUG_PRINT("Init_udp_packet");
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
                /* define class UdpPacket */
         
     | 
| 
      
 87 
     | 
    
         
            +
                cUDPPacket = rb_define_class_under(mPcap, "UDPPacket", cIPPacket);
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
                rb_define_method(cUDPPacket, "udp_sport", udpp_sport, 0);
         
     | 
| 
      
 90 
     | 
    
         
            +
                rb_define_method(cUDPPacket, "sport", udpp_sport, 0);
         
     | 
| 
      
 91 
     | 
    
         
            +
                rb_define_method(cUDPPacket, "udp_dport", udpp_dport, 0);
         
     | 
| 
      
 92 
     | 
    
         
            +
                rb_define_method(cUDPPacket, "dport", udpp_dport, 0);
         
     | 
| 
      
 93 
     | 
    
         
            +
                rb_define_method(cUDPPacket, "udp_len", udpp_len, 0);
         
     | 
| 
      
 94 
     | 
    
         
            +
                rb_define_method(cUDPPacket, "udp_sum", udpp_sum, 0);
         
     | 
| 
      
 95 
     | 
    
         
            +
                rb_define_method(cUDPPacket, "udp_data", udpp_data, 0);
         
     | 
| 
      
 96 
     | 
    
         
            +
            }
         
     | 
    
        data/lib/pcap_misc.rb
    ADDED
    
    | 
         @@ -0,0 +1,116 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
             
     | 
| 
      
 2 
     | 
    
         
            +
            module Pcap
         
     | 
| 
      
 3 
     | 
    
         
            +
              class Packet
         
     | 
| 
      
 4 
     | 
    
         
            +
                def to_s
         
     | 
| 
      
 5 
     | 
    
         
            +
                  'Some packet'
         
     | 
| 
      
 6 
     | 
    
         
            +
                end
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                def inspect
         
     | 
| 
      
 9 
     | 
    
         
            +
                  "#<#{self.class}: #{self}>"
         
     | 
| 
      
 10 
     | 
    
         
            +
                end
         
     | 
| 
      
 11 
     | 
    
         
            +
              end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
              class IPPacket
         
     | 
| 
      
 14 
     | 
    
         
            +
                def to_s
         
     | 
| 
      
 15 
     | 
    
         
            +
                  "#{ip_src} > #{ip_dst}"
         
     | 
| 
      
 16 
     | 
    
         
            +
                end
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
              class TCPPacket
         
     | 
| 
      
 20 
     | 
    
         
            +
                def tcp_data_len
         
     | 
| 
      
 21 
     | 
    
         
            +
                  ip_len - 4 * (ip_hlen + tcp_hlen)
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                def tcp_flags_s
         
     | 
| 
      
 25 
     | 
    
         
            +
                  return \
         
     | 
| 
      
 26 
     | 
    
         
            +
            	(tcp_urg? ? 'U' : '.') +
         
     | 
| 
      
 27 
     | 
    
         
            +
            	(tcp_ack? ? 'A' : '.') +
         
     | 
| 
      
 28 
     | 
    
         
            +
            	(tcp_psh? ? 'P' : '.') +
         
     | 
| 
      
 29 
     | 
    
         
            +
            	(tcp_rst? ? 'R' : '.') +
         
     | 
| 
      
 30 
     | 
    
         
            +
            	(tcp_syn? ? 'S' : '.') +
         
     | 
| 
      
 31 
     | 
    
         
            +
                    (tcp_fin? ? 'F' : '.')
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                def to_s
         
     | 
| 
      
 35 
     | 
    
         
            +
                  "#{src}:#{sport} > #{dst}:#{dport} #{tcp_flags_s}"
         
     | 
| 
      
 36 
     | 
    
         
            +
                end
         
     | 
| 
      
 37 
     | 
    
         
            +
              end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
              class UDPPacket
         
     | 
| 
      
 40 
     | 
    
         
            +
                def to_s
         
     | 
| 
      
 41 
     | 
    
         
            +
                  "#{src}:#{sport} > #{dst}:#{dport} len #{udp_len} sum #{udp_sum}"
         
     | 
| 
      
 42 
     | 
    
         
            +
                end
         
     | 
| 
      
 43 
     | 
    
         
            +
              end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
              class ICMPPacket
         
     | 
| 
      
 46 
     | 
    
         
            +
                def to_s
         
     | 
| 
      
 47 
     | 
    
         
            +
                  "#{src} > #{dst}: icmp: #{icmp_typestr}"
         
     | 
| 
      
 48 
     | 
    
         
            +
                end
         
     | 
| 
      
 49 
     | 
    
         
            +
              end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
              #
         
     | 
| 
      
 52 
     | 
    
         
            +
              # Backword compatibility
         
     | 
| 
      
 53 
     | 
    
         
            +
              #
         
     | 
| 
      
 54 
     | 
    
         
            +
              IpPacket = IPPacket
         
     | 
| 
      
 55 
     | 
    
         
            +
              IpAddress = IPAddress
         
     | 
| 
      
 56 
     | 
    
         
            +
              TcpPacket = TCPPacket
         
     | 
| 
      
 57 
     | 
    
         
            +
              UdpPacket = UDPPacket
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
              # IpAddress is now obsolete.
         
     | 
| 
      
 60 
     | 
    
         
            +
              # New class IPAddress is implemented in C.
         
     | 
| 
      
 61 
     | 
    
         
            +
            =begin
         
     | 
| 
      
 62 
     | 
    
         
            +
              class IpAddress
         
     | 
| 
      
 63 
     | 
    
         
            +
                def initialize(a)
         
     | 
| 
      
 64 
     | 
    
         
            +
                  raise AurgumentError unless a.is_a?(Integer)
         
     | 
| 
      
 65 
     | 
    
         
            +
                  @addr = a
         
     | 
| 
      
 66 
     | 
    
         
            +
                end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                def to_i
         
     | 
| 
      
 69 
     | 
    
         
            +
                  return @addr
         
     | 
| 
      
 70 
     | 
    
         
            +
                end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                def ==(other)
         
     | 
| 
      
 73 
     | 
    
         
            +
                  @addr == other.to_i
         
     | 
| 
      
 74 
     | 
    
         
            +
                end
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
                alias === ==
         
     | 
| 
      
 77 
     | 
    
         
            +
                alias eql? ==
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                def to_num_s
         
     | 
| 
      
 80 
     | 
    
         
            +
                    return ((@addr >> 24) & 0xff).to_s + "." +
         
     | 
| 
      
 81 
     | 
    
         
            +
                      ((@addr >> 16) & 0xff).to_s + "." +
         
     | 
| 
      
 82 
     | 
    
         
            +
                      ((@addr >> 8) & 0xff).to_s + "." +
         
     | 
| 
      
 83 
     | 
    
         
            +
                      (@addr & 0xff).to_s;
         
     | 
| 
      
 84 
     | 
    
         
            +
                end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
                def hostname
         
     | 
| 
      
 87 
     | 
    
         
            +
                  addr = self.to_num_s
         
     | 
| 
      
 88 
     | 
    
         
            +
                  # "require 'socket'" is here because of the order of
         
     | 
| 
      
 89 
     | 
    
         
            +
                  #   ext initialization in static linked binary
         
     | 
| 
      
 90 
     | 
    
         
            +
                  require 'socket'
         
     | 
| 
      
 91 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 92 
     | 
    
         
            +
            	return Socket.gethostbyname(addr)[0]
         
     | 
| 
      
 93 
     | 
    
         
            +
                  rescue SocketError
         
     | 
| 
      
 94 
     | 
    
         
            +
            	return addr
         
     | 
| 
      
 95 
     | 
    
         
            +
                  end
         
     | 
| 
      
 96 
     | 
    
         
            +
                end
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
                def to_s
         
     | 
| 
      
 99 
     | 
    
         
            +
                  if Pcap.convert?
         
     | 
| 
      
 100 
     | 
    
         
            +
                    return hostname
         
     | 
| 
      
 101 
     | 
    
         
            +
                  else
         
     | 
| 
      
 102 
     | 
    
         
            +
                    return to_num_s
         
     | 
| 
      
 103 
     | 
    
         
            +
                  end
         
     | 
| 
      
 104 
     | 
    
         
            +
                end
         
     | 
| 
      
 105 
     | 
    
         
            +
              end
         
     | 
| 
      
 106 
     | 
    
         
            +
            =end
         
     | 
| 
      
 107 
     | 
    
         
            +
            end
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
            class Time
         
     | 
| 
      
 110 
     | 
    
         
            +
              # tcpdump style format
         
     | 
| 
      
 111 
     | 
    
         
            +
              def tcpdump
         
     | 
| 
      
 112 
     | 
    
         
            +
                sprintf "%0.2d:%0.2d:%0.2d.%0.6d", hour, min, sec, tv_usec
         
     | 
| 
      
 113 
     | 
    
         
            +
              end
         
     | 
| 
      
 114 
     | 
    
         
            +
            end
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
            autoload :Pcaplet, 'pcaplet'
         
     |