Created
December 7, 2011 07:15
-
-
Save zunda/1441829 to your computer and use it in GitHub Desktop.
A script to create byte sequence of an arp packet. This can not emit packet onto the network.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# asks for IP address of a MAC address | |
# | |
# Copyright (c) 2011 zunda <zunda at freeshell.org> | |
# | |
# Permission is granted for use, copying, modification, | |
# distribution, and distribution of modified versions of this | |
# work as long as the above copyright notice is included. | |
# | |
# ARP message over Ethenet ARP packet | |
# http://en.wikipedia.org/wiki/Address_Resolution_Protocol | |
class ARPMessage | |
attr_accessor :htype # Hardware type | |
attr_accessor :ptype # Protocol type | |
attr_accessor :hlen # Hardware address length | |
attr_accessor :plen # Protocol address length | |
attr_accessor :oper # Operation | |
attr_accessor :sha # Sender hardware address | |
attr_accessor :spa # Sender protocol address | |
attr_accessor :tha # Target hardware address | |
attr_accessor :tpa # Target protocol address | |
# http://www.javvin.com/protocolARP.html | |
OperCode = { | |
:ARP_request => 1, | |
:ARP_response => 2, | |
:RARP_response => 3, | |
:RARP_response => 4, | |
:Dynamic_RARP_response => 5, | |
:Dynamic_RARP_response => 6, | |
:Dynamic_RARP_error => 7, | |
:InARP_request => 8, | |
:InARP_response => 9, | |
} | |
def initialize(htype = 1, ptype = 0x0800, hlen = 6, plen = 4) | |
@htype = htype # 1:Ethernet | |
@ptype = ptype # 0x0800:IPv4 | |
@hlen = hlen # 6:Ethernet | |
@plen = plen # 4:IPv4 | |
end | |
def msg | |
raise 'oper must be set' unless @oper | |
result = [@htype, @ptype, @hlen, @plen, @oper].pack('n2C2n') | |
result += @sha.bytes.to_a.pack("C#{@hlen}") | |
result += (@spa || "\x00"*@plen).bytes.to_a.pack("C#{@plen}") | |
result += (@tha || "\x00"*@hlen).bytes.to_a.pack("C#{@hlen}") | |
result += (@tpa || "\x00"*@plen).bytes.to_a.pack("C#{@plen}") | |
return result | |
end | |
def ARPMessage.parse(message) | |
result = ARPMessage.new | |
result.htype, result.ptype, result.hlen, result.plen, result.oper = message.slice!(0,8).unpack('n2C2n') | |
result.sha = message.slice!(0,result.hlen) | |
result.spa = message.slice!(0,result.plen) | |
result.tha = message.slice!(0,result.hlen) | |
result.tpa = message.slice!(0,result.plen) | |
return result | |
end | |
end | |
if __FILE__ == $0 | |
require 'test/unit' | |
class TestARPMessage < Test::Unit::TestCase | |
def setup | |
@oper = ARPMessage::OperCode[:ARP_request] | |
@sha = "\x00\x00\x00\x12\x34\x56" | |
@spa = "\xc0\xa8\x01\x01" | |
@tpa = "\xc0\xa8\x01\x40" | |
@packet = ARPMessage.new | |
@packet.oper = @oper | |
@packet.sha = @sha | |
@packet.spa = @spa | |
@packet.tpa = @tpa | |
end | |
def test_creation | |
assert_equal("\x00\x01\x08\x00\x06\x04\x00\x01\x00\x00\x00\x12\x34\x56\xc0\xa8\x01\x01\x00\x00\x00\x00\x00\x00\xc0\xa8\x01\x40", @packet.msg) | |
end | |
def test_parse | |
packet = ARPMessage.parse(@packet.msg) | |
assert_equal(1, packet.htype, 'htype') | |
assert_equal(@oper, packet.oper, 'oper') | |
assert_equal(@sha, packet.sha, 'sha') | |
assert_equal(@spa, packet.spa, 'spa') | |
assert_equal("\x00"*6, packet.tha, 'tha') | |
assert_equal(@tpa, packet.tpa, 'tpa') | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment