Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add support for recalculating the ip checksum.

Automatically do so if changing the source or dest IP
  • Loading branch information...
commit 8b1ee0bdd8e57c3067a95152d31d5d12bba44ad9 1 parent b217ab8
Andrew Hobson authored
Showing with 52 additions and 5 deletions.
  1. +1 −0  MANIFEST
  2. +1 −1  VERSION
  3. +46 −0 ext/ip_packet.c
  4. +4 −4 pcap.gemspec
View
1  MANIFEST
@@ -16,6 +16,7 @@ lib/pcaplet.rb
examples/test.rb
examples/tcpdump.rb
examples/httpdump.rb
+examples/rewrite_time.rb
doc/index.html
doc/Pcap.html
doc/Capture.html
View
2  VERSION
@@ -1 +1 @@
-0.7.3
+0.7.4
View
46 ext/ip_packet.c
@@ -12,6 +12,8 @@
VALUE cIPPacket;
static VALUE cIPAddress;
+static unsigned short in_cksum(unsigned char *data, int len);
+
#define CheckTruncateIp(pkt, need) \
CheckTruncate(pkt, pkt->hdr.layer3_off, need, "truncated IP")
@@ -110,6 +112,8 @@ static VALUE \
case T_DATA: \
(member).s_addr = ((struct in_addr *)&(DATA_PTR(val)))->s_addr; \
} \
+ ip->ip_sum = 0; \
+ ip->ip_sum = in_cksum((unsigned char *)ip, ip->ip_hl*4); \
return val; \
}
@@ -145,6 +149,45 @@ ipp_sumok(self)
return Qfalse;
}
+static unsigned short
+in_cksum(unsigned char *data, int len)
+{
+ long sum = 0; /* assume 32 bit long, 16 bit short */
+ unsigned short *temp = (unsigned short *)data;
+
+ while(len > 1){
+ sum += *temp++;
+ if(sum & 0x80000000) /* if high order bit set, fold */
+ sum = (sum & 0xFFFF) + (sum >> 16);
+ len -= 2;
+ }
+ if(len) /* take care of left over byte */
+ sum += (unsigned short) *((unsigned char *)temp);
+
+ while(sum>>16)
+ sum = (sum & 0xFFFF) + (sum >> 16);
+
+ return ~sum;
+}
+
+
+static VALUE
+ipp_sum_update(self)
+ VALUE self;
+{
+ struct packet_object *pkt;
+ struct ip *ip;
+
+ GetPacket(self, pkt);
+ CheckTruncateIp(pkt, 20);
+ ip = IP_HDR(pkt);
+
+ ip->ip_sum = 0;
+ ip->ip_sum = in_cksum((unsigned char *)ip, ip->ip_hl*4);
+ return INT2FIX(ntohs(ip->ip_sum));
+}
+
+
static VALUE
ipp_data(self)
VALUE self;
@@ -187,6 +230,8 @@ new_ipaddr(addr)
return self;
}
+
+
#ifndef INADDR_NONE
# define INADDR_NONE (0xffffffff)
#endif
@@ -355,6 +400,7 @@ Init_ip_packet(void)
rb_define_method(cIPPacket, "ip_dst=", ipp_set_dst, 1);
rb_define_method(cIPPacket, "dst=", ipp_set_dst, 1);
rb_define_method(cIPPacket, "ip_data", ipp_data, 0);
+ rb_define_method(cIPPacket, "ip_sum_update!", ipp_sum_update, 0);
cIPAddress = rb_define_class_under(mPcap, "IPAddress", rb_cObject);
rb_define_singleton_method(cIPAddress, "new", ipaddr_s_new, 1);
View
8 pcap.gemspec
@@ -5,11 +5,11 @@
Gem::Specification.new do |s|
s.name = %q{pcap}
- s.version = "0.7.3"
+ s.version = "0.7.4"
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
s.authors = ["Masaki Fukushima", "Andrew Hobson"]
- s.date = %q{2010-12-02}
+ s.date = %q{2011-02-17}
s.description = %q{Ruby interface to LBL Packet Capture library. This library also includes classes to access packet header fields.}
s.email = %q{fukusima@goto.info.waseda.ac.jp}
s.extensions = ["ext/extconf.rb"]
@@ -72,14 +72,14 @@ Gem::Specification.new do |s|
s.homepage = %q{http://www.goto.info.waseda.ac.jp/~fukusima/ruby/pcap-e.html}
s.rdoc_options = ["--charset=UTF-8"]
s.require_paths = ["lib"]
- s.rubygems_version = %q{1.3.7}
+ s.rubygems_version = %q{1.3.6}
s.summary = %q{Interface to LBL Packet Capture library (libpcap)}
if s.respond_to? :specification_version then
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
s.specification_version = 3
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
else
end
else
Please sign in to comment.
Something went wrong with that request. Please try again.