Index: nselib/packet.lua =================================================================== --- nselib/packet.lua (revision 6672) +++ nselib/packet.lua (working copy) @@ -55,6 +55,12 @@ local sum = 0 local c local x = b + + -- fill with 00, this should be done by the code below, + -- but it's not. maybe we should fix this someday + if x:len() % 2 == 1 then + x = x .. hextobin("00") + end while x:len() > 1 do c = x:sub(1,2) @@ -116,6 +122,10 @@ if not o:tcp_parse(force_continue) then io.write("Error while parsing TCP packet\n") end + elseif o.ip_p == IPPROTO_UDP then + if not o:udp_parse(force_continue) then + io.write("Error while parsing UDP packet\n") + end elseif o.ip_p == IPPROTO_ICMP then if not o:icmp_parse(force_continue) then io.write("Error while parsing ICMP packet\n") @@ -207,14 +217,31 @@ self.ip_v = bit.rshift(bit.band(self:u8(self.ip_offset + 0), 0xF0), 4) self.ip_hl = bit.band(self:u8(self.ip_offset + 0), 0x0F) -- header_length or data_offset end +-- set tos +function Packet:ip_set_tos(tos) + self:set_u8(self.ip_offset + 1, tos) +end -- set packet length field function Packet:ip_set_len(len) self:set_u16(self.ip_offset + 2, len) end +-- set id +function Packet:ip_set_id(id) + self:set_u16(self.ip_offset + 4, id) +end +-- set fragment offset + ip flags rf|df|mf +function Packet:ip_set_off(off) + self:set_u16(self.ip_offset + 6, off) +end -- set ttl function Packet:ip_set_ttl(ttl) self:set_u8(self.ip_offset + 8, ttl) end +-- set protocol +function Packet:ip_set_p(protocol) + self:set_u8(self.ip_offset + 9, protocol) + self.ip_p = self:u8(self.ip_offset + 9) +end -- set checksum function Packet:ip_set_checksum(checksum) self:set_u16(self.ip_offset + 10, checksum) @@ -296,6 +323,8 @@ function Packet:tostring() if self.tcp then return self:tcp_tostring() + elseif self.udp then + return self:udp_tostring() elseif self.icmp then return self:icmp_tostring() elseif self.ip then @@ -501,7 +530,62 @@ end ---------------------------------------------------------------------------------------------------------------- +-- PARSE UDP HEADER FROM PACKET +function Packet:udp_parse(force_continue) + self.udp = true + self.udp_offset = self.ip_data_offset + if string.len(self.buf) < self.udp_offset + 4 then + return false + end + self.udp_sport = self:u16(self.udp_offset + 0) + self.udp_dport = self:u16(self.udp_offset + 2) + if string.len(self.buf) < self.udp_offset + 8 then + if force_continue then + return true + else + return false + end + end + self.udp_length = self:u16(self.udp_offset + 4) + self.udp_sum = self:u16(self.udp_offset + 6) + return true +end +-- return short information about tcp packet +function Packet:udp_tostring() + return string.format( + "UDP %s:%i -> %s:%i", + self.ip_src, self.udp_sport, + self.ip_dst, self.udp_dport + ) +end + +function Packet:udp_set_sport(port) + self:set_u16(self.udp_offset + 0, port) +end +function Packet:udp_set_dport(port) + self:set_u16(self.udp_offset + 2, port) +end +function Packet:udp_set_length(len) + self:set_u16(self.udp_offset + 4, len) +end +function Packet:udp_set_checksum(sum) + self:set_u16(self.udp_offset + 6, sum) +end +-- count and save tcp checksum field +function Packet:udp_count_checksum() + self:udp_set_checksum(0) + local length = self.buf:len() - self.udp_offset + local b = self.ip_bin_src .. + self.ip_bin_dst .. + string.char(0) .. + string.char(self.ip_p) .. -- proto + set_u16("..", 0, length) .. + self.buf:sub(self.udp_offset+1) + self:udp_set_checksum(in_cksum(b)) +end +---------------------------------------------------------------------------------------------------------------- + -- UTILS -- get binary string as hex string function bintohex(str)