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/ip_packet.c
    ADDED
    
    | 
         @@ -0,0 +1,378 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            /*
         
     | 
| 
      
 2 
     | 
    
         
            +
             *  ip_packet.c
         
     | 
| 
      
 3 
     | 
    
         
            +
             *
         
     | 
| 
      
 4 
     | 
    
         
            +
             *  $Id: ip_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 <netdb.h>
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            VALUE cIPPacket;
         
     | 
| 
      
 13 
     | 
    
         
            +
            static VALUE cIPAddress;
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            #define CheckTruncateIp(pkt, need) \
         
     | 
| 
      
 16 
     | 
    
         
            +
                CheckTruncate(pkt, pkt->hdr.layer3_off, need, "truncated IP")
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            VALUE
         
     | 
| 
      
 19 
     | 
    
         
            +
            setup_ip_packet(pkt, nl_len)
         
     | 
| 
      
 20 
     | 
    
         
            +
                 struct packet_object *pkt;
         
     | 
| 
      
 21 
     | 
    
         
            +
                 int nl_len;
         
     | 
| 
      
 22 
     | 
    
         
            +
            {
         
     | 
| 
      
 23 
     | 
    
         
            +
                VALUE class;
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                DEBUG_PRINT("setup_ip_packet");
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                if (nl_len > 0 && IP_HDR(pkt)->ip_v != 4) {
         
     | 
| 
      
 28 
     | 
    
         
            +
                    return cPacket;
         
     | 
| 
      
 29 
     | 
    
         
            +
                }
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                class = cIPPacket;
         
     | 
| 
      
 32 
     | 
    
         
            +
                nl_len = MIN(nl_len, ntohs(IP_HDR(pkt)->ip_len));
         
     | 
| 
      
 33 
     | 
    
         
            +
                if (nl_len > 20) {
         
     | 
| 
      
 34 
     | 
    
         
            +
                    int hl = IP_HDR(pkt)->ip_hl * 4;
         
     | 
| 
      
 35 
     | 
    
         
            +
                    int tl_len = nl_len - hl;
         
     | 
| 
      
 36 
     | 
    
         
            +
                    if (tl_len > 0) {
         
     | 
| 
      
 37 
     | 
    
         
            +
                        pkt->hdr.layer4_off = pkt->hdr.layer3_off + hl;
         
     | 
| 
      
 38 
     | 
    
         
            +
                        /* if this is fragment zero, setup upper layer */
         
     | 
| 
      
 39 
     | 
    
         
            +
                        if ((ntohs(IP_HDR(pkt)->ip_off) & IP_OFFMASK) == 0) {
         
     | 
| 
      
 40 
     | 
    
         
            +
                            switch (IP_HDR(pkt)->ip_p) {
         
     | 
| 
      
 41 
     | 
    
         
            +
                            case IPPROTO_TCP:
         
     | 
| 
      
 42 
     | 
    
         
            +
                                class = setup_tcp_packet(pkt, tl_len);
         
     | 
| 
      
 43 
     | 
    
         
            +
                                break;
         
     | 
| 
      
 44 
     | 
    
         
            +
                            case IPPROTO_UDP:
         
     | 
| 
      
 45 
     | 
    
         
            +
                                class = setup_udp_packet(pkt, tl_len);
         
     | 
| 
      
 46 
     | 
    
         
            +
                                break;
         
     | 
| 
      
 47 
     | 
    
         
            +
                            case IPPROTO_ICMP:
         
     | 
| 
      
 48 
     | 
    
         
            +
                                class = setup_icmp_packet(pkt, tl_len);
         
     | 
| 
      
 49 
     | 
    
         
            +
                                break;
         
     | 
| 
      
 50 
     | 
    
         
            +
                            }               
         
     | 
| 
      
 51 
     | 
    
         
            +
                        }
         
     | 
| 
      
 52 
     | 
    
         
            +
                    }
         
     | 
| 
      
 53 
     | 
    
         
            +
                }
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                return class;
         
     | 
| 
      
 56 
     | 
    
         
            +
            }
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
            #define IPP_METHOD(func, need, val) \
         
     | 
| 
      
 59 
     | 
    
         
            +
            static VALUE\
         
     | 
| 
      
 60 
     | 
    
         
            +
            (func)(self)\
         
     | 
| 
      
 61 
     | 
    
         
            +
                 VALUE self;\
         
     | 
| 
      
 62 
     | 
    
         
            +
            {\
         
     | 
| 
      
 63 
     | 
    
         
            +
                struct packet_object *pkt;\
         
     | 
| 
      
 64 
     | 
    
         
            +
                struct ip *ip;\
         
     | 
| 
      
 65 
     | 
    
         
            +
            \
         
     | 
| 
      
 66 
     | 
    
         
            +
                DEBUG_PRINT(#func);\
         
     | 
| 
      
 67 
     | 
    
         
            +
                GetPacket(self, pkt);\
         
     | 
| 
      
 68 
     | 
    
         
            +
                CheckTruncateIp(pkt, (need));\
         
     | 
| 
      
 69 
     | 
    
         
            +
                ip = IP_HDR(pkt);\
         
     | 
| 
      
 70 
     | 
    
         
            +
                return (val);\
         
     | 
| 
      
 71 
     | 
    
         
            +
            }
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
            IPP_METHOD(ipp_ver,    1, INT2FIX(ip->ip_v))
         
     | 
| 
      
 74 
     | 
    
         
            +
            IPP_METHOD(ipp_hlen,   1, INT2FIX(ip->ip_hl))
         
     | 
| 
      
 75 
     | 
    
         
            +
            IPP_METHOD(ipp_tos,    2, INT2FIX(ip->ip_tos))
         
     | 
| 
      
 76 
     | 
    
         
            +
            IPP_METHOD(ipp_len,    4, INT2FIX(ntohs(ip->ip_len)))
         
     | 
| 
      
 77 
     | 
    
         
            +
            IPP_METHOD(ipp_id,     6, INT2FIX(ntohs(ip->ip_id)))
         
     | 
| 
      
 78 
     | 
    
         
            +
            IPP_METHOD(ipp_flags,  8, INT2FIX((ntohs(ip->ip_off) & ~IP_OFFMASK) >> 13))
         
     | 
| 
      
 79 
     | 
    
         
            +
            IPP_METHOD(ipp_df,     8, ntohs(ip->ip_off) & IP_DF ? Qtrue : Qfalse)
         
     | 
| 
      
 80 
     | 
    
         
            +
            IPP_METHOD(ipp_mf,     8, ntohs(ip->ip_off) & IP_MF ? Qtrue : Qfalse)
         
     | 
| 
      
 81 
     | 
    
         
            +
            IPP_METHOD(ipp_off,    8, INT2FIX(ntohs(ip->ip_off) & IP_OFFMASK))
         
     | 
| 
      
 82 
     | 
    
         
            +
            IPP_METHOD(ipp_ttl,    9, INT2FIX(ip->ip_ttl))
         
     | 
| 
      
 83 
     | 
    
         
            +
            IPP_METHOD(ipp_proto, 10, INT2FIX(ip->ip_p))
         
     | 
| 
      
 84 
     | 
    
         
            +
            IPP_METHOD(ipp_sum,   12, INT2FIX(ntohs(ip->ip_sum)))
         
     | 
| 
      
 85 
     | 
    
         
            +
            IPP_METHOD(ipp_src,   16, new_ipaddr(&ip->ip_src))
         
     | 
| 
      
 86 
     | 
    
         
            +
            IPP_METHOD(ipp_dst,   20, new_ipaddr(&ip->ip_dst))
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
            #define IPP_SET_METHOD(func, need, member) \
         
     | 
| 
      
 90 
     | 
    
         
            +
            static VALUE \
         
     | 
| 
      
 91 
     | 
    
         
            +
            (func)(self, val) \
         
     | 
| 
      
 92 
     | 
    
         
            +
                 VALUE self; \
         
     | 
| 
      
 93 
     | 
    
         
            +
                 VALUE val; \
         
     | 
| 
      
 94 
     | 
    
         
            +
            { \
         
     | 
| 
      
 95 
     | 
    
         
            +
                 struct packet_object *pkt; \
         
     | 
| 
      
 96 
     | 
    
         
            +
                 struct ip *ip; \
         
     | 
| 
      
 97 
     | 
    
         
            +
            \
         
     | 
| 
      
 98 
     | 
    
         
            +
                 DEBUG_PRINT(#func); \
         
     | 
| 
      
 99 
     | 
    
         
            +
                 GetPacket(self, pkt); \
         
     | 
| 
      
 100 
     | 
    
         
            +
                 CheckTruncateIp(pkt, (need)); \
         
     | 
| 
      
 101 
     | 
    
         
            +
                 ip = IP_HDR(pkt); \
         
     | 
| 
      
 102 
     | 
    
         
            +
            \
         
     | 
| 
      
 103 
     | 
    
         
            +
                 switch(TYPE(val)) { \
         
     | 
| 
      
 104 
     | 
    
         
            +
                 case T_STRING: \
         
     | 
| 
      
 105 
     | 
    
         
            +
                   (member).s_addr = inet_addr(RSTRING(val)->ptr); \
         
     | 
| 
      
 106 
     | 
    
         
            +
                   break; \
         
     | 
| 
      
 107 
     | 
    
         
            +
                 case T_BIGNUM: \
         
     | 
| 
      
 108 
     | 
    
         
            +
                   (member).s_addr = NUM2UINT(val); \
         
     | 
| 
      
 109 
     | 
    
         
            +
                   break; \
         
     | 
| 
      
 110 
     | 
    
         
            +
                 case T_DATA: \
         
     | 
| 
      
 111 
     | 
    
         
            +
                   (member).s_addr = ((struct in_addr *)&(DATA_PTR(val)))->s_addr; \
         
     | 
| 
      
 112 
     | 
    
         
            +
                 } \
         
     | 
| 
      
 113 
     | 
    
         
            +
                 return val; \
         
     | 
| 
      
 114 
     | 
    
         
            +
            }
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
            IPP_SET_METHOD(ipp_set_src, 16, ip->ip_src)
         
     | 
| 
      
 118 
     | 
    
         
            +
            IPP_SET_METHOD(ipp_set_dst, 20, ip->ip_dst)
         
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
      
 120 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 121 
     | 
    
         
            +
            ipp_sumok(self)
         
     | 
| 
      
 122 
     | 
    
         
            +
                 VALUE self;
         
     | 
| 
      
 123 
     | 
    
         
            +
            {
         
     | 
| 
      
 124 
     | 
    
         
            +
                struct packet_object *pkt;
         
     | 
| 
      
 125 
     | 
    
         
            +
                struct ip *ip;
         
     | 
| 
      
 126 
     | 
    
         
            +
                int hlen, i, sum;
         
     | 
| 
      
 127 
     | 
    
         
            +
                unsigned short *ipus;
         
     | 
| 
      
 128 
     | 
    
         
            +
             
     | 
| 
      
 129 
     | 
    
         
            +
                GetPacket(self, pkt);
         
     | 
| 
      
 130 
     | 
    
         
            +
                CheckTruncateIp(pkt, 20);
         
     | 
| 
      
 131 
     | 
    
         
            +
                ip = IP_HDR(pkt);
         
     | 
| 
      
 132 
     | 
    
         
            +
             
     | 
| 
      
 133 
     | 
    
         
            +
                hlen = ip->ip_hl * 4;
         
     | 
| 
      
 134 
     | 
    
         
            +
                CheckTruncateIp(pkt, hlen);
         
     | 
| 
      
 135 
     | 
    
         
            +
             
     | 
| 
      
 136 
     | 
    
         
            +
                ipus = (unsigned short *)ip;
         
     | 
| 
      
 137 
     | 
    
         
            +
                sum = 0;
         
     | 
| 
      
 138 
     | 
    
         
            +
                hlen /= 2; /* 16-bit word */
         
     | 
| 
      
 139 
     | 
    
         
            +
                for (i = 0; i < hlen; i++) {
         
     | 
| 
      
 140 
     | 
    
         
            +
                    sum += ntohs(ipus[i]);
         
     | 
| 
      
 141 
     | 
    
         
            +
                    sum = (sum & 0xffff) + (sum >> 16);
         
     | 
| 
      
 142 
     | 
    
         
            +
                }
         
     | 
| 
      
 143 
     | 
    
         
            +
                if (sum == 0xffff)
         
     | 
| 
      
 144 
     | 
    
         
            +
                    return Qtrue;
         
     | 
| 
      
 145 
     | 
    
         
            +
                return Qfalse;
         
     | 
| 
      
 146 
     | 
    
         
            +
            }
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 149 
     | 
    
         
            +
            ipp_data(self)
         
     | 
| 
      
 150 
     | 
    
         
            +
                 VALUE self;
         
     | 
| 
      
 151 
     | 
    
         
            +
            {
         
     | 
| 
      
 152 
     | 
    
         
            +
                struct packet_object *pkt;
         
     | 
| 
      
 153 
     | 
    
         
            +
                struct ip *ip;
         
     | 
| 
      
 154 
     | 
    
         
            +
                int len, hlen;
         
     | 
| 
      
 155 
     | 
    
         
            +
             
     | 
| 
      
 156 
     | 
    
         
            +
                DEBUG_PRINT("ipp_data");
         
     | 
| 
      
 157 
     | 
    
         
            +
                GetPacket(self, pkt);
         
     | 
| 
      
 158 
     | 
    
         
            +
                CheckTruncateIp(pkt, 20);
         
     | 
| 
      
 159 
     | 
    
         
            +
                ip = IP_HDR(pkt);
         
     | 
| 
      
 160 
     | 
    
         
            +
             
     | 
| 
      
 161 
     | 
    
         
            +
                hlen = ip->ip_hl * 4;
         
     | 
| 
      
 162 
     | 
    
         
            +
                len = pkt->hdr.pkthdr.caplen - pkt->hdr.layer3_off - hlen;
         
     | 
| 
      
 163 
     | 
    
         
            +
                return rb_str_new((u_char *)ip + hlen, len);
         
     | 
| 
      
 164 
     | 
    
         
            +
            }
         
     | 
| 
      
 165 
     | 
    
         
            +
             
     | 
| 
      
 166 
     | 
    
         
            +
            /*
         
     | 
| 
      
 167 
     | 
    
         
            +
             * IPAddress
         
     | 
| 
      
 168 
     | 
    
         
            +
             */
         
     | 
| 
      
 169 
     | 
    
         
            +
             
     | 
| 
      
 170 
     | 
    
         
            +
            /* IPv4 adress (32bit) is stored by immediate value */
         
     | 
| 
      
 171 
     | 
    
         
            +
            #if SIZEOF_VOIDP < 4
         
     | 
| 
      
 172 
     | 
    
         
            +
            # error IPAddress assumes sizeof(void *) >= 4
         
     | 
| 
      
 173 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 174 
     | 
    
         
            +
             
     | 
| 
      
 175 
     | 
    
         
            +
            #define GetIPAddress(obj, addr) {\
         
     | 
| 
      
 176 
     | 
    
         
            +
                Check_Type(obj, T_DATA);\
         
     | 
| 
      
 177 
     | 
    
         
            +
                addr = (struct in_addr *)&(DATA_PTR(obj));\
         
     | 
| 
      
 178 
     | 
    
         
            +
            }
         
     | 
| 
      
 179 
     | 
    
         
            +
             
     | 
| 
      
 180 
     | 
    
         
            +
            VALUE
         
     | 
| 
      
 181 
     | 
    
         
            +
            new_ipaddr(addr)
         
     | 
| 
      
 182 
     | 
    
         
            +
                struct in_addr *addr;
         
     | 
| 
      
 183 
     | 
    
         
            +
            {
         
     | 
| 
      
 184 
     | 
    
         
            +
                VALUE self;
         
     | 
| 
      
 185 
     | 
    
         
            +
             
     | 
| 
      
 186 
     | 
    
         
            +
                self = Data_Wrap_Struct(cIPAddress, 0, 0, (void *)addr->s_addr);
         
     | 
| 
      
 187 
     | 
    
         
            +
                return self;
         
     | 
| 
      
 188 
     | 
    
         
            +
            }
         
     | 
| 
      
 189 
     | 
    
         
            +
             
     | 
| 
      
 190 
     | 
    
         
            +
            #ifndef INADDR_NONE
         
     | 
| 
      
 191 
     | 
    
         
            +
            # define INADDR_NONE (0xffffffff)
         
     | 
| 
      
 192 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 193 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 194 
     | 
    
         
            +
            ipaddr_s_new(self, val)
         
     | 
| 
      
 195 
     | 
    
         
            +
                VALUE self, val;
         
     | 
| 
      
 196 
     | 
    
         
            +
            {
         
     | 
| 
      
 197 
     | 
    
         
            +
                struct in_addr addr;
         
     | 
| 
      
 198 
     | 
    
         
            +
                struct hostent *hent;
         
     | 
| 
      
 199 
     | 
    
         
            +
                char *hname;
         
     | 
| 
      
 200 
     | 
    
         
            +
             
     | 
| 
      
 201 
     | 
    
         
            +
                switch(TYPE(val)) {
         
     | 
| 
      
 202 
     | 
    
         
            +
                case T_STRING:
         
     | 
| 
      
 203 
     | 
    
         
            +
                    hname = RSTRING(val)->ptr;
         
     | 
| 
      
 204 
     | 
    
         
            +
                    hent = gethostbyname(hname);
         
     | 
| 
      
 205 
     | 
    
         
            +
                    if (hent == NULL) {
         
     | 
| 
      
 206 
     | 
    
         
            +
                        extern int h_errno;
         
     | 
| 
      
 207 
     | 
    
         
            +
                        switch (h_errno) {
         
     | 
| 
      
 208 
     | 
    
         
            +
                        case HOST_NOT_FOUND:
         
     | 
| 
      
 209 
     | 
    
         
            +
                            rb_raise(ePcapError, "host not found: %s", hname);
         
     | 
| 
      
 210 
     | 
    
         
            +
                            break;
         
     | 
| 
      
 211 
     | 
    
         
            +
                        default:
         
     | 
| 
      
 212 
     | 
    
         
            +
            #ifdef HAVE_HSTRERROR
         
     | 
| 
      
 213 
     | 
    
         
            +
                            rb_raise(ePcapError, (char *)hstrerror(h_errno));
         
     | 
| 
      
 214 
     | 
    
         
            +
            #else
         
     | 
| 
      
 215 
     | 
    
         
            +
                            rb_raise(ePcapError, "host not found: %s", hname);
         
     | 
| 
      
 216 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 217 
     | 
    
         
            +
                        }
         
     | 
| 
      
 218 
     | 
    
         
            +
                    }
         
     | 
| 
      
 219 
     | 
    
         
            +
                    addr = *(struct in_addr *)hent->h_addr;
         
     | 
| 
      
 220 
     | 
    
         
            +
                    break;
         
     | 
| 
      
 221 
     | 
    
         
            +
                case T_FIXNUM:
         
     | 
| 
      
 222 
     | 
    
         
            +
                case T_BIGNUM:
         
     | 
| 
      
 223 
     | 
    
         
            +
                    addr.s_addr = htonl(NUM2ULONG(val));
         
     | 
| 
      
 224 
     | 
    
         
            +
                    break;
         
     | 
| 
      
 225 
     | 
    
         
            +
                default:
         
     | 
| 
      
 226 
     | 
    
         
            +
                    rb_raise(rb_eTypeError, "String or Integer required");
         
     | 
| 
      
 227 
     | 
    
         
            +
                }
         
     | 
| 
      
 228 
     | 
    
         
            +
                return new_ipaddr(&addr);
         
     | 
| 
      
 229 
     | 
    
         
            +
            }
         
     | 
| 
      
 230 
     | 
    
         
            +
             
     | 
| 
      
 231 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 232 
     | 
    
         
            +
            ipaddr_to_i(self)
         
     | 
| 
      
 233 
     | 
    
         
            +
                VALUE self;
         
     | 
| 
      
 234 
     | 
    
         
            +
            {
         
     | 
| 
      
 235 
     | 
    
         
            +
                struct in_addr *addr;
         
     | 
| 
      
 236 
     | 
    
         
            +
             
     | 
| 
      
 237 
     | 
    
         
            +
                GetIPAddress(self, addr);
         
     | 
| 
      
 238 
     | 
    
         
            +
                return UINT32_2_NUM(ntohl(addr->s_addr));
         
     | 
| 
      
 239 
     | 
    
         
            +
            }
         
     | 
| 
      
 240 
     | 
    
         
            +
             
     | 
| 
      
 241 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 242 
     | 
    
         
            +
            ipaddr_num_s(self)
         
     | 
| 
      
 243 
     | 
    
         
            +
                VALUE self;
         
     | 
| 
      
 244 
     | 
    
         
            +
            {
         
     | 
| 
      
 245 
     | 
    
         
            +
                struct in_addr *addr;
         
     | 
| 
      
 246 
     | 
    
         
            +
             
     | 
| 
      
 247 
     | 
    
         
            +
                GetIPAddress(self, addr);
         
     | 
| 
      
 248 
     | 
    
         
            +
                return rb_str_new2(inet_ntoa(*addr));
         
     | 
| 
      
 249 
     | 
    
         
            +
            }
         
     | 
| 
      
 250 
     | 
    
         
            +
             
     | 
| 
      
 251 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 252 
     | 
    
         
            +
            ipaddr_hostname(self)
         
     | 
| 
      
 253 
     | 
    
         
            +
                VALUE self;
         
     | 
| 
      
 254 
     | 
    
         
            +
            {
         
     | 
| 
      
 255 
     | 
    
         
            +
                struct in_addr *addr;
         
     | 
| 
      
 256 
     | 
    
         
            +
                struct hostent *host;
         
     | 
| 
      
 257 
     | 
    
         
            +
             
     | 
| 
      
 258 
     | 
    
         
            +
                GetIPAddress(self, addr);
         
     | 
| 
      
 259 
     | 
    
         
            +
                host = gethostbyaddr((char *)&addr->s_addr, sizeof addr->s_addr, AF_INET);
         
     | 
| 
      
 260 
     | 
    
         
            +
                if (host == NULL)
         
     | 
| 
      
 261 
     | 
    
         
            +
                    return ipaddr_num_s(self);
         
     | 
| 
      
 262 
     | 
    
         
            +
                return rb_str_new2(host->h_name);
         
     | 
| 
      
 263 
     | 
    
         
            +
            }
         
     | 
| 
      
 264 
     | 
    
         
            +
             
     | 
| 
      
 265 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 266 
     | 
    
         
            +
            ipaddr_to_s(self)
         
     | 
| 
      
 267 
     | 
    
         
            +
                VALUE self;
         
     | 
| 
      
 268 
     | 
    
         
            +
            {
         
     | 
| 
      
 269 
     | 
    
         
            +
                if (RTEST(rbpcap_convert))
         
     | 
| 
      
 270 
     | 
    
         
            +
                    return ipaddr_hostname(self);
         
     | 
| 
      
 271 
     | 
    
         
            +
                else
         
     | 
| 
      
 272 
     | 
    
         
            +
                    return ipaddr_num_s(self);
         
     | 
| 
      
 273 
     | 
    
         
            +
            }
         
     | 
| 
      
 274 
     | 
    
         
            +
             
     | 
| 
      
 275 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 276 
     | 
    
         
            +
            ipaddr_equal(self, other)
         
     | 
| 
      
 277 
     | 
    
         
            +
                VALUE self, other;
         
     | 
| 
      
 278 
     | 
    
         
            +
            {
         
     | 
| 
      
 279 
     | 
    
         
            +
                struct in_addr *addr1;
         
     | 
| 
      
 280 
     | 
    
         
            +
                struct in_addr *addr2;
         
     | 
| 
      
 281 
     | 
    
         
            +
             
     | 
| 
      
 282 
     | 
    
         
            +
                GetIPAddress(self, addr1);
         
     | 
| 
      
 283 
     | 
    
         
            +
                if (rb_class_of(other) == cIPAddress) {
         
     | 
| 
      
 284 
     | 
    
         
            +
                    GetIPAddress(other, addr2);
         
     | 
| 
      
 285 
     | 
    
         
            +
                    if (addr1->s_addr == addr2->s_addr)
         
     | 
| 
      
 286 
     | 
    
         
            +
                        return Qtrue;
         
     | 
| 
      
 287 
     | 
    
         
            +
                }
         
     | 
| 
      
 288 
     | 
    
         
            +
                return Qfalse;
         
     | 
| 
      
 289 
     | 
    
         
            +
            }
         
     | 
| 
      
 290 
     | 
    
         
            +
             
     | 
| 
      
 291 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 292 
     | 
    
         
            +
            ipaddr_hash(self)
         
     | 
| 
      
 293 
     | 
    
         
            +
                VALUE self;
         
     | 
| 
      
 294 
     | 
    
         
            +
            {
         
     | 
| 
      
 295 
     | 
    
         
            +
                struct in_addr *addr;
         
     | 
| 
      
 296 
     | 
    
         
            +
             
     | 
| 
      
 297 
     | 
    
         
            +
                GetIPAddress(self, addr);
         
     | 
| 
      
 298 
     | 
    
         
            +
                return INT2FIX(ntohl(addr->s_addr));
         
     | 
| 
      
 299 
     | 
    
         
            +
            }
         
     | 
| 
      
 300 
     | 
    
         
            +
             
     | 
| 
      
 301 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 302 
     | 
    
         
            +
            ipaddr_dump(self, limit)
         
     | 
| 
      
 303 
     | 
    
         
            +
                 VALUE self;
         
     | 
| 
      
 304 
     | 
    
         
            +
                 VALUE limit;
         
     | 
| 
      
 305 
     | 
    
         
            +
            {
         
     | 
| 
      
 306 
     | 
    
         
            +
                struct in_addr *addr;
         
     | 
| 
      
 307 
     | 
    
         
            +
             
     | 
| 
      
 308 
     | 
    
         
            +
                GetIPAddress(self, addr);
         
     | 
| 
      
 309 
     | 
    
         
            +
                return rb_str_new((char *)addr, sizeof addr);
         
     | 
| 
      
 310 
     | 
    
         
            +
            }
         
     | 
| 
      
 311 
     | 
    
         
            +
             
     | 
| 
      
 312 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 313 
     | 
    
         
            +
            ipaddr_s_load(klass, str)
         
     | 
| 
      
 314 
     | 
    
         
            +
                 VALUE klass;
         
     | 
| 
      
 315 
     | 
    
         
            +
                 VALUE str;
         
     | 
| 
      
 316 
     | 
    
         
            +
            {
         
     | 
| 
      
 317 
     | 
    
         
            +
                struct in_addr addr;
         
     | 
| 
      
 318 
     | 
    
         
            +
                int i;
         
     | 
| 
      
 319 
     | 
    
         
            +
             
     | 
| 
      
 320 
     | 
    
         
            +
                if (RSTRING(str)->len != sizeof addr) {
         
     | 
| 
      
 321 
     | 
    
         
            +
                    rb_raise(rb_eArgError, "dump format error (IPAddress)");
         
     | 
| 
      
 322 
     | 
    
         
            +
                }
         
     | 
| 
      
 323 
     | 
    
         
            +
                for (i = 0; i < sizeof addr; i++) {
         
     | 
| 
      
 324 
     | 
    
         
            +
                    ((char *)&addr)[i] = RSTRING(str)->ptr[i];
         
     | 
| 
      
 325 
     | 
    
         
            +
                }   
         
     | 
| 
      
 326 
     | 
    
         
            +
                return new_ipaddr(&addr);
         
     | 
| 
      
 327 
     | 
    
         
            +
            }
         
     | 
| 
      
 328 
     | 
    
         
            +
             
     | 
| 
      
 329 
     | 
    
         
            +
            void
         
     | 
| 
      
 330 
     | 
    
         
            +
            Init_ip_packet(void)
         
     | 
| 
      
 331 
     | 
    
         
            +
            {
         
     | 
| 
      
 332 
     | 
    
         
            +
                DEBUG_PRINT("Init_ip_packet");
         
     | 
| 
      
 333 
     | 
    
         
            +
             
     | 
| 
      
 334 
     | 
    
         
            +
                cIPPacket = rb_define_class_under(mPcap, "IPPacket", cPacket);
         
     | 
| 
      
 335 
     | 
    
         
            +
             
     | 
| 
      
 336 
     | 
    
         
            +
                rb_define_method(cIPPacket, "ip_ver", ipp_ver, 0);
         
     | 
| 
      
 337 
     | 
    
         
            +
                rb_define_method(cIPPacket, "ip_hlen", ipp_hlen, 0);
         
     | 
| 
      
 338 
     | 
    
         
            +
                rb_define_method(cIPPacket, "ip_tos", ipp_tos, 0);
         
     | 
| 
      
 339 
     | 
    
         
            +
                rb_define_method(cIPPacket, "ip_len", ipp_len, 0);
         
     | 
| 
      
 340 
     | 
    
         
            +
                rb_define_method(cIPPacket, "ip_id", ipp_id, 0);
         
     | 
| 
      
 341 
     | 
    
         
            +
                rb_define_method(cIPPacket, "ip_flags", ipp_flags, 0);
         
     | 
| 
      
 342 
     | 
    
         
            +
                rb_define_method(cIPPacket, "ip_df?", ipp_df, 0);
         
     | 
| 
      
 343 
     | 
    
         
            +
                rb_define_method(cIPPacket, "ip_mf?", ipp_mf, 0);
         
     | 
| 
      
 344 
     | 
    
         
            +
                rb_define_method(cIPPacket, "ip_off", ipp_off, 0);
         
     | 
| 
      
 345 
     | 
    
         
            +
                rb_define_method(cIPPacket, "ip_ttl", ipp_ttl, 0);
         
     | 
| 
      
 346 
     | 
    
         
            +
                rb_define_method(cIPPacket, "ip_proto", ipp_proto, 0);
         
     | 
| 
      
 347 
     | 
    
         
            +
                rb_define_method(cIPPacket, "ip_sum", ipp_sum, 0);
         
     | 
| 
      
 348 
     | 
    
         
            +
                rb_define_method(cIPPacket, "ip_sumok?", ipp_sumok, 0);
         
     | 
| 
      
 349 
     | 
    
         
            +
                rb_define_method(cIPPacket, "ip_src", ipp_src, 0);
         
     | 
| 
      
 350 
     | 
    
         
            +
                rb_define_method(cIPPacket, "src", ipp_src, 0);
         
     | 
| 
      
 351 
     | 
    
         
            +
                rb_define_method(cIPPacket, "ip_src=", ipp_set_src, 1);
         
     | 
| 
      
 352 
     | 
    
         
            +
                rb_define_method(cIPPacket, "src=", ipp_set_src, 1);
         
     | 
| 
      
 353 
     | 
    
         
            +
                rb_define_method(cIPPacket, "ip_dst", ipp_dst, 0);
         
     | 
| 
      
 354 
     | 
    
         
            +
                rb_define_method(cIPPacket, "dst", ipp_dst, 0);
         
     | 
| 
      
 355 
     | 
    
         
            +
                rb_define_method(cIPPacket, "ip_dst=", ipp_set_dst, 1);
         
     | 
| 
      
 356 
     | 
    
         
            +
                rb_define_method(cIPPacket, "dst=", ipp_set_dst, 1);
         
     | 
| 
      
 357 
     | 
    
         
            +
                rb_define_method(cIPPacket, "ip_data", ipp_data, 0);
         
     | 
| 
      
 358 
     | 
    
         
            +
             
     | 
| 
      
 359 
     | 
    
         
            +
                cIPAddress = rb_define_class_under(mPcap, "IPAddress", rb_cObject);
         
     | 
| 
      
 360 
     | 
    
         
            +
                rb_define_singleton_method(cIPAddress, "new", ipaddr_s_new, 1);
         
     | 
| 
      
 361 
     | 
    
         
            +
                rb_define_method(cIPAddress, "to_i", ipaddr_to_i, 0);
         
     | 
| 
      
 362 
     | 
    
         
            +
                rb_define_method(cIPAddress, "to_s", ipaddr_to_s, 0);
         
     | 
| 
      
 363 
     | 
    
         
            +
                rb_define_method(cIPAddress, "num_s", ipaddr_num_s, 0);
         
     | 
| 
      
 364 
     | 
    
         
            +
                rb_define_method(cIPAddress, "to_num_s", ipaddr_num_s, 0); /* BWC */
         
     | 
| 
      
 365 
     | 
    
         
            +
                rb_define_method(cIPAddress, "hostname", ipaddr_hostname, 0);
         
     | 
| 
      
 366 
     | 
    
         
            +
                rb_define_method(cIPAddress, "sym_s", ipaddr_hostname, 0);
         
     | 
| 
      
 367 
     | 
    
         
            +
                rb_define_method(cIPAddress, "==", ipaddr_equal, 1);
         
     | 
| 
      
 368 
     | 
    
         
            +
                rb_define_method(cIPAddress, "===", ipaddr_equal, 1);
         
     | 
| 
      
 369 
     | 
    
         
            +
                rb_define_method(cIPAddress, "eql?", ipaddr_equal, 1);
         
     | 
| 
      
 370 
     | 
    
         
            +
                rb_define_method(cIPAddress, "hash", ipaddr_hash, 0);
         
     | 
| 
      
 371 
     | 
    
         
            +
             
     | 
| 
      
 372 
     | 
    
         
            +
                rb_define_method(cIPAddress, "_dump", ipaddr_dump, 1);
         
     | 
| 
      
 373 
     | 
    
         
            +
                rb_define_singleton_method(cIPAddress, "_load", ipaddr_s_load, 1);
         
     | 
| 
      
 374 
     | 
    
         
            +
             
     | 
| 
      
 375 
     | 
    
         
            +
                Init_tcp_packet();
         
     | 
| 
      
 376 
     | 
    
         
            +
                Init_udp_packet();
         
     | 
| 
      
 377 
     | 
    
         
            +
                Init_icmp_packet();
         
     | 
| 
      
 378 
     | 
    
         
            +
            }
         
     | 
    
        data/ext/packet.c
    ADDED
    
    | 
         @@ -0,0 +1,328 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            /*
         
     | 
| 
      
 2 
     | 
    
         
            +
             *  packet.c
         
     | 
| 
      
 3 
     | 
    
         
            +
             *
         
     | 
| 
      
 4 
     | 
    
         
            +
             *  $Id: packet.c,v 1.4 2000/08/13 06:56:15 fukusima Exp $
         
     | 
| 
      
 5 
     | 
    
         
            +
             *
         
     | 
| 
      
 6 
     | 
    
         
            +
             *  Copyright (C) 1998-2000  Masaki Fukushima
         
     | 
| 
      
 7 
     | 
    
         
            +
             */
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            #include "ruby.h"
         
     | 
| 
      
 10 
     | 
    
         
            +
            #include "ruby_pcap.h"
         
     | 
| 
      
 11 
     | 
    
         
            +
            #include <sys/socket.h>
         
     | 
| 
      
 12 
     | 
    
         
            +
            #include <net/if.h>
         
     | 
| 
      
 13 
     | 
    
         
            +
            #include <netinet/if_ether.h>
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            #define DL_HDR(pkt)     ((u_char *)LAYER2_HDR(pkt))
         
     | 
| 
      
 16 
     | 
    
         
            +
            #define DL_DATA(pkt)    ((u_char *)LAYER3_HDR(pkt))
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            VALUE cPacket;
         
     | 
| 
      
 19 
     | 
    
         
            +
            static VALUE mMarshal;
         
     | 
| 
      
 20 
     | 
    
         
            +
            int id_load;
         
     | 
| 
      
 21 
     | 
    
         
            +
            int id_dump;
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            /* called from GC */
         
     | 
| 
      
 24 
     | 
    
         
            +
            static void
         
     | 
| 
      
 25 
     | 
    
         
            +
            free_packet(pkt)
         
     | 
| 
      
 26 
     | 
    
         
            +
                 struct packet_object *pkt;
         
     | 
| 
      
 27 
     | 
    
         
            +
            {
         
     | 
| 
      
 28 
     | 
    
         
            +
                DEBUG_PRINT("free_packet");
         
     | 
| 
      
 29 
     | 
    
         
            +
                free(pkt);
         
     | 
| 
      
 30 
     | 
    
         
            +
            }
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
            /* called from GC */
         
     | 
| 
      
 33 
     | 
    
         
            +
            static void
         
     | 
| 
      
 34 
     | 
    
         
            +
            mark_packet(pkt)
         
     | 
| 
      
 35 
     | 
    
         
            +
                 struct packet_object *pkt;
         
     | 
| 
      
 36 
     | 
    
         
            +
            {
         
     | 
| 
      
 37 
     | 
    
         
            +
                DEBUG_PRINT("mark_packet");
         
     | 
| 
      
 38 
     | 
    
         
            +
                if (pkt->udata != Qnil)
         
     | 
| 
      
 39 
     | 
    
         
            +
                    rb_gc_mark(pkt->udata);
         
     | 
| 
      
 40 
     | 
    
         
            +
            }
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
            struct datalink_type {
         
     | 
| 
      
 43 
     | 
    
         
            +
                int nltype_off;     /* offset of network-layer type field */
         
     | 
| 
      
 44 
     | 
    
         
            +
                int nl_off;         /* offset of network-layer header */
         
     | 
| 
      
 45 
     | 
    
         
            +
            };
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
            static struct datalink_type datalinks[] = {
         
     | 
| 
      
 48 
     | 
    
         
            +
            #if 0
         
     | 
| 
      
 49 
     | 
    
         
            +
                {  0,  4 }, /*  0: DLT_NULL */
         
     | 
| 
      
 50 
     | 
    
         
            +
            #else
         
     | 
| 
      
 51 
     | 
    
         
            +
                { -1,  4 }, /*  0: DLT_NULL */
         
     | 
| 
      
 52 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 53 
     | 
    
         
            +
                { 12, 14 }, /*  1: DLT_EN10MB */
         
     | 
| 
      
 54 
     | 
    
         
            +
                { -1, -1 }, /*  2: DLT_EN3MB */
         
     | 
| 
      
 55 
     | 
    
         
            +
                { -1, -1 }, /*  3: DLT_AX25 */
         
     | 
| 
      
 56 
     | 
    
         
            +
                { -1, -1 }, /*  4: DLT_PRONET */
         
     | 
| 
      
 57 
     | 
    
         
            +
                { -1, -1 }, /*  5: DLT_CHAOS */
         
     | 
| 
      
 58 
     | 
    
         
            +
                { 20, 22 }, /*  6: DLT_IEEE802 */
         
     | 
| 
      
 59 
     | 
    
         
            +
                { -1, -1 }, /*  7: DLT_ARCNET */
         
     | 
| 
      
 60 
     | 
    
         
            +
                { -1, 16 }, /*  8: DLT_SLIP */
         
     | 
| 
      
 61 
     | 
    
         
            +
                {  2,  4 }, /*  9: DLT_PPP */
         
     | 
| 
      
 62 
     | 
    
         
            +
            #ifndef PCAP_FDDIPAD
         
     | 
| 
      
 63 
     | 
    
         
            +
                { 19, 21 }, /* 10: DLT_FDDI */
         
     | 
| 
      
 64 
     | 
    
         
            +
            #else
         
     | 
| 
      
 65 
     | 
    
         
            +
                { 19 + PCAP_FDDIPAD, 21 + PCAP_FDDIPAD },
         
     | 
| 
      
 66 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 67 
     | 
    
         
            +
                {  6,  8 }, /* 11: DLT_ATM_RFC1483 */
         
     | 
| 
      
 68 
     | 
    
         
            +
                { -1,  0 }, /* 12: DLT_RAW */
         
     | 
| 
      
 69 
     | 
    
         
            +
                { -1, 24 }, /* 13: DLT_SLIP_BSDOS */
         
     | 
| 
      
 70 
     | 
    
         
            +
                {  5, 24 }  /* 14: DLT_PPP_BSDOS */
         
     | 
| 
      
 71 
     | 
    
         
            +
            #define DATALINK_MAX 14
         
     | 
| 
      
 72 
     | 
    
         
            +
            };
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
            VALUE
         
     | 
| 
      
 75 
     | 
    
         
            +
            new_packet(data, pkthdr, dl_type)
         
     | 
| 
      
 76 
     | 
    
         
            +
                 const u_char *data;
         
     | 
| 
      
 77 
     | 
    
         
            +
                 const struct pcap_pkthdr *pkthdr;
         
     | 
| 
      
 78 
     | 
    
         
            +
                 int dl_type;
         
     | 
| 
      
 79 
     | 
    
         
            +
            {
         
     | 
| 
      
 80 
     | 
    
         
            +
                VALUE class;
         
     | 
| 
      
 81 
     | 
    
         
            +
                struct packet_object *pkt;
         
     | 
| 
      
 82 
     | 
    
         
            +
                int nl_off, nl_len, nltype_off, nl_type, pad;
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                DEBUG_PRINT("new_packet");
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
                /* check nework layer type and offset */
         
     | 
| 
      
 87 
     | 
    
         
            +
                if (dl_type > DATALINK_MAX) {
         
     | 
| 
      
 88 
     | 
    
         
            +
                    rb_raise(ePcapError, "Unknown data-link type (%d)", dl_type);
         
     | 
| 
      
 89 
     | 
    
         
            +
                }
         
     | 
| 
      
 90 
     | 
    
         
            +
                nltype_off  = datalinks[dl_type].nltype_off;
         
     | 
| 
      
 91 
     | 
    
         
            +
                nl_off      = datalinks[dl_type].nl_off;
         
     | 
| 
      
 92 
     | 
    
         
            +
                if (nl_off < 0) {
         
     | 
| 
      
 93 
     | 
    
         
            +
                    rb_raise(ePcapError, "Unsupported data-link type (%d)", dl_type);
         
     | 
| 
      
 94 
     | 
    
         
            +
                }
         
     | 
| 
      
 95 
     | 
    
         
            +
                if (nltype_off == -1) {
         
     | 
| 
      
 96 
     | 
    
         
            +
                    /* assume IP */
         
     | 
| 
      
 97 
     | 
    
         
            +
                    nl_type = ETHERTYPE_IP;
         
     | 
| 
      
 98 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 99 
     | 
    
         
            +
                    /* assume Ether Type value */
         
     | 
| 
      
 100 
     | 
    
         
            +
                    nl_type = ntohs(*(u_short *)(data + nltype_off));
         
     | 
| 
      
 101 
     | 
    
         
            +
                }
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
                /* alloc memory and setup packet_object */
         
     | 
| 
      
 104 
     | 
    
         
            +
                pad = nl_off % 4;   /* align network layer header */
         
     | 
| 
      
 105 
     | 
    
         
            +
                pkt = xmalloc(sizeof(*pkt) + pad + pkthdr->caplen);
         
     | 
| 
      
 106 
     | 
    
         
            +
                pkt->hdr.version    = PACKET_MARSHAL_VERSION;
         
     | 
| 
      
 107 
     | 
    
         
            +
                pkt->hdr.flags      = 0;
         
     | 
| 
      
 108 
     | 
    
         
            +
                pkt->hdr.dl_type    = dl_type;
         
     | 
| 
      
 109 
     | 
    
         
            +
                pkt->hdr.layer3_off = OFF_NONEXIST;
         
     | 
| 
      
 110 
     | 
    
         
            +
                pkt->hdr.layer4_off = OFF_NONEXIST;
         
     | 
| 
      
 111 
     | 
    
         
            +
                pkt->hdr.layer5_off = OFF_NONEXIST;
         
     | 
| 
      
 112 
     | 
    
         
            +
                pkt->hdr.pkthdr     = *pkthdr;
         
     | 
| 
      
 113 
     | 
    
         
            +
                pkt->data = (u_char *)pkt + sizeof(*pkt) + pad;
         
     | 
| 
      
 114 
     | 
    
         
            +
                pkt->udata = Qnil;
         
     | 
| 
      
 115 
     | 
    
         
            +
                memcpy(pkt->data, data, pkthdr->caplen);
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
                nl_len = pkthdr->caplen - nl_off;
         
     | 
| 
      
 118 
     | 
    
         
            +
                if (nl_off >= 0 && nl_len > 0)
         
     | 
| 
      
 119 
     | 
    
         
            +
                    pkt->hdr.layer3_off = nl_off;
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
                /* setup upper layer */
         
     | 
| 
      
 122 
     | 
    
         
            +
                class = cPacket;
         
     | 
| 
      
 123 
     | 
    
         
            +
                if (pkt->hdr.layer3_off != OFF_NONEXIST) {
         
     | 
| 
      
 124 
     | 
    
         
            +
                    switch (nl_type) {
         
     | 
| 
      
 125 
     | 
    
         
            +
                    case ETHERTYPE_IP:
         
     | 
| 
      
 126 
     | 
    
         
            +
                        class = setup_ip_packet(pkt, nl_len);
         
     | 
| 
      
 127 
     | 
    
         
            +
                        break;
         
     | 
| 
      
 128 
     | 
    
         
            +
                    }
         
     | 
| 
      
 129 
     | 
    
         
            +
                }
         
     | 
| 
      
 130 
     | 
    
         
            +
            #if DEBUG
         
     | 
| 
      
 131 
     | 
    
         
            +
                if (ruby_debug && TYPE(class) != T_CLASS) {
         
     | 
| 
      
 132 
     | 
    
         
            +
                    rb_fatal("not class");
         
     | 
| 
      
 133 
     | 
    
         
            +
                }
         
     | 
| 
      
 134 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 135 
     | 
    
         
            +
                return Data_Wrap_Struct(class, mark_packet, free_packet, pkt);
         
     | 
| 
      
 136 
     | 
    
         
            +
            }
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
      
 138 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 139 
     | 
    
         
            +
            packet_load(class, str)
         
     | 
| 
      
 140 
     | 
    
         
            +
                 VALUE class;
         
     | 
| 
      
 141 
     | 
    
         
            +
                 VALUE str;
         
     | 
| 
      
 142 
     | 
    
         
            +
            {
         
     | 
| 
      
 143 
     | 
    
         
            +
                struct packet_object *pkt = NULL;
         
     | 
| 
      
 144 
     | 
    
         
            +
                struct packet_object_header *hdr;
         
     | 
| 
      
 145 
     | 
    
         
            +
                int version;
         
     | 
| 
      
 146 
     | 
    
         
            +
                u_char *str_ptr;
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
                DEBUG_PRINT("packet_load");
         
     | 
| 
      
 149 
     | 
    
         
            +
             
     | 
| 
      
 150 
     | 
    
         
            +
                str_ptr = RSTRING(str)->ptr;
         
     | 
| 
      
 151 
     | 
    
         
            +
                hdr = (struct packet_object_header *)str_ptr;
         
     | 
| 
      
 152 
     | 
    
         
            +
                version = hdr->version;
         
     | 
| 
      
 153 
     | 
    
         
            +
                if (version == PACKET_MARSHAL_VERSION) {
         
     | 
| 
      
 154 
     | 
    
         
            +
                    bpf_u_int32 caplen;
         
     | 
| 
      
 155 
     | 
    
         
            +
                    u_short layer3_off;
         
     | 
| 
      
 156 
     | 
    
         
            +
                    int pad;
         
     | 
| 
      
 157 
     | 
    
         
            +
             
     | 
| 
      
 158 
     | 
    
         
            +
                    caplen = ntohl(hdr->pkthdr.caplen);
         
     | 
| 
      
 159 
     | 
    
         
            +
                    layer3_off = ntohs(hdr->layer3_off);
         
     | 
| 
      
 160 
     | 
    
         
            +
                    pad = layer3_off % 4;   /* align network layer header */
         
     | 
| 
      
 161 
     | 
    
         
            +
                    pkt = (struct packet_object *)xmalloc(sizeof(*pkt) + pad + caplen);
         
     | 
| 
      
 162 
     | 
    
         
            +
             
     | 
| 
      
 163 
     | 
    
         
            +
                    pkt->hdr.version                = PACKET_MARSHAL_VERSION;
         
     | 
| 
      
 164 
     | 
    
         
            +
                    pkt->hdr.flags                  = hdr->flags;
         
     | 
| 
      
 165 
     | 
    
         
            +
                    pkt->hdr.dl_type                = hdr->dl_type;
         
     | 
| 
      
 166 
     | 
    
         
            +
                    pkt->hdr.layer3_off             = ntohs(hdr->layer3_off);
         
     | 
| 
      
 167 
     | 
    
         
            +
                    pkt->hdr.layer4_off             = ntohs(hdr->layer4_off);
         
     | 
| 
      
 168 
     | 
    
         
            +
                    pkt->hdr.layer5_off             = ntohs(hdr->layer5_off);
         
     | 
| 
      
 169 
     | 
    
         
            +
                    pkt->hdr.pkthdr.ts.tv_sec       = ntohl(hdr->pkthdr.ts.tv_sec);
         
     | 
| 
      
 170 
     | 
    
         
            +
                    pkt->hdr.pkthdr.ts.tv_usec      = ntohl(hdr->pkthdr.ts.tv_usec);
         
     | 
| 
      
 171 
     | 
    
         
            +
                    pkt->hdr.pkthdr.caplen          = ntohl(hdr->pkthdr.caplen);
         
     | 
| 
      
 172 
     | 
    
         
            +
                    pkt->hdr.pkthdr.len             = ntohl(hdr->pkthdr.len);
         
     | 
| 
      
 173 
     | 
    
         
            +
             
     | 
| 
      
 174 
     | 
    
         
            +
                    pkt->data = (u_char *)pkt + sizeof(*pkt) + pad;
         
     | 
| 
      
 175 
     | 
    
         
            +
                    memcpy(pkt->data, str_ptr + sizeof(*hdr), caplen);
         
     | 
| 
      
 176 
     | 
    
         
            +
                    if (PKTFLAG_TEST(pkt, POH_UDATA)) {
         
     | 
| 
      
 177 
     | 
    
         
            +
                        int l = sizeof(*hdr) + caplen;
         
     | 
| 
      
 178 
     | 
    
         
            +
                        VALUE ustr = rb_str_substr(str, l, RSTRING(str)->len - l);
         
     | 
| 
      
 179 
     | 
    
         
            +
                        pkt->udata = rb_funcall(mMarshal, id_load, 1, ustr);
         
     | 
| 
      
 180 
     | 
    
         
            +
                    } else {
         
     | 
| 
      
 181 
     | 
    
         
            +
                        pkt->udata = Qnil;
         
     | 
| 
      
 182 
     | 
    
         
            +
                    }
         
     | 
| 
      
 183 
     | 
    
         
            +
                    PKTFLAG_SET(pkt, POH_UDATA, (pkt->udata != Qnil));
         
     | 
| 
      
 184 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 185 
     | 
    
         
            +
                    rb_raise(rb_eArgError, "unknown packet marshal version(0x%x)", version);
         
     | 
| 
      
 186 
     | 
    
         
            +
                }
         
     | 
| 
      
 187 
     | 
    
         
            +
             
     | 
| 
      
 188 
     | 
    
         
            +
                if (pkt != NULL)
         
     | 
| 
      
 189 
     | 
    
         
            +
                    return Data_Wrap_Struct(class, mark_packet, free_packet, pkt);
         
     | 
| 
      
 190 
     | 
    
         
            +
                else
         
     | 
| 
      
 191 
     | 
    
         
            +
                    return Qnil;
         
     | 
| 
      
 192 
     | 
    
         
            +
            }
         
     | 
| 
      
 193 
     | 
    
         
            +
             
     | 
| 
      
 194 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 195 
     | 
    
         
            +
            packet_dump(self, limit)
         
     | 
| 
      
 196 
     | 
    
         
            +
                 VALUE self;
         
     | 
| 
      
 197 
     | 
    
         
            +
                 VALUE limit;
         
     | 
| 
      
 198 
     | 
    
         
            +
            {
         
     | 
| 
      
 199 
     | 
    
         
            +
                struct packet_object *pkt;
         
     | 
| 
      
 200 
     | 
    
         
            +
                struct packet_object_header hdr;
         
     | 
| 
      
 201 
     | 
    
         
            +
                VALUE str;
         
     | 
| 
      
 202 
     | 
    
         
            +
             
     | 
| 
      
 203 
     | 
    
         
            +
                DEBUG_PRINT("packet_dump");
         
     | 
| 
      
 204 
     | 
    
         
            +
                GetPacket(self, pkt);
         
     | 
| 
      
 205 
     | 
    
         
            +
             
     | 
| 
      
 206 
     | 
    
         
            +
                hdr.version                 = PACKET_MARSHAL_VERSION;
         
     | 
| 
      
 207 
     | 
    
         
            +
                hdr.flags                   = pkt->hdr.flags;
         
     | 
| 
      
 208 
     | 
    
         
            +
                hdr.dl_type                 = pkt->hdr.dl_type;
         
     | 
| 
      
 209 
     | 
    
         
            +
                hdr.layer3_off              = htons(pkt->hdr.layer3_off);
         
     | 
| 
      
 210 
     | 
    
         
            +
                hdr.layer4_off              = htons(pkt->hdr.layer4_off);
         
     | 
| 
      
 211 
     | 
    
         
            +
                hdr.layer5_off              = htons(pkt->hdr.layer5_off);
         
     | 
| 
      
 212 
     | 
    
         
            +
                hdr.pkthdr.ts.tv_sec        = htonl(pkt->hdr.pkthdr.ts.tv_sec);
         
     | 
| 
      
 213 
     | 
    
         
            +
                hdr.pkthdr.ts.tv_usec       = htonl(pkt->hdr.pkthdr.ts.tv_usec);
         
     | 
| 
      
 214 
     | 
    
         
            +
                hdr.pkthdr.caplen           = htonl(pkt->hdr.pkthdr.caplen);
         
     | 
| 
      
 215 
     | 
    
         
            +
                hdr.pkthdr.len              = htonl(pkt->hdr.pkthdr.len);
         
     | 
| 
      
 216 
     | 
    
         
            +
             
     | 
| 
      
 217 
     | 
    
         
            +
                str = rb_str_new((char *)&hdr, sizeof(hdr));
         
     | 
| 
      
 218 
     | 
    
         
            +
                rb_str_cat(str, pkt->data, pkt->hdr.pkthdr.caplen);
         
     | 
| 
      
 219 
     | 
    
         
            +
                if (pkt->udata != Qnil) {
         
     | 
| 
      
 220 
     | 
    
         
            +
                    VALUE ustr;
         
     | 
| 
      
 221 
     | 
    
         
            +
                    ustr = rb_funcall(mMarshal, id_dump, 1, pkt->udata);
         
     | 
| 
      
 222 
     | 
    
         
            +
                    rb_str_concat(str, ustr);
         
     | 
| 
      
 223 
     | 
    
         
            +
                }
         
     | 
| 
      
 224 
     | 
    
         
            +
                return str;
         
     | 
| 
      
 225 
     | 
    
         
            +
            }
         
     | 
| 
      
 226 
     | 
    
         
            +
             
     | 
| 
      
 227 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 228 
     | 
    
         
            +
            packet_set_udata(self, val)
         
     | 
| 
      
 229 
     | 
    
         
            +
                 VALUE self;
         
     | 
| 
      
 230 
     | 
    
         
            +
                 VALUE val;
         
     | 
| 
      
 231 
     | 
    
         
            +
            {
         
     | 
| 
      
 232 
     | 
    
         
            +
                struct packet_object *pkt;
         
     | 
| 
      
 233 
     | 
    
         
            +
             
     | 
| 
      
 234 
     | 
    
         
            +
                DEBUG_PRINT("packet_set_udata");
         
     | 
| 
      
 235 
     | 
    
         
            +
                GetPacket(self, pkt);
         
     | 
| 
      
 236 
     | 
    
         
            +
             
     | 
| 
      
 237 
     | 
    
         
            +
                pkt->udata = val;
         
     | 
| 
      
 238 
     | 
    
         
            +
                PKTFLAG_SET(pkt, POH_UDATA, (val != Qnil));
         
     | 
| 
      
 239 
     | 
    
         
            +
                return val;
         
     | 
| 
      
 240 
     | 
    
         
            +
            }
         
     | 
| 
      
 241 
     | 
    
         
            +
             
     | 
| 
      
 242 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 243 
     | 
    
         
            +
            packet_set_time_i(self, val)
         
     | 
| 
      
 244 
     | 
    
         
            +
                 VALUE self;
         
     | 
| 
      
 245 
     | 
    
         
            +
                 VALUE val;
         
     | 
| 
      
 246 
     | 
    
         
            +
            {
         
     | 
| 
      
 247 
     | 
    
         
            +
                 struct packet_object *pkt;
         
     | 
| 
      
 248 
     | 
    
         
            +
                 unsigned int time_i;
         
     | 
| 
      
 249 
     | 
    
         
            +
             
     | 
| 
      
 250 
     | 
    
         
            +
                 DEBUG_PRINT("packet_set_time_i");
         
     | 
| 
      
 251 
     | 
    
         
            +
                 GetPacket(self, pkt);
         
     | 
| 
      
 252 
     | 
    
         
            +
                 Check_Type(val, T_BIGNUM);
         
     | 
| 
      
 253 
     | 
    
         
            +
                 time_i = NUM2UINT(val);
         
     | 
| 
      
 254 
     | 
    
         
            +
             
     | 
| 
      
 255 
     | 
    
         
            +
                 pkt->hdr.pkthdr.ts.tv_sec = time_i;
         
     | 
| 
      
 256 
     | 
    
         
            +
                 return val;
         
     | 
| 
      
 257 
     | 
    
         
            +
            }
         
     | 
| 
      
 258 
     | 
    
         
            +
             
     | 
| 
      
 259 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 260 
     | 
    
         
            +
            packet_match(self, expr)
         
     | 
| 
      
 261 
     | 
    
         
            +
                 VALUE self;
         
     | 
| 
      
 262 
     | 
    
         
            +
                 VALUE expr;
         
     | 
| 
      
 263 
     | 
    
         
            +
            {
         
     | 
| 
      
 264 
     | 
    
         
            +
                if (IsKindOf(expr, cFilter)) {
         
     | 
| 
      
 265 
     | 
    
         
            +
                    return filter_match(expr, self);
         
     | 
| 
      
 266 
     | 
    
         
            +
                }
         
     | 
| 
      
 267 
     | 
    
         
            +
                rb_raise(rb_eArgError, "Not Filter");
         
     | 
| 
      
 268 
     | 
    
         
            +
            }
         
     | 
| 
      
 269 
     | 
    
         
            +
             
     | 
| 
      
 270 
     | 
    
         
            +
            #define PACKET_METHOD(func, val) \
         
     | 
| 
      
 271 
     | 
    
         
            +
            static VALUE\
         
     | 
| 
      
 272 
     | 
    
         
            +
            (func)(self)\
         
     | 
| 
      
 273 
     | 
    
         
            +
                 VALUE self;\
         
     | 
| 
      
 274 
     | 
    
         
            +
            {\
         
     | 
| 
      
 275 
     | 
    
         
            +
                struct packet_object *pkt;\
         
     | 
| 
      
 276 
     | 
    
         
            +
            \
         
     | 
| 
      
 277 
     | 
    
         
            +
                DEBUG_PRINT(#func);\
         
     | 
| 
      
 278 
     | 
    
         
            +
                GetPacket(self, pkt);\
         
     | 
| 
      
 279 
     | 
    
         
            +
                return (val);\
         
     | 
| 
      
 280 
     | 
    
         
            +
            }
         
     | 
| 
      
 281 
     | 
    
         
            +
             
     | 
| 
      
 282 
     | 
    
         
            +
            PACKET_METHOD(packet_get_udata, pkt->udata);
         
     | 
| 
      
 283 
     | 
    
         
            +
            PACKET_METHOD(packet_datalink, INT2FIX(pkt->hdr.dl_type));
         
     | 
| 
      
 284 
     | 
    
         
            +
            PACKET_METHOD(packet_ip, rb_obj_is_kind_of(self, cIPPacket));
         
     | 
| 
      
 285 
     | 
    
         
            +
            PACKET_METHOD(packet_tcp, rb_obj_is_kind_of(self, cTCPPacket));
         
     | 
| 
      
 286 
     | 
    
         
            +
            PACKET_METHOD(packet_udp, rb_obj_is_kind_of(self, cUDPPacket));
         
     | 
| 
      
 287 
     | 
    
         
            +
            PACKET_METHOD(packet_length, UINT32_2_NUM(pkt->hdr.pkthdr.len));
         
     | 
| 
      
 288 
     | 
    
         
            +
            PACKET_METHOD(packet_caplen, UINT32_2_NUM(pkt->hdr.pkthdr.caplen));
         
     | 
| 
      
 289 
     | 
    
         
            +
            PACKET_METHOD(packet_time, rb_time_new(pkt->hdr.pkthdr.ts.tv_sec,
         
     | 
| 
      
 290 
     | 
    
         
            +
                                                   pkt->hdr.pkthdr.ts.tv_usec));
         
     | 
| 
      
 291 
     | 
    
         
            +
            PACKET_METHOD(packet_time_i, rb_int2inum(pkt->hdr.pkthdr.ts.tv_sec));
         
     | 
| 
      
 292 
     | 
    
         
            +
            PACKET_METHOD(packet_raw_data, rb_str_new(pkt->data, pkt->hdr.pkthdr.caplen));
         
     | 
| 
      
 293 
     | 
    
         
            +
             
     | 
| 
      
 294 
     | 
    
         
            +
            void
         
     | 
| 
      
 295 
     | 
    
         
            +
            Init_packet(void)
         
     | 
| 
      
 296 
     | 
    
         
            +
            {
         
     | 
| 
      
 297 
     | 
    
         
            +
                DEBUG_PRINT("Init_packet");
         
     | 
| 
      
 298 
     | 
    
         
            +
             
     | 
| 
      
 299 
     | 
    
         
            +
                /* define class Packet */
         
     | 
| 
      
 300 
     | 
    
         
            +
                cPacket = rb_define_class_under(mPcap, "Packet", rb_cObject);
         
     | 
| 
      
 301 
     | 
    
         
            +
             
     | 
| 
      
 302 
     | 
    
         
            +
                rb_define_singleton_method(cPacket, "_load", packet_load, 1);
         
     | 
| 
      
 303 
     | 
    
         
            +
                rb_define_method(cPacket, "_dump", packet_dump, 1);
         
     | 
| 
      
 304 
     | 
    
         
            +
                /* marshal backward compatibility */
         
     | 
| 
      
 305 
     | 
    
         
            +
                rb_define_singleton_method(cPacket, "_load_from", packet_load, 1);
         
     | 
| 
      
 306 
     | 
    
         
            +
                rb_define_method(cPacket, "_dump_to", packet_dump, 1);
         
     | 
| 
      
 307 
     | 
    
         
            +
             
     | 
| 
      
 308 
     | 
    
         
            +
                rb_define_method(cPacket, "udata", packet_get_udata, 0);
         
     | 
| 
      
 309 
     | 
    
         
            +
                rb_define_method(cPacket, "udata=", packet_set_udata, 1);
         
     | 
| 
      
 310 
     | 
    
         
            +
                rb_define_method(cPacket, "datalink", packet_datalink, 0);
         
     | 
| 
      
 311 
     | 
    
         
            +
                rb_define_method(cPacket, "ip?", packet_ip, 0);
         
     | 
| 
      
 312 
     | 
    
         
            +
                rb_define_method(cPacket, "tcp?", packet_tcp, 0);
         
     | 
| 
      
 313 
     | 
    
         
            +
                rb_define_method(cPacket, "udp?", packet_udp, 0);
         
     | 
| 
      
 314 
     | 
    
         
            +
                rb_define_method(cPacket, "length", packet_length, 0);
         
     | 
| 
      
 315 
     | 
    
         
            +
                rb_define_method(cPacket, "size", packet_length, 0);
         
     | 
| 
      
 316 
     | 
    
         
            +
                rb_define_method(cPacket, "caplen", packet_caplen, 0);
         
     | 
| 
      
 317 
     | 
    
         
            +
                rb_define_method(cPacket, "time", packet_time, 0);
         
     | 
| 
      
 318 
     | 
    
         
            +
                rb_define_method(cPacket, "time_i", packet_time_i, 0);
         
     | 
| 
      
 319 
     | 
    
         
            +
                rb_define_method(cPacket, "time_i=", packet_set_time_i, 1);
         
     | 
| 
      
 320 
     | 
    
         
            +
                rb_define_method(cPacket, "raw_data", packet_raw_data, 0);
         
     | 
| 
      
 321 
     | 
    
         
            +
                rb_define_method(cPacket, "=~", packet_match, 1);
         
     | 
| 
      
 322 
     | 
    
         
            +
             
     | 
| 
      
 323 
     | 
    
         
            +
                /* mMarshal in ruby/marshal.c is static. Why? */
         
     | 
| 
      
 324 
     | 
    
         
            +
                mMarshal = rb_eval_string("Marshal");
         
     | 
| 
      
 325 
     | 
    
         
            +
                id_load = rb_intern("load");
         
     | 
| 
      
 326 
     | 
    
         
            +
                id_dump = rb_intern("dump");
         
     | 
| 
      
 327 
     | 
    
         
            +
                Init_ip_packet();
         
     | 
| 
      
 328 
     | 
    
         
            +
            }
         
     |