Closed varnerac closed 8 years ago
Use procket:sendto/4. Similar to an unconnected datagram packet, since the OS doesn't know where the packet is being sent, we have to provide a struct sockaddr_in.
Here's a version of your code I tested on linux:
-module(raw_syn).
-export([
make_ipv4_syn/0,
make_ipv4_syn_test/0
]).
-include_lib("pkt/include/pkt.hrl").
-ifdef(TEST).
-include_lib("eunit/include/eunit.hrl").
-endif.
-define(IP_HDRINCL, 3).
make_ipv4_syn() ->
IPID = rand:uniform(16#ffff) - 1,
SeqNo = rand:uniform(16#ffffffff) - 1,
TCPHdr = #tcp{dport = 8080,
seqno = SeqNo,
syn = 1,
win = 5840}, % header size 20 bytes
IPv4Hdr = #ipv4{id = IPID,
df = 1,
len = 40, % 20 for TCPHdr and 20 for IPv4HDR
saddr = {127, 0, 0, 1},
daddr = {127, 0, 0, 1}}, % header size 20 bytes
IPCheckSum = pkt:makesum([IPv4Hdr, TCPHdr, <<>>]),
I = pkt:ipv4(IPv4Hdr#ipv4{sum=IPCheckSum}),
T = pkt:tcp(TCPHdr),
<<I/binary, T/binary>>.
-define(IPPPROTO_TCP, 6).
%% based on http://www.binarytides.com/tcp-syn-portscan-in-c-with-linux-sockets/
make_ipv4_syn_test() ->
Packet = make_ipv4_syn(),
IPPROTO_TCP = case os:type() of
{unix,linux} -> procket:ntohs(?IPPROTO_TCP);
_ -> ?IPPROTO_TCP
end,
{ok, Socket} = procket:open(0, [{protocol, IPPROTO_TCP}, {type, raw}, {family, inet}]),
ok = procket:setsockopt(Socket, ?IPPROTO_IP, ?IP_HDRINCL, <<1:32/native>>),
Sockaddr_in = <<
(procket:sockaddr_common(?PF_INET, 16))/binary,
8080:16, % destination port
127,0,0,1, % destination IPv4 address
0:64 % pad
>>,
procket:sendto(Socket, Packet, 0, Sockaddr_in).
Sending the SYN:
$ sudo tcpdump -n -s0 -X -i lo port 8080
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo, link-type EN10MB (Ethernet), capture size 65535 bytes
17:32:53.585891 IP 127.0.0.1.0 > 127.0.0.1.8080: Flags [S], seq 2076729285, win 5840, length 0
0x0000: 4500 0028 28ec 4000 4006 13e2 7f00 0001 E..((.@.@.......
0x0010: 7f00 0001 0000 1f90 7bc8 5fc5 0000 0000 ........{._.....
0x0020: 5002 16d0 0000 0000 P.......
The source port is 0 because we didn't set it in make_ipv4_syn/0. The other quirk is that Linux requires the protocol number to be in host byte order while, if I remember correctly, the BSDs use network byte order. Thanks for reminding me about the rebar3 branch, I forgot to merge it!
Hey,
I am trying to send a TCP SYN packet for a SYN scan from
procket
usingpkt
. I am on OS X and I'm using therebar3
branch ofprocket
and running the code asroot
. I'm mimicking this C code: http://www.binarytides.com/tcp-syn-portscan-in-c-with-linux-sockets/I receive
**error:{badmatch,{error,enotconn}}
fromok = procket:write(Socket, Packet)
. Is there something simple I am missing?