blackfoundry-pcap 0.1

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