ネットワークやセキュリティの試験をする際、送信するパケットのMACアドレスやIPアドレスを自由に設定できる必要がある。
そういう際によく使われるのはsmartbitという機材だが、いかんせんめちゃ高。とても個人で購入できる代物ではない。
そこで、自分のパソコンからsmartbitのように好きなパケットを流すツールがNetwork packet generator (Windows専用)というツールだ。
EthernetフレームからのデータをすべてHEX文字で設定したデータをそのまま流すことができるというスグレものなのだが、いかんせんUDPのデータを送る際にいちいちチェックサムやデータ内容をHEX文字に置き換えるのが大変面倒。
そこでNetwork packet generator用のUDPプロトコルのパケットデータを簡単に作れるrubyのプログラムを2年ぐらい前に作っていた。どうもsipのテスト用に作ったようだ。すっかり忘れていた。今だともっと簡単に,おまけにTCPも対応できそうだが、それは必要になった時に。
無保証です。問題が起こっても、保証しません。
使い方
ruby packet.rb データ記述ファイル
標準出力にNetwork packet generator用のデータが
出力される。そのため普通は >ファイル名 でリダイレクトして使う。
データ記述ファイルフォーマット
以下の順にカンマ区切りでレコードを書き、複数パケットは改行
行先MACアドレス,送信元MACアドレス,送信元IP,送信先IP,宛先ポート,送信先ポート,データ部分の内容が書かれたファイル名
packet.rb
def makeChecksum(sumArr)
arr = Array.new
i = 0
j = 0
while i < sumArr.length
arr[j] = sumArr[i].to_s + sumArr[i+1].to_s + sumArr[i+2].to_s + sumArr[i+3].to_s
i=i+4
j=j+1
end
hexArr = arr.collect{|c| c.hex}
sum = 0
idx = 0
hexArr.each{|e|
sum += e
if(sum & 0x80000000)
sum = (sum & 0xffff) + (sum >> 16)
end
}
while(sum > 65535)
sum = (sum & 0xffff) + (sum >> 16)
end
if(sum != 0xffff)
sum = 65535-sum
end
return make2Hex(sum)
end
def makeHexStr(contents)
hexStr=""
count = 0
contents.each_byte {|c|
if(count %8 ==0)
hexStr += "\n "
hexStr += sprintf("%02X",c)
else
hexStr += sprintf(" %02X",c)
end
count = count+1
}
return hexStr
end
def make2Hex(port)
source = sprintf("%X",port)
sArray = source.split('')
while sArray.length < 4
sArray.unshift("0")
end
return sArray
end
def makeUdpHeader(contents,sourcePort,destinationPort)
dm = make2Hex(destinationPort)
sm = make2Hex(sourcePort)
len = contents.length + 8
lenArr = make2Hex(len)
return dm.concat(sm).concat(lenArr).concat(["0","0","0","0"])
end
def checkMac(mac)
if(mac.length != 12 || mac !~ /[0-9A-Fa-f]/)
return false
end
return true
end
def formatIp(ip)
ipArray = Array.new
if(ip =~ /([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})/)
i=1
while i <= 4
num = eval("$#{i}")
if(num.to_i > 255)
print "num format#{num}\n"
return nil
end
ipArray[i-1] = sprintf("%02X",num)
i=i+1
end
else
print "not format\n"
return nil
end
return ipArray
end
fn = ARGV.shift
File::open(fn){|f|
i=1
f.each{|line|
values = line.split(/\s*,\s*/)
if(values.length != 7)
print "format error line:#{i}"
exit
end
destMac,sourceMac,sourceIp,destIp,destinationPort,sourcePort,outPutFile=values;
cf = open(outPutFile.chomp,"rb")
if(!cf)
print "#{outPutFile} can't open"
exit
end
contents = cf.read
cf.close
if(!checkMac(destMac))
print "destMac format error line:#{i}"
exit
end
if(!checkMac(sourceMac))
print "sourceMac #{sourceMac} format error line:#{i}"
exit
end
dIp = formatIp(destIp)
if(!dIp)
print "destIp #{destIp} format error line:#{i}"
exit
end
sIp = formatIp(sourceIp)
if(!sIp)
print "sourceIp #{sourceIp} format error line:#{i}"
exit
end
if(destinationPort !~ /^\d+$/)
print "destinationPort #{destinationPort} format error line:#{i}"
exit
end
if(sourcePort !~ /^\d+$/)
print "sourcePort #{sourcePort} format error line:#{i}"
exit
end
uh = makeUdpHeader(contents,sourcePort,destinationPort)
# ip(20) + udp(8) + contents
size = 20+8+contents.length
print "[0,1000]\n<sip #{i}>\n{\n"
dmacAddr = destMac.split('')
print " #{dmacAddr[0..1]} #{dmacAddr[2..3]} #{dmacAddr[4..5]} #{dmacAddr[6..7]} #{dmacAddr[8..9]} #{dmacAddr[10..11]} #Destination MAC\n"
smacAddr = sourceMac.split('')
print " #{smacAddr[0..1]} #{smacAddr[2..3]} #{smacAddr[4..5]} #{smacAddr[6..7]} #{smacAddr[8..9]} #{smacAddr[10..11]} #Source MAC\n"
proto = "0800".split('')
print " #{proto[0..1]} #{proto[2..3]} #protocol\n"
versionType = "4500".split('')
print " #{versionType[0..1]} # Version / Header Length\n"
print " #{versionType[2..3]} # Type of Service\n"
total = make2Hex(size)
print " #{total[0..1]} #{total[2..3]} # Total length\n"
other = "000100008011".split('')
print " #{other[0..1]} #{other[2..3]} # Identification\n"
print " #{other[4..5]} #{other[6..7]} # Flags / Fragment offset\n"
print " #{other[8..9]} # Time to live\n"
print " #{other[10..11]} # Protocol\n"
sumArr = Array.new
sumArr.concat(versionType).concat(total).concat(other).concat(sIp).concat(dIp)
checksum = makeChecksum(sumArr)
print " #{checksum[0..1]} #{checksum[2..3]} # Checksum\n"
print " #{sIp[0]} #{sIp[1]} #{sIp[2]} #{sIp[3]} #soruce IP\n"
print " #{dIp[0]} #{dIp[1]} #{dIp[2]} #{dIp[3]} #Destination IP\n"
udpContents = " #{uh[0..1]} #{uh[2..3]} # Source port\n" +
" #{uh[4..5]} #{uh[6..7]} # Destination port\n" +
" #{uh[8..9]} #{uh[10..11]} # Length\n" +
" #{uh[12..13]} #{uh[14..15]} # Check sum\n"
print udpContents
contentsHex = makeHexStr(contents)
print contentsHex
print "\n}\n"
i=i+1
}
}
最近のコメント