I'm trying to send some data over TCP using Net::RawIP in Perl. Unfortunately i get the error
sendto() at /usr/lib/x86_64-linus-gnu/perl5/5.24/Net/RawIP.pm line 630
if the TCP data field is bigger than about 1470 characters:
my $n = Net::RawIP->new({
ip => {
saddr => '[src]',
daddr => '[dst]',
},
tcp => {
source => 7777,
dest => 7777,
data => "x" x 150
}
});
$n->send;
works, but
my $n = Net::RawIP->new({
ip => {
saddr => '[src]',
daddr => '[dst]',
},
tcp => {
source => 7777,
dest => 7777,
data => "x" x 1500 # size changed here
}
});
$n->send;
crashes. Any ideas why this happens?
You're building a packet that's too large, so sendto is returning error EMSGSIZE.
EMSGSIZE
The socket type requires that message be sent atomically, and the size of the message to be sent made this impossible.
It's no mystery it starts failing around 1500; that's the maximum an Ethernet frame can carry.
You need to use multiple packets or multiple packet fragments.
Related
I want to create a server-client connection where a client send a request packet to the server then return a value back to the user. I can get the server to read the incoming packet from the client, but when it write back to the client, the client is not receiving the packet.
I have the size of string in Client and Server matches to ensure the read is not waiting for more incoming packet.
Server
Buffer : Ada.Streams.Stream_Element_Array (1 .. 10);
Offset : Ada.Streams.Stream_Element_Offset;
...
GNAT.Sockets.Create_Socket (Socket => Receiver);
GNAT.Sockets.Set_Socket_Option
(Socket => Receiver,
Option => (Name => GNAT.Sockets.Reuse_Address, Enabled => True));
GNAT.Sockets.Bind_Socket
(Socket => Receiver,
Address => (Family => GNAT.Sockets.Family_Inet,
Addr => GNAT.Sockets.Inet_Addr ("127.0.0.1"),
Port => 12321));
GNAT.Sockets.Listen_Socket (Socket => Receiver);
GNAT.Sockets.Accept_Socket
(Server => Receiver,
Socket => Connection,
Address => Client);
Channel := GNAT.Sockets.Stream (Connection);
Ada.Streams.Read(Stream => Channel.all,
Item => Buffer,
Last => Offset);
for J in 1..Offset loop
Ada.Text_IO.Put_Line(Character'Val(Integer (Buffer (J)))'Img);
end loop;
String'Write(GNAT.Sockets.Stream (Connection), "1234567890");
GNAT.Sockets.Close_Socket (Connection);
Client
input : String(1..10);
output : String(1..10);
...
Initialize;
Create_Socket (Socket => Client);
Connect_Socket (Socket => Client,
Server => (Family => Family_Inet,
Addr => Inet_Addr ("127.0.0.1"),
Port => 12321));
String'Write (Stream (Client), Input);
String'Read (Stream (Client), output); --hanging right here
Close_Socket (Client);
For some reason, the client is getting the message now. The code above works as intended
I'm using Net::RawIP to send packets with specific TCP flags. Is there a way to set the CWR flag?
TCP protokey "res2" sets the ECE flag, but "res1" seems to set the NS flag:
$n = Net::RawIP->new({
ip => {
saddr => 'my.target.lan',
daddr => 'my.target.lan',
},
tcp => {
source => 123,
dest => 123,
res1 => 1,
res2 => 1,
fin => 1,
syn => 1
}
});
Here's a Wireshark capture of the packet's flags:
res2 is two bits wide.
res2 => 1 # ECE
res2 => 2 # CWR
res2 => 3 # ECE & CWR
(It might be the opposite on big-endian machines, but I doubt it.)
(res1 is the 4 bits labeled as "Reserved" and "Nonce" in the Wireshark capture.)
Can i set Maximum segment size to some value when using Net::RawIP?
I am trying the below code but don't know how can i set MSS value in TCP options to custom value.
#!/usr/bin/perl
use Net::RawIP;
$packet = new Net::RawIP;
$packet->set({
ip => {
saddr => '192.168.122.128',
daddr => '192.168.122.1'
},
tcp => { source => 2323,
dest => 8080,
syn => 1,
seq => 100,
ack_seq => 0,
data => 'hello world'
}
});
$packet->optset(tcp => { type => [ (2) ], data => [ (10) ] });
$packet->send(0, 1);
According to the documentation:
optset(OPTPROTO => { type => [...],data => [...] },...)
[...] The value of the data also is an array reference. This array must be filled with strings which must contain all bytes from a option except bytes with type and length of an option.
(emphasis added)
You're passing a reference to an array of integers; you need to pass a reference to an array of strings. Try something like this:
$packet->optset( tcp => { type => [ 2 ], data => [ "\x00\x0A" ] } );
The length of the maximum segment size field is 4, which includes one byte for the kind field, one byte for the length field, and two bytes for the data itself, so you need to pass a two-byte string as above.
According to the cpan documentation I can create a raw packet with the following code:
use Net::RawIP;
$n = Net::RawIP->new({
ip => {
saddr => 'my.target.lan',
daddr => 'my.target.lan',
},
});
tcp => {
source => 139,
dest => 139,
psh => 1,
syn => 1,
},
});
$n->send;
But where do I declare the data the packet contains?
Can I send the packet with another module?
Since you are sending a tcp packet you need as the documentations says to specify:
$n = Net::RawIP->new({
ip => {
saddr => 'my.target.lan',
daddr => 'my.target.lan',
},
tcp => {
source => 139,
dest => 139,
psh => 1,
syn => 1,
data => $your_data
},
});
I need to change the tcp/ip headers of packets caught with Net::PCAP. I know this is possible with Net::RawIP, but this doesn't work under windows?
Is there a module for this that works with windows? Is there at least to do this in windows with another programming language that I can call in perl, such as C?
To demonstrate what I want to do, here is the code using Net::RawIP, which does not work under windows because I can't install the module:
$n = Net::RawIP->new({
ip => {
saddr => 'my.target.lan',
daddr => 'my.target.lan',
},
tcp => {
source => 139,
dest => 139,
psh => 1,
syn => 1,
data => $your_data
},
});
$n->send();
Try pcap_sendpacket using this per module https://metacpan.org/pod/Net::Pcap