#!/usr/bin/env ruby

require 'RubyLibtrace'

# 1925, Sun 6 Apr 08 (PDT)
# arp-anon.rb: Anonymise IPv4 addresses in ARP records
# Copyright (C) 2008, Nevil Brownlee, U Auckland | CAIDA | WAND

#doc_ipv4 = IPprefix::from_s('192.168.0.0/24')  # IPv4 'documentation' prefix
doc_ipv4 = IPprefix::from_s('192.123.0.0/24')  # for rlt testing
doc_addr = doc_ipv4.addr[0..2]  # 3-byte address string

def get_short(a, x)  # Get value of two-byte fied from a[]
   return a[x] << 8 | a[x+1]
end

f = Trace.new(ARGV[0])
f.start

of = OutputTrace.new('pcapfile:arp-changed.bpf')
of.start_output

n = nip = 0;  nudp = 0
f.each_packet do |pkt|
   n += 1

   l3 = pkt.layer3
   if l3.ethertype == 0x0806  # ARP
      d = l3.data  # Decode the ARP packet
      hw_type = get_short(d, 0)
      protocol_type = get_short(d, 2)
      hln = d[4]  # Length of h/w address
      pln = d[5]  # Length of protocol address
      opcode = get_short(d, 6)
#      print "hrd=#{hw_type}, pro=#{protocol_type}, " +
#         "hln=#{hln}, pln=#{pln}, op=#{opcode}\n"

      sax = 8+hln;  tax = sax+pln+hln  # Change sender and
      d[sax..sax+pln-2] = doc_addr     # target addresses in d
      d[tax..tax+pln-2] = doc_addr

      pkt.layer3.data= d  # Write changed addresses into pkt
   end

   of.write_packet(pkt)
 
#   break if n == 5
end

of.close_output;  f.close

