Any Tools/Libraries for Replaying IP Packets?

Discussion in 'Ruby' started by Sven C. Koehler, Mar 27, 2005.

  1. Hello!

    I have captured the TCP/IP traffic of an application with tcpdump -w, and
    now I would like to read in the file to replay the traffic, can you
    advise any tools/libraries to do this? (preferably Ruby ones.) I work on
    a Linux box, the dump contains both TCP and UDP packets. I want to use
    Ruby here because I need to adjust some data of the dump when replaying.

    Best regards,

    Sven C. Koehler
     
    Sven C. Koehler, Mar 27, 2005
    #1
    1. Advertising

  2. --------------080709010801000306020303
    Content-Type: text/plain; charset=ISO-8859-1; format=flowed
    Content-Transfer-Encoding: 7bit

    Sven C. Koehler wrote:
    > Hello!
    >
    > I have captured the TCP/IP traffic of an application with tcpdump -w, and
    > now I would like to read in the file to replay the traffic, can you
    > advise any tools/libraries to do this? (preferably Ruby ones.) I work on
    > a Linux box, the dump contains both TCP and UDP packets. I want to use
    > Ruby here because I need to adjust some data of the dump when replaying.


    I guess tcpdump -w writes raw packets, so you will need to send out the
    same data as raw packets.

    Here are some files to do that. Start with send.rb. Take out the
    readline code. Add code to read each packet data as a string, and call
    IP.new on it to get a packet, and then call send with the packet. The IP
    methods will help with manipulating the packet data (in particular, you
    can treat the whole packet as a string). The send-recv.rb file is nice
    for debugging. Of course, all have to be run as root.

    BTW, these three files are ruby prototypes for a library I am working on
    to generate C code (and ruby wrappers) for doing similar things with raw
    IP packets and packet options, esp. DSRC wireless options. I'll make it
    available in a few weeks, probably.


    --------------080709010801000306020303
    Content-Type: text/plain;
    name="ip.rb"
    Content-Transfer-Encoding: 7bit
    Content-Disposition: inline;
    filename="ip.rb"

    require 'scanf'

    # based on icmp.rb Copyright (C) 2000 GOTOU YUUZOU <>
    class IP < String
    def self.new(s=nil); s ? super(s) : super("\0" * 20); end

    def ip_v; (self[0] >> 4) & 0x0f; end
    def ip_v=(v); self[0] = (v << 4) | (self[0] & 0x0f); end

    def ip_hl; self[0] & 0xf end
    def ip_hl=(v); self[0] = (self[0] & 0xf0) | (v & 0x0f); end

    def ip_tos; self[1]; end
    def ip_tos=(v); self[1] = v; end

    def ip_len; self[2..3].unpack("n")[0]; end
    def ip_len=(v); self[2..3]=[v].pack("n"); end

    def ip_id; self[4..5].unpack("n")[0]; end
    def ip_id=(v); self[4..5]=[v].pack("n"); end

    def ip_off; self[6..7].unpack("n")[0]; end
    def ip_off=(v); self[6..7]=[v].pack("n"); end

    def ip_ttl; self[8]; end
    def ip_ttl=(v); self[8]=v; end

    def ip_p; self[9]; end
    def ip_p=(v); self[9]=v; end

    def ip_sum; self[10..11].unpack("n")[0]; end
    def ip_sum=(v); self[10..11]=[v].pack("n"); end

    def ip_src; "%d.%d.%d.%d" % [self[12], self[13], self[14], self[15]]; end
    def ip_src=(s); self[12..15] = s.scanf("%d.%d.%d.%d").pack("c*"); end

    def ip_dst; "%d.%d.%d.%d" % [self[16], self[17], self[18], self[19]]; end
    def ip_dst=(s); self[16..19] = s.scanf("%d.%d.%d.%d").pack("c*"); end

    def body; self[(ip_hl*4)..-1]; end
    def body=(s); self[(ip_hl*4)..-1] = s; end

    # def inspect; "<IP: size=#{size} src=#{ip_src} dst=#{ip_dst}>"; end

    IP_FIELDS = [
    ["Version", :ip_v ],
    ["Header length", :ip_hl ],
    ["TOS", :ip_tos ],
    ["Length", :ip_len ],
    ["ID", :ip_id ],
    ["Frag offset", :ip_off ],
    ["TTL", :ip_ttl ],
    ["Protocol", :ip_p ],
    ["Checksum", :ip_sum ],
    ["Source addr", :ip_src ],
    ["Dest addr", :ip_dst ]
    ]

    def details
    IP_FIELDS.map do |name, meth|
    sprintf("%20s = %s\n", name, send(meth))
    end <<
    sprintf("%20s = %s\n", "Body", body.inspect)
    end
    end

    if __FILE__ == $0
    ip = IP.new
    ip.ip_v = 4
    ip.ip_hl = 5 ## ?
    ip.ip_tos = 0
    ip.ip_len = 0
    ip.ip_id = 0
    ip.ip_off = 0
    ip.ip_ttl = 255
    ip.ip_p = 255
    ip.ip_sum = 0
    ip.ip_src = "192.168.1.4"
    ip.ip_dst = "192.168.1.255"

    print ip.details
    end


    --------------080709010801000306020303
    Content-Type: text/plain;
    name="send-recv.rb"
    Content-Transfer-Encoding: 7bit
    Content-Disposition: inline;
    filename="send-recv.rb"

    require "socket"
    require "ip"
    require "readline"

    begin
    rsock = Socket.open(Socket::pF_INET, Socket::SOCK_RAW, Socket::IPPROTO_RAW)
    rescue Errno::EPERM => e
    raise e, "You must be root to run this program."
    end

    rsock.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)

    listener = Thread.new do
    loop do
    data, sender = rsock.recvfrom(8192)
    port, host = Socket.unpack_sockaddr_in(sender)
    puts
    puts "-"*80
    puts "packet received from #{host}:#{port}:"
    puts IP.new(data).details
    $stdout.flush
    end
    end

    sockaddr = Socket.pack_sockaddr_in(1024, "127.0.0.1")
    #dst_port, dst_host = Socket.unpack_sockaddr_in(sockaddr)
    #src_port, src_host = Socket.unpack_sockaddr_in(rsock.getsockname)

    ip = IP.new
    ip.ip_v = 4
    ip.ip_hl = 5
    ip.ip_tos = 0
    ip.ip_len = 0
    ip.ip_id = 0
    ip.ip_off = 0
    ip.ip_ttl = 255
    ip.ip_p = Socket::IPPROTO_RAW
    ip.ip_sum = 0
    # ip.ip_src = src_host <-- filled in by socket
    # ip.ip_dst = dst_host

    loop do
    line = Readline.readline("input> ", true)
    break unless line
    ip.body = line
    rsock.send(ip, 0, sockaddr)
    end

    listener.kill
    rsock.close


    --------------080709010801000306020303
    Content-Type: text/plain;
    name="send.rb"
    Content-Transfer-Encoding: 7bit
    Content-Disposition: inline;
    filename="send.rb"

    require "socket"
    require "ip"
    require "readline"

    rsock = Socket.open(Socket::pF_INET, Socket::SOCK_RAW, Socket::IPPROTO_RAW)
    sockaddr = Socket.pack_sockaddr_in(1024, "localhost")

    ip = IP.new
    ip.ip_v = 4
    ip.ip_hl = 5
    ip.ip_tos = 0
    ip.ip_len = 0
    ip.ip_id = 0
    ip.ip_off = 0
    ip.ip_ttl = 255
    ip.ip_p = 255
    ip.ip_sum = 0
    ip.ip_src = "192.168.1.4"
    ip.ip_dst = "192.168.1.255"

    loop do
    line = Readline.readline("input> ", true)
    break unless line
    ip.body = line
    rsock.send(ip, 0, sockaddr)
    end

    rsock.close


    --------------080709010801000306020303--
     
    Joel VanderWerf, Mar 27, 2005
    #2
    1. Advertising

  3. Am Sonntag 27 März 2005 19:04 schrieb Sven C. Koehler:
    > Hello!
    >
    > I have captured the TCP/IP traffic of an application with tcpdump -w, and
    > now I would like to read in the file to replay the traffic, can you
    > advise any tools/libraries to do this? (preferably Ruby ones.) I work on
    > a Linux box, the dump contains both TCP and UDP packets. I want to use
    > Ruby here because I need to adjust some data of the dump when replaying.


    This might be of interest:

    http://www.goto.info.waseda.ac.jp/~fukusima/ruby/pcap-e.html

    But, I'm not sure if you can read a tcpdump file with it.

    Regards,

    Michael
     
    Michael Neumann, Mar 28, 2005
    #3
  4. On Mon, Mar 28, 2005 at 06:00:41AM +0900, Joel VanderWerf wrote:
    > Here are some files to do that. Start with send.rb. Take out the
    > readline code. Add code to read each packet data as a string, and call
    > IP.new on it to get a packet, and then call send with the packet. The IP
    > methods will help with manipulating the packet data (in particular, you
    > can treat the whole packet as a string). The send-recv.rb file is nice
    > for debugging. Of course, all have to be run as root.


    Thanks for the code! I will try it out later. Thanks also to the other
    advisors.

    -S.
     
    Sven C. Koehler, Mar 28, 2005
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    1
    Views:
    323
    Diez B. Roggisch
    Apr 18, 2005
  2. Karsten Wutzke
    Replies:
    21
    Views:
    951
    Roedy Green
    Jun 29, 2007
  3. Replies:
    1
    Views:
    369
    rayyildiz
    Nov 20, 2007
  4. Sriram Srinivasan
    Replies:
    13
    Views:
    600
    Benjamin Kaplan
    Nov 12, 2009
  5. Greg Hauptmann
    Replies:
    12
    Views:
    213
    Peter Szinek
    Apr 28, 2008
Loading...

Share This Page