ruby-pcap 0.7.9 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,162 @@
1
+ /*
2
+ * ipv6_packet.c
3
+ */
4
+
5
+ #include "ruby_pcap.h"
6
+
7
+ VALUE cIPv6Packet;
8
+
9
+ #define CheckTruncateIpv6(pkt, need) CheckTruncate(pkt, pkt->hdr.layer3_off, need, "truncated IPv6")
10
+ #define IPV6_HL 40
11
+
12
+ VALUE
13
+ setup_ipv6_packet(pkt, nl_len)
14
+ struct packet_object *pkt;
15
+ int nl_len;
16
+ {
17
+ VALUE class;
18
+
19
+ class = cIPv6Packet;
20
+ pkt->hdr.layer4_off = pkt->hdr.layer3_off + IPV6_HL;
21
+ switch (IPV6_HDR(pkt)->ip6_nxt) {
22
+ case IPPROTO_TCP:
23
+ DEBUG_PRINT("setup_tcpv6_packet");
24
+ class = setup_tcpv6_packet(pkt, nl_len - IPV6_HL);
25
+ break;
26
+ case IPPROTO_UDP:
27
+ DEBUG_PRINT("setup_udpv6_packet");
28
+ class = setup_udpv6_packet(pkt, nl_len - IPV6_HL);
29
+ break;
30
+ case IPPROTO_ICMPV6:
31
+ DEBUG_PRINT("setup_icmpv6_packet");
32
+ class = setup_icmpv6_packet(pkt);
33
+ break;
34
+ }
35
+ return class;
36
+ }
37
+
38
+ #define IPV6P_METHOD(func, val) \
39
+ static VALUE\
40
+ (func)(self)\
41
+ VALUE self;\
42
+ {\
43
+ struct ip6_hdr *ip;\
44
+ \
45
+ DEBUG_PRINT(#func);\
46
+ ip = IPV6_HDR_OBJ(self);\
47
+ return (val);\
48
+ }
49
+
50
+ IPV6P_METHOD(ipp_ver, INT2FIX(ip->ip6_vfc >> 4))
51
+ /*
52
+ The bits of this field hold two values.
53
+ The six most-significant bits hold the Differentiated Services (DS) field, which is used to classify packets.
54
+ Currently, all standard DS fields end with a '0' bit. Any DS field that ends with two '1' bits is intended for local or experimental use.[4]
55
+ The remaining two bits are used for Explicit Congestion Notification (ECN);
56
+ priority values subdivide into ranges: traffic where the source provides congestion control and non-congestion control traffic.
57
+ */
58
+ IPV6P_METHOD(ipp_tc, INT2FIX((ntohl(ip->ip6_flow) & 0x0FF00000) >> 20))
59
+ IPV6P_METHOD(ipp_ds, INT2FIX((ntohl(ip->ip6_flow) & 0x0FF00000) >> 22))
60
+ IPV6P_METHOD(ipp_ecn, INT2FIX((ntohl(ip->ip6_flow) & 0x00300000) >> 20))
61
+ IPV6P_METHOD(ipp_fl, INT2FIX(ntohl(ip->ip6_flow) & 0x000FFFFF))
62
+ IPV6P_METHOD(ipp_pl, INT2FIX(ntohs(ip->ip6_plen)))
63
+ IPV6P_METHOD(ipp_nh, INT2FIX(ip->ip6_nxt))
64
+ IPV6P_METHOD(ipp_hl, INT2FIX(ip->ip6_hlim))
65
+
66
+
67
+ static VALUE
68
+ ipp_truncated(self)
69
+ VALUE self;
70
+ {
71
+ struct packet_object *pkt;
72
+ struct ip6_hdr *ip;
73
+ GetPacket(self, pkt);
74
+ ip = IPV6_HDR(pkt);
75
+ if IsTruncated(pkt, pkt->hdr.layer3_off, ntohs(ip->ip6_plen))
76
+ return Qtrue;
77
+ return Qfalse;
78
+ }
79
+
80
+ static VALUE
81
+ ipp_data(self)
82
+ VALUE self;
83
+ {
84
+ struct packet_object *pkt;
85
+ struct ip6_hdr *ip;
86
+ int len;
87
+
88
+ GetPacket(self, pkt);
89
+ ip = IPV6_HDR(pkt);
90
+ CheckTruncateIpv6(pkt, 20);
91
+ len = pkt->hdr.pkthdr.caplen - pkt->hdr.layer3_off - IPV6_HL;
92
+ return rb_str_new((u_char *)ip + IPV6_HL, len);
93
+ }
94
+
95
+ /*
96
+ * IPv6Address
97
+ */
98
+
99
+ static VALUE
100
+ ipp_src_i(self)
101
+ VALUE self;
102
+ {
103
+ struct ip6_hdr *ip;
104
+ ip = (struct ip6_hdr *)IPV6_HDR_OBJ(self);
105
+ return rb_integer_unpack(ip->ip6_src.s6_addr, 16, 1, 0, INTEGER_PACK_BIG_ENDIAN);
106
+ }
107
+
108
+ static VALUE
109
+ ipp_src_s(self)
110
+ VALUE self;
111
+ {
112
+ struct ip6_hdr *ip;
113
+ char buff[INET6_ADDRSTRLEN];
114
+ ip = (struct ip6_hdr *)IPV6_HDR_OBJ(self);
115
+
116
+ inet_ntop(AF_INET6, ip->ip6_src.s6_addr, buff, INET6_ADDRSTRLEN);
117
+ return rb_str_new2(buff);
118
+ }
119
+
120
+ static VALUE
121
+ ipp_dst_i(self)
122
+ VALUE self;
123
+ {
124
+ struct ip6_hdr *ip;
125
+ ip = IPV6_HDR_OBJ(self);
126
+ return rb_integer_unpack(ip->ip6_dst.s6_addr, 16, 1, 0, INTEGER_PACK_BIG_ENDIAN);
127
+ }
128
+
129
+ static VALUE
130
+ ipp_dst_s(self)
131
+ VALUE self;
132
+ {
133
+ char buff[INET6_ADDRSTRLEN];
134
+ struct ip6_hdr *ip;
135
+ ip = IPV6_HDR_OBJ(self);
136
+
137
+ inet_ntop(AF_INET6, ip->ip6_dst.s6_addr, buff, INET6_ADDRSTRLEN);
138
+ return rb_str_new2(buff);
139
+ }
140
+
141
+ void
142
+ Init_ipv6_packet(void)
143
+ {
144
+ DEBUG_PRINT("Init_ipv6_packet");
145
+
146
+ cIPv6Packet = rb_define_class_under(mPcap, "IPv6Packet", cPacket);
147
+
148
+ rb_define_method(cIPv6Packet, "ip_ver", ipp_ver, 0);
149
+ rb_define_method(cIPv6Packet, "ip_tc", ipp_tc, 0);
150
+ rb_define_method(cIPv6Packet, "ip_ds", ipp_ds, 0);
151
+ rb_define_method(cIPv6Packet, "ip_ecn", ipp_ecn, 0);
152
+ rb_define_method(cIPv6Packet, "ip_fl", ipp_fl, 0); /* IPv6 flow label */
153
+ rb_define_method(cIPv6Packet, "ip_pl", ipp_pl, 0); /* IPv6 Payload length */
154
+ rb_define_method(cIPv6Packet, "ip_nh", ipp_nh, 0); /* IPv6 Next header */
155
+ rb_define_method(cIPv6Packet, "ip_hl", ipp_hl, 0); /* IPv6 Hop limit */
156
+ rb_define_method(cIPv6Packet, "src_s", ipp_src_s, 0);
157
+ rb_define_method(cIPv6Packet, "dst_s", ipp_dst_s, 0);
158
+ rb_define_method(cIPv6Packet, "src_i", ipp_src_i, 0);
159
+ rb_define_method(cIPv6Packet, "dst_i", ipp_dst_i, 0);
160
+ rb_define_method(cIPv6Packet, "ip_data", ipp_data, 0);
161
+ rb_define_method(cIPv6Packet, "ip_truncated?", ipp_truncated, 0);
162
+ }
data/ext/pcap/packet.c CHANGED
@@ -11,7 +11,17 @@
11
11
  #include <sys/socket.h>
12
12
  #include <net/if.h>
13
13
  #include <netinet/if_ether.h>
14
+ #ifndef ETH_P_IPV6
15
+ #define ETH_P_IPV6 0x86DD /* IPv6 packet */
16
+ #endif
17
+
18
+ #ifndef ETH_P_SLOW
19
+ #define ETH_P_SLOW 0x8809 /* Slow Protocol frame */
20
+ #endif
14
21
 
22
+ #ifndef ETH_P_ARP
23
+ #define ETH_P_ARP 0x0806 /* Address Resolution packet */
24
+ #endif
15
25
  #define DL_HDR(pkt) ((u_char *)LAYER2_HDR(pkt))
16
26
  #define DL_DATA(pkt) ((u_char *)LAYER3_HDR(pkt))
17
27
 
@@ -125,14 +135,18 @@ new_packet(data, pkthdr, dl_type)
125
135
  case ETHERTYPE_IP:
126
136
  class = setup_ip_packet(pkt, nl_len);
127
137
  break;
138
+ case ETH_P_IPV6:
139
+ class = setup_ipv6_packet(pkt, nl_len);
140
+ break;
141
+ case ETH_P_ARP:
142
+ class = setup_arp_packet(pkt, nl_len);
143
+ break;
144
+ case ETH_P_SLOW:
145
+ class = setup_slow_protocol_packet(pkt, nl_len);
146
+ break;
128
147
  }
129
148
  }
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);
149
+ return Data_Wrap_Struct(class, mark_packet, free_packet, pkt);
136
150
  }
137
151
 
138
152
  static VALUE
@@ -282,14 +296,18 @@ static VALUE\
282
296
  PACKET_METHOD(packet_get_udata, pkt->udata);
283
297
  PACKET_METHOD(packet_datalink, INT2FIX(pkt->hdr.dl_type));
284
298
  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));
299
+ PACKET_METHOD(packet_ipv6, rb_obj_is_kind_of(self, cIPv6Packet));
300
+ PACKET_METHOD(packet_tcp, rb_obj_is_kind_of(self, cTCPPacket) | rb_obj_is_kind_of(self, cTCPv6Packet));
301
+ PACKET_METHOD(packet_udp, rb_obj_is_kind_of(self, cUDPPacket) | rb_obj_is_kind_of(self, cUDPv6Packet));
287
302
  PACKET_METHOD(packet_length, UINT32_2_NUM(pkt->hdr.pkthdr.len));
288
303
  PACKET_METHOD(packet_caplen, UINT32_2_NUM(pkt->hdr.pkthdr.caplen));
289
304
  PACKET_METHOD(packet_time, rb_time_new(pkt->hdr.pkthdr.ts.tv_sec,
290
305
  pkt->hdr.pkthdr.ts.tv_usec));
291
306
  PACKET_METHOD(packet_time_i, rb_int2inum(pkt->hdr.pkthdr.ts.tv_sec));
292
307
  PACKET_METHOD(packet_raw_data, rb_str_new(pkt->data, pkt->hdr.pkthdr.caplen));
308
+ PACKET_METHOD(packet_arp, rb_obj_is_kind_of(self, cARPPacket));
309
+ PACKET_METHOD(packet_lacp, rb_obj_is_kind_of(self, cLACPPacket));
310
+
293
311
 
294
312
  void
295
313
  Init_packet(void)
@@ -308,9 +326,12 @@ Init_packet(void)
308
326
  rb_define_method(cPacket, "udata", packet_get_udata, 0);
309
327
  rb_define_method(cPacket, "udata=", packet_set_udata, 1);
310
328
  rb_define_method(cPacket, "datalink", packet_datalink, 0);
329
+ rb_define_method(cPacket, "arp?", packet_arp, 0);
311
330
  rb_define_method(cPacket, "ip?", packet_ip, 0);
331
+ rb_define_method(cPacket, "ipv6?", packet_ipv6, 0);
312
332
  rb_define_method(cPacket, "tcp?", packet_tcp, 0);
313
333
  rb_define_method(cPacket, "udp?", packet_udp, 0);
334
+ rb_define_method(cPacket, "lacp?", packet_lacp, 0);
314
335
  rb_define_method(cPacket, "length", packet_length, 0);
315
336
  rb_define_method(cPacket, "size", packet_length, 0);
316
337
  rb_define_method(cPacket, "caplen", packet_caplen, 0);
@@ -325,4 +346,11 @@ Init_packet(void)
325
346
  id_load = rb_intern("load");
326
347
  id_dump = rb_intern("dump");
327
348
  Init_ip_packet();
349
+ Init_arp_packet();
350
+ Init_ipv6_packet();
351
+ Init_tcp_packet();
352
+ Init_udp_packet();
353
+ Init_icmp_packet();
354
+ Init_icmpv6_packet();
355
+ Init_sp_packet();
328
356
  }
data/ext/pcap/ruby_pcap.h CHANGED
@@ -15,6 +15,8 @@
15
15
  #include <netinet/in.h>
16
16
  #include <netinet/in_systm.h>
17
17
  #include <netinet/ip.h>
18
+ #include <netinet/ip6.h>
19
+ #include <netinet/icmp6.h>
18
20
  #include <arpa/inet.h>
19
21
  #ifndef IP_OFFMASK
20
22
  # define IP_OFFMASK 0x1fff
@@ -29,10 +31,7 @@
29
31
  #include <netdb.h>
30
32
 
31
33
  #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)
34
+ # define DEBUG_PRINT(x) fprintf(stderr, "%s\n", x),fflush(stderr)
36
35
  #else
37
36
  # define DEBUG_PRINT(x) do {} while (0)
38
37
  #endif
@@ -89,11 +88,16 @@ struct packet_object {
89
88
  rb_raise(eTruncatedPacket, (emsg)) : 0 \
90
89
  )
91
90
 
91
+ #define IsTruncated(pkt, from, need) (\
92
+ (from) + (need) > (pkt)->hdr.pkthdr.caplen ? \
93
+ 1 : 0 \
94
+ )
92
95
  #define IsKindOf(v, class) RTEST(rb_obj_is_kind_of(v, class))
93
96
  #define CheckClass(v, class) ((IsKindOf(v, class)) ? 0 :\
94
97
  rb_raise(rb_eTypeError, "wrong type %s (expected %s)",\
95
98
  rb_class2name(CLASS_OF(v)), rb_class2name(class)))
96
99
 
100
+ #define DEBUG_CHECKSUM 0
97
101
 
98
102
  /* Pcap.c */
99
103
  extern VALUE mPcap, rbpcap_convert;
@@ -118,17 +122,43 @@ VALUE new_ipaddr(struct in_addr *);
118
122
 
119
123
  /* tcp_packet.c */
120
124
  extern VALUE cTCPPacket;
125
+ extern VALUE cTCPv6Packet;
121
126
  void Init_tcp_packet(void);
122
127
  VALUE setup_tcp_packet(struct packet_object *, int);
128
+ VALUE setup_tcpv6_packet(struct packet_object *, int);
129
+
130
+ /* ipv6_packet.c */
131
+ #define IPV6_HDR(pkt) ((struct ip6_hdr *)LAYER3_HDR(pkt))
132
+ #define IPV6_HDR_OBJ(self) ((struct ip6_hdr *)LAYER3_HDR((struct packet_object *)DATA_PTR(self)))
133
+ extern VALUE cIPv6Packet;
134
+ void Init_ipv6_packet(void);
135
+ VALUE setup_ipv6_packet(struct packet_object *, int);
123
136
 
124
137
  /* udp_packet.c */
125
138
  extern VALUE cUDPPacket;
139
+ extern VALUE cUDPv6Packet;
126
140
  void Init_udp_packet(void);
127
141
  VALUE setup_udp_packet(struct packet_object *, int);
142
+ VALUE setup_udpv6_packet(struct packet_object *, int);
128
143
 
129
144
  /* icmp_packet.c */
130
145
  extern VALUE cICMPPacket;
146
+ extern VALUE cICMPv6Packet;
131
147
  void Init_icmp_packet(void);
148
+ void Init_icmpv6_packet(void);
132
149
  VALUE setup_icmp_packet(struct packet_object *, int);
150
+ VALUE setup_icmpv6_packet(struct packet_object *);
133
151
 
152
+
153
+ /* arp_packet.c */
154
+ extern VALUE cARPPacket;
155
+ void Init_arp_packet(void);
156
+ VALUE setup_arp_packet(struct packet_object *, int);
157
+
158
+ /* slow_protocol_packet.c */
159
+ extern VALUE cSPPacket;
160
+ extern VALUE cLACPPacket;
161
+ void Init_sp_packet(void);
162
+ VALUE setup_slow_protocol_packet(struct packet_object *, int);
134
163
  #endif /* RUBY_PCAP_H */
164
+
@@ -0,0 +1,29 @@
1
+ #include "ruby_pcap.h"
2
+
3
+ VALUE cSPPacket;
4
+ VALUE cLACPPacket;
5
+
6
+ VALUE
7
+ setup_slow_protocol_packet(pkt, nl_len)
8
+ struct packet_object *pkt;
9
+ int nl_len;
10
+ {
11
+ VALUE class;
12
+
13
+ DEBUG_PRINT("setup_slow_protocol_packet");
14
+ if (pkt->data[14] == 0x01) {
15
+ class = cLACPPacket;
16
+ } else {
17
+ class = cSPPacket;
18
+ }
19
+ return class;
20
+ }
21
+
22
+ void
23
+ Init_sp_packet(void)
24
+ {
25
+ DEBUG_PRINT("Init_sp_packet");
26
+
27
+ cSPPacket = rb_define_class_under(mPcap, "SPPacket", cPacket);
28
+ cLACPPacket = rb_define_class_under(mPcap, "LACPPacket", cSPPacket);
29
+ }