ruby-pcap 0.7.9 → 0.8.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/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
+ }
@@ -14,10 +14,12 @@
14
14
  #define TCP_DATALEN(pkt) (ntohs(IP_HDR(pkt)->ip_len) - \
15
15
  (IP_HDR(pkt)->ip_hl + TCP_HDR(pkt)->th_off) * 4)
16
16
 
17
+ #define TCP_OPTIONS(pkt) ((u_char *) &TCP_HDR(pkt)->th_urp + 2)
18
+ #define TCP_OPTIONS_LEN(pkt) (((TCP_HDR(pkt)->th_off) * 4) - 20)
19
+
17
20
  VALUE cTCPPacket;
18
21
 
19
- #define CheckTruncateTcp(pkt, need) \
20
- CheckTruncate(pkt, pkt->hdr.layer4_off, need, "truncated TCP")
22
+ #define CheckTruncateTcp(pkt, need) CheckTruncate(pkt, pkt->hdr.layer4_off, need, "truncated TCP")
21
23
 
22
24
  VALUE
23
25
  setup_tcp_packet(pkt, tl_len)
@@ -64,8 +66,8 @@ TCPP_METHOD(tcpp_win, 16, INT2FIX(ntohs(tcp->th_win)))
64
66
  TCPP_METHOD(tcpp_sum, 18, INT2FIX(ntohs(tcp->th_sum)))
65
67
  TCPP_METHOD(tcpp_urp, 20, INT2FIX(ntohs(tcp->th_urp)))
66
68
 
67
- #define TCPP_FLAG(func, flag) \
68
- TCPP_METHOD(func, 14, (tcp->th_flags & flag) ? Qtrue : Qfalse)
69
+ #define TCPP_FLAG(func, flag) TCPP_METHOD(func, 14, (tcp->th_flags & flag) ? Qtrue : Qfalse)
70
+
69
71
  TCPP_FLAG(tcpp_fin, TH_FIN)
70
72
  TCPP_FLAG(tcpp_syn, TH_SYN)
71
73
  TCPP_FLAG(tcpp_rst, TH_RST)
@@ -78,7 +80,6 @@ tcpp_data(self)
78
80
  VALUE self;
79
81
  {
80
82
  struct packet_object *pkt;
81
- VALUE v_len;
82
83
  int len;
83
84
 
84
85
  DEBUG_PRINT("tcpp_data");
@@ -91,6 +92,308 @@ tcpp_data(self)
91
92
  return rb_str_new(TCP_DATA(pkt), len);
92
93
  }
93
94
 
95
+ static VALUE
96
+ tcpp_options(self)
97
+ VALUE self;
98
+ {
99
+ struct packet_object *pkt;
100
+ int len;
101
+
102
+ DEBUG_PRINT("tcpp_options");
103
+ GetPacket(self, pkt);
104
+ len = TCP_OPTIONS_LEN(pkt);
105
+ if (len < 1 ) return Qnil;
106
+ return rb_str_new(TCP_OPTIONS(pkt), len);
107
+ }
108
+
109
+ static VALUE
110
+ tcpp_csumok(self)
111
+ VALUE self;
112
+ {
113
+ struct packet_object *pkt;
114
+ struct ip *ip;
115
+ struct tcphdr *tcp;
116
+ GetPacket(self, pkt);
117
+ ip = IP_HDR(pkt);
118
+ tcp = TCP_HDR(pkt);
119
+ unsigned short *ip_src = (void *)&ip->ip_src.s_addr;
120
+ unsigned short *ip_dst = (void *)&ip->ip_dst.s_addr;
121
+ long sum = 0;
122
+ unsigned short *temp = (unsigned short *)tcp;
123
+ int len = ntohs(ip->ip_len) - ip->ip_hl*4; // length of ip data
124
+ unsigned short csum = ntohs(tcp->th_sum); // keep the checksum in packet
125
+
126
+ // pseudo header sum
127
+ sum += ntohs(*(ip_src++));
128
+ sum += ntohs(*ip_src);
129
+ sum += ntohs(*(ip_dst++));
130
+ sum += ntohs(*ip_dst);
131
+ sum += 6;
132
+ sum += len;
133
+ // set checksum to zero and sum
134
+ tcp->th_sum = 0;
135
+ while(len > 1){
136
+ sum += ntohs(*temp++);
137
+ len -= 2;
138
+ }
139
+ if(len)
140
+ sum += ntohs((unsigned short) *((unsigned char *)temp));
141
+ while(sum>>16)
142
+ sum = (sum & 0xFFFF) + (sum >> 16);
143
+ unsigned short answer = ~sum;
144
+
145
+ tcp->th_sum = htons(csum); //restore the checkum in packet
146
+ if (DEBUG_CHECKSUM)
147
+ printf("TCP csum in packet:%d should be %d\n", csum, answer);
148
+ if (answer == csum)
149
+ return Qtrue;
150
+ return Qfalse;
151
+ }
152
+
153
+ static VALUE
154
+ tcpp_truncated(self)
155
+ VALUE self;
156
+ {
157
+ struct packet_object *pkt;
158
+ struct ip *ip;
159
+ struct tcphdr *tcp;
160
+ GetPacket(self, pkt);
161
+ ip = IP_HDR(pkt);
162
+ tcp = TCP_HDR(pkt);
163
+ if IsTruncated(pkt, pkt->hdr.layer3_off, ip->ip_hl * 4 + tcp->th_off * 4)
164
+ return Qtrue;
165
+ return Qfalse;
166
+ }
167
+
168
+ static VALUE
169
+ tcpp_data_len(self)
170
+ VALUE self;
171
+ {
172
+ struct packet_object *pkt;
173
+ GetPacket(self, pkt);
174
+
175
+ return INT2FIX(TCP_DATALEN(pkt));
176
+ }
177
+
178
+ /*
179
+ Calculate TCP checksum and update it in packet
180
+ */
181
+ static VALUE
182
+ tcpp_csum_update(self)
183
+ VALUE self;
184
+ {
185
+ struct packet_object *pkt;
186
+ struct ip *ip;
187
+ struct tcphdr *tcp;
188
+ GetPacket(self, pkt);
189
+ ip = IP_HDR(pkt);
190
+ tcp = TCP_HDR(pkt);
191
+ unsigned short *ip_src = (void *)&ip->ip_src.s_addr;
192
+ unsigned short *ip_dst = (void *)&ip->ip_dst.s_addr;
193
+ long sum = 0;
194
+ /* save checksum in packet */
195
+ unsigned short th_sum = ntohs(tcp->th_sum);
196
+ unsigned short *temp = (unsigned short *)tcp;
197
+ int len = ntohs(ip->ip_len) - ip->ip_hl*4; // length of ip data
198
+
199
+ // pseudo header sum
200
+ sum += ntohs(*(ip_src++));
201
+ sum += ntohs(*ip_src);
202
+ sum += ntohs(*(ip_dst++));
203
+ sum += ntohs(*ip_dst);
204
+ sum += 6;
205
+ sum += len;
206
+ // set checksum to zero and sum
207
+ tcp->th_sum = 0;
208
+ while(len > 1){
209
+ sum += ntohs(*temp++);
210
+ len -= 2;
211
+ }
212
+ if(len)
213
+ sum += ntohs((unsigned short) *((unsigned char *)temp));
214
+ while(sum>>16)
215
+ sum = (sum & 0xFFFF) + (sum >> 16);
216
+ unsigned short answer = ~sum;
217
+ /*
218
+ * set checkum in packet
219
+ */
220
+ tcp->th_sum = htons(answer);
221
+ /*
222
+ * no change, return nil
223
+ */
224
+ if (answer == th_sum)
225
+ return Qnil;
226
+ /*
227
+ * return new checkum
228
+ */
229
+ return UINT2NUM(answer);
230
+ }
231
+
232
+ /*
233
+ * Set TCP source port and update checksum
234
+ */
235
+ static VALUE
236
+ tcpp_sport_set(self, val)
237
+ VALUE self, val;
238
+ {
239
+ struct packet_object *pkt;
240
+ struct tcphdr *tcp;
241
+ GetPacket(self, pkt);
242
+ tcp = TCP_HDR(pkt);
243
+ long sum = 0;
244
+ /*
245
+ * https://tools.ietf.org/html/rfc1624
246
+ * HC' = ~(C + (-m) + m')
247
+ */
248
+ sum = ~(~ntohs(tcp->th_sum) - ntohs(tcp->th_sport) + NUM2USHORT(val));
249
+ while(sum>>16)
250
+ sum = (sum & 0xFFFF) + (sum >> 16);
251
+ /*
252
+ * ttps://tools.ietf.org/html/rfc1624 boundary conditions
253
+ */
254
+ if (sum == 0xFFFF)
255
+ sum = ~sum;
256
+ /*
257
+ * set desired value and new checksum
258
+ */
259
+ tcp->th_sport = htons(NUM2USHORT(val));
260
+ tcp->th_sum = htons(sum);
261
+ return val;
262
+ }
263
+
264
+ /*
265
+ Set TCP destination port and update checksum
266
+ */
267
+ static VALUE
268
+ tcpp_dport_set(self, val)
269
+ VALUE self, val;
270
+ {
271
+ struct packet_object *pkt;
272
+ struct tcphdr *tcp;
273
+ GetPacket(self, pkt);
274
+ tcp = TCP_HDR(pkt);
275
+ long sum = 0;
276
+ /*
277
+ * https://tools.ietf.org/html/rfc1624
278
+ * HC' = ~(C + (-m) + m')
279
+ */
280
+ sum = ~(~ntohs(tcp->th_sum) - ntohs(tcp->th_dport) + NUM2USHORT(val));
281
+ while(sum>>16)
282
+ sum = (sum & 0xFFFF) + (sum >> 16);
283
+ /*
284
+ * ttps://tools.ietf.org/html/rfc1624 boundary conditions
285
+ */
286
+ if (sum == 0xFFFF)
287
+ sum = ~sum;
288
+ /*
289
+ * set desired value and new checksum
290
+ */
291
+ tcp->th_dport = htons(NUM2USHORT(val));
292
+ tcp->th_sum = htons(sum);
293
+ return val;
294
+ }
295
+
296
+ /*
297
+ * IPv6 Specific methods
298
+ */
299
+
300
+ VALUE cTCPv6Packet;
301
+
302
+ #define TCPV6_DATALEN(pkt) (ntohs(IPV6_HDR(pkt)->ip6_plen) - TCP_HDR(pkt)->th_off * 4)
303
+
304
+ VALUE
305
+ setup_tcpv6_packet(pkt, tl_len)
306
+ struct packet_object *pkt;
307
+ int tl_len;
308
+ {
309
+ VALUE class;
310
+
311
+ class = cTCPv6Packet;
312
+ if (tl_len > 20) {
313
+ int hl = TCP_HDR(pkt)->th_off * 4;
314
+ int layer5_len = tl_len - hl;
315
+ if (layer5_len > 0) {
316
+ pkt->hdr.layer5_off = pkt->hdr.layer4_off + hl;
317
+ /* upper layer */
318
+ }
319
+ }
320
+ return class;
321
+ }
322
+
323
+ static VALUE
324
+ tcppv6_data_len(self)
325
+ VALUE self;
326
+ {
327
+ struct packet_object *pkt;
328
+ GetPacket(self, pkt);
329
+
330
+ return INT2FIX(TCPV6_DATALEN(pkt));
331
+ }
332
+
333
+ static VALUE
334
+ tcppv6_data(self)
335
+ VALUE self;
336
+ {
337
+ struct packet_object *pkt;
338
+ int len;
339
+
340
+ DEBUG_PRINT("tcppv6_data");
341
+ GetPacket(self, pkt);
342
+
343
+ if (pkt->hdr.layer5_off == OFF_NONEXIST) return Qnil;
344
+
345
+ len = MIN(Caplen(pkt, pkt->hdr.layer5_off), TCPV6_DATALEN(pkt));
346
+ if (len < 1) return Qnil;
347
+ return rb_str_new(TCP_DATA(pkt), len);
348
+ }
349
+
350
+ static VALUE
351
+ tcpp_csumokv6(self)
352
+ VALUE self;
353
+ {
354
+ struct packet_object *pkt;
355
+ struct ip6_hdr *ip;
356
+ struct tcphdr *tcp;
357
+ GetPacket(self, pkt);
358
+ ip = IPV6_HDR(pkt);
359
+ tcp = TCP_HDR(pkt);
360
+ unsigned short *ip_src = (void *)&ip->ip6_src.s6_addr;
361
+ unsigned short *ip_dst = (void *)&ip->ip6_dst.s6_addr;
362
+ unsigned long sum = 0;
363
+ unsigned short *temp = (unsigned short *)tcp;
364
+ int len = ntohs(ip->ip6_plen); // length of ip data
365
+ unsigned short csum = ntohs(tcp->th_sum); // keep the checksum in packet
366
+
367
+ // pseudo header sum
368
+ int i = 1;
369
+ for (i = 0; i < 8; i++) {
370
+ sum += ntohs(*(ip_src));
371
+ sum += ntohs(*(ip_dst));
372
+ ip_src++;
373
+ ip_dst++;
374
+ }
375
+ sum += 0x6; /* TCP type */
376
+ sum += len; /* packet length */
377
+ // set checksum to zero and sum
378
+ tcp->th_sum = 0;
379
+ while(len > 1){
380
+ sum += ntohs(*temp++);
381
+ len -= 2;
382
+ }
383
+ if(len)
384
+ sum += ntohs((unsigned short) *((unsigned char *)temp));
385
+ while(sum>>16)
386
+ sum = (sum & 0xFFFF) + (sum >> 16);
387
+ unsigned short answer = ~sum;
388
+
389
+ tcp->th_sum = htons(csum); //restore the checkum in packet
390
+ if (DEBUG_CHECKSUM)
391
+ printf("TCPv6 csum in packet:%d should be %d\n", csum, answer);
392
+ if (answer == csum)
393
+ return Qtrue;
394
+ return Qfalse;
395
+ }
396
+
94
397
  void
95
398
  Init_tcp_packet(void)
96
399
  {
@@ -98,11 +401,15 @@ Init_tcp_packet(void)
98
401
 
99
402
  /* define class TcpPacket */
100
403
  cTCPPacket = rb_define_class_under(mPcap, "TCPPacket", cIPPacket);
101
-
404
+ /* define methods under IPv4 */
102
405
  rb_define_method(cTCPPacket, "tcp_sport", tcpp_sport, 0);
406
+ rb_define_method(cTCPPacket, "tcp_sport=", tcpp_sport_set, 1);
103
407
  rb_define_method(cTCPPacket, "sport", tcpp_sport, 0);
408
+ rb_define_method(cTCPPacket, "sport=", tcpp_sport_set, 1);
104
409
  rb_define_method(cTCPPacket, "tcp_dport", tcpp_dport, 0);
410
+ rb_define_method(cTCPPacket, "tcp_dport=", tcpp_dport_set, 1);
105
411
  rb_define_method(cTCPPacket, "dport", tcpp_dport, 0);
412
+ rb_define_method(cTCPPacket, "dport=", tcpp_dport_set, 1);
106
413
  rb_define_method(cTCPPacket, "tcp_seq", tcpp_seq, 0);
107
414
  rb_define_method(cTCPPacket, "tcp_ack", tcpp_acknum, 0);
108
415
  rb_define_method(cTCPPacket, "tcp_off", tcpp_off, 0);
@@ -118,4 +425,37 @@ Init_tcp_packet(void)
118
425
  rb_define_method(cTCPPacket, "tcp_ack?", tcpp_ack, 0);
119
426
  rb_define_method(cTCPPacket, "tcp_urg?", tcpp_urg, 0);
120
427
  rb_define_method(cTCPPacket, "tcp_data", tcpp_data, 0);
428
+ rb_define_method(cTCPPacket, "tcp_data_len", tcpp_data_len, 0);
429
+ rb_define_method(cTCPPacket, "tcp_options", tcpp_options, 0);
430
+ rb_define_method(cTCPPacket, "tcp_csum_ok?", tcpp_csumok, 0);
431
+ rb_define_method(cTCPPacket, "tcp_truncated?", tcpp_truncated, 0);
432
+ rb_define_method(cTCPPacket, "tcp_csum_update!", tcpp_csum_update, 0);
433
+
434
+ // IPv6
435
+ cTCPv6Packet = rb_define_class_under(mPcap, "TCPv6Packet", cIPv6Packet);
436
+ /* define methods under IPv6 */
437
+ rb_define_method(cTCPv6Packet, "tcp_sport", tcpp_sport, 0);
438
+ rb_define_method(cTCPv6Packet, "sport", tcpp_sport, 0);
439
+ rb_define_method(cTCPv6Packet, "tcp_dport", tcpp_dport, 0);
440
+ rb_define_method(cTCPv6Packet, "dport", tcpp_dport, 0);
441
+ rb_define_method(cTCPv6Packet, "tcp_seq", tcpp_seq, 0);
442
+ rb_define_method(cTCPv6Packet, "tcp_ack", tcpp_acknum, 0);
443
+ rb_define_method(cTCPv6Packet, "tcp_off", tcpp_off, 0);
444
+ rb_define_method(cTCPv6Packet, "tcp_hlen", tcpp_off, 0);
445
+ rb_define_method(cTCPv6Packet, "tcp_flags", tcpp_flags, 0);
446
+ rb_define_method(cTCPv6Packet, "tcp_win", tcpp_win, 0);
447
+ rb_define_method(cTCPv6Packet, "tcp_sum", tcpp_sum, 0);
448
+ rb_define_method(cTCPv6Packet, "tcp_csumok?", tcpp_csumokv6, 0);
449
+ rb_define_method(cTCPv6Packet, "tcp_urp", tcpp_urp, 0);
450
+ rb_define_method(cTCPv6Packet, "tcp_fin?", tcpp_fin, 0);
451
+ rb_define_method(cTCPv6Packet, "tcp_syn?", tcpp_syn, 0);
452
+ rb_define_method(cTCPv6Packet, "tcp_rst?", tcpp_rst, 0);
453
+ rb_define_method(cTCPv6Packet, "tcp_psh?", tcpp_psh, 0);
454
+ rb_define_method(cTCPv6Packet, "tcp_ack?", tcpp_ack, 0);
455
+ rb_define_method(cTCPv6Packet, "tcp_urg?", tcpp_urg, 0);
456
+ rb_define_method(cTCPv6Packet, "tcp_data", tcppv6_data, 0);
457
+ rb_define_method(cTCPv6Packet, "tcp_data_len", tcppv6_data_len, 0);
458
+ rb_define_method(cTCPv6Packet, "tcp_options", tcpp_options, 0);
459
+
460
+
121
461
  }