ruby-pcap 0.7.9 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
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
  }