Strange problem receiving packets on a socket

W

White Spirit

I have the following code to send a packet to a remote socket and
receive a response in return:

System.Net.Sockets.Socket locSocket = new System.Net.Sockets.Socket
(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Tcp);
System.Net.Sockets.Socket remSocket = new System.Net.Sockets.Socket
(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Tcp);
locSocket.Bind (new IPEndPoint (locIP, 2126));

/*

Code to create a packet of data (byte[] datagram) goes here

*/

byte[] receivedPacket = new byte[96];
Console.WriteLine ("Sending packet...");
remoteSocket.SendTo (datagram, remoteEndPoint);
Console.WriteLine ("Packet sent");
locSocket.Receive (receivedPacket);

So far, it seems to work for external hosts but when I try to send a
packet to a port on my computer (say, port 23 for example) I seem to
receive the original packet that I sent to port 2126. I've checked
with wireshark and the packet goes to port 23 as it should, whereupon
a response is sent to port 2126 as expected (I'm communicating with
the network layer and wireshark shows I get an ACK/RST as expected I
have no server listening on port 23).

Is there something I'm doing wrong? Because of the nature of the
application, I'm unable to use connection oriented transmission in
this part of the program.
 
P

Peter Duniho

[...]
Is there something I'm doing wrong? Because of the nature of the
application, I'm unable to use connection oriented transmission in
this part of the program.

I don't know exactly what you're doing wrong, as it's not really even
clear to me what the behavior you're trying to describe is. For example,
you write "So far, it seems to work for external hosts but when I try to
send a packet to a port on my computer (say, port 23 for example) I seem
to receive the original packet that I sent to port 2126". You seem to be
saying that you send the datagram to port 23, but then you say that you
sent it to port 2126. Did you send it to port 23 or port 2126?

You also write "the packet goes to port 23 as it should, whereupon a
response is sent to port 2126 as expected". Reading this statement it
seems as though data in both directions is going exactly where you expect
it to. But if everything's fine, then what is your question?

In other words, I assume you have some problem with the behavior, but you
haven't done very well explaining the problem in an unambiguous way.

All that said however, some things jump out at me in your code...

You don't show us the initialization of "remoteEndPoint", but assuming
this the address of "remoteSocket", then you are sending the datagram from
that socket to itself. The "locSocket" doesn't get involved.

I can't comment on the use of raw sockets with TCP, but it's my
recollection that there is some limitation on the use of raw sockets with
one or the other of TCP and UDP. I just can't recall off the top of my
head where that limitation is. It doesn't sound like this is what you're
running into, but be aware that you don't get carte blanche using raw
sockets under Windows, even running with administrator rights.

I don't think this should affect your code, but there's usually no reason
to use an explicit IP address when binding a socket. Just specify
IPAddress.Any and your socket will bind to whatever the current IP address
(or addresses) exist on the local computer.

Pete
 
D

DeveloperX

I have the following code to send a packet to a remote socket and
receive a response in return:

System.Net.Sockets.Socket locSocket = new System.Net.Sockets.Socket
(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Tcp);
System.Net.Sockets.Socket remSocket = new System.Net.Sockets.Socket
(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Tcp);
locSocket.Bind (new IPEndPoint (locIP, 2126));

/*

Code to create a packet of data (byte[] datagram) goes here

*/

byte[] receivedPacket = new byte[96];
Console.WriteLine ("Sending packet...");
remoteSocket.SendTo (datagram, remoteEndPoint);
Console.WriteLine ("Packet sent");
locSocket.Receive (receivedPacket);

So far, it seems to work for external hosts but when I try to send a
packet to a port on my computer (say, port 23 for example) I seem to
receive the original packet that I sent to port 2126. I've checked
with wireshark and the packet goes to port 23 as it should, whereupon
a response is sent to port 2126 as expected (I'm communicating with
the network layer and wireshark shows I get an ACK/RST as expected I
have no server listening on port 23).

Is there something I'm doing wrong? Because of the nature of the
application, I'm unable to use connection oriented transmission in
this part of the program.

I think you'll need to submit a small runnable bit of code. You're
using SocketType.Raw, so it could be whatever's in the data causing
chaos. Seeing that ACK and RST are set in a packet doesn't mean it
will make it up the stack. I assume wireshark operates at layer 2 (had
to look it up, didn't realise it was Ethereal :)), as it can operate
on ethernet frames, so it might not be making it to layer 3 or
beyond.

Hope that helps.
 
W

White Spirit

Hi,

Basically, I'm sending a SYN packet, in this example to port 80 of a
machine using a raw socket. The header of the packet identifies my
source port as port 2126 together with my IP address. When I use a
remote host such as one of Google's IP addresses in the example below,
the SYN/ACK from Google port 80 is received by my machine on port
2126, as expected. When I try to send a SYN packet to port 80 on my
own computer using any of the available IP addresses (127.0.0.1,
192.168.100.102 and 192.168.0.2), locSocket on port 2126 receives the
packet I sent to myself intended for port 80. In other words, I send
a packet to port 80 on my machine and it shows up on port 2126 in my
application. However, when I use Wireshark to see what is happening,
I don't see any discrepancy in the network layers - wireshark
identifies my SYN packet going from port 2126 to port 80 and the ACK/
RST packet from port 80 to port 2126 in response.

I hope that explains it a bit better. I've attached code below
showing what I'm doing with the remote endpoint. The code I've
skipped deals with building a TCP SYN packet and computing the
checksum.

IPAddress remoteIP = IPAddress.Parse ("64.233.187.99");
IPEndPoint remoteEndPoint = new IPEndPoint (remoteIP, port);

System.Net.Sockets.Socket locSocket = new System.Net.Sockets.Socket
(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Tcp);
System.Net.Sockets.Socket remSocket = new System.Net.Sockets.Socket
(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Tcp);
locSocket.Bind (new IPEndPoint (locIP, 2126));

/*

Code to create a packet of data (byte[] datagram) goes here

*/

byte[] receivedPacket = new byte[96];
Console.WriteLine ("Sending packet...");
remSocket.SendTo (datagram, remoteEndPoint);
Console.WriteLine ("Packet sent");
locSocket.Receive (receivedPacket);
 
D

DeveloperX

Hi,

Basically, I'm sending a SYN packet, in this example to port 80 of a
machine using a raw socket. The header of the packet identifies my
source port as port 2126 together with my IP address. When I use a
remote host such as one of Google's IP addresses in the example below,
the SYN/ACK from Google port 80 is received by my machine on port
2126, as expected. When I try to send a SYN packet to port 80 on my
own computer using any of the available IP addresses (127.0.0.1,
192.168.100.102 and 192.168.0.2), locSocket on port 2126 receives the
packet I sent to myself intended for port 80. In other words, I send
a packet to port 80 on my machine and it shows up on port 2126 in my
application. However, when I use Wireshark to see what is happening,
I don't see any discrepancy in the network layers - wireshark
identifies my SYN packet going from port 2126 to port 80 and the ACK/
RST packet from port 80 to port 2126 in response.

I hope that explains it a bit better. I've attached code below
showing what I'm doing with the remote endpoint. The code I've
skipped deals with building a TCP SYN packet and computing the
checksum.

IPAddress remoteIP = IPAddress.Parse ("64.233.187.99");
IPEndPoint remoteEndPoint = new IPEndPoint (remoteIP, port);

System.Net.Sockets.Socket locSocket = new System.Net.Sockets.Socket
(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Tcp);
System.Net.Sockets.Socket remSocket = new System.Net.Sockets.Socket
(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Tcp);
locSocket.Bind (new IPEndPoint (locIP, 2126));

/*

Code to create a packet of data (byte[] datagram) goes here

*/

byte[] receivedPacket = new byte[96];
Console.WriteLine ("Sending packet...");
remSocket.SendTo (datagram, remoteEndPoint);
Console.WriteLine ("Packet sent");
locSocket.Receive (receivedPacket);

Might have an answer here:

http://www.codeguru.com/forum/showthread.php?t=320739

So it seems your code is fine :)
 
W

White Spirit

Might have an answer here:

So it seems your code is fine :)

The problem is that I send a packet from port 2128 to port 80, try to
receive a packet on port 2128 in response but instead of receiving the
RST/ACK that gets sent *from* port 80, I receive a copy of the packet
I originally sent *to* port 80. I'm aware of the difference between
TCP handshaking on the application and the transport layers - indeed,
I'm relying on it to initiate a half-open connection for a port
scanning application. I just don't understand why my application
behaves as expected when I try to scan a server half way across the
globe but when I try to scan my own machine the packets aren't making
their way to my application. The RST/ACK packets I mentioned were
just a specific instance - if a port is open and I should get a SYN
back from port 80 I still get the original packet that I sent instead.
 
D

DeveloperX

The problem is that I send a packet from port 2128 to port 80, try to
receive a packet on port 2128 in response but instead of receiving the
RST/ACK that gets sent *from* port 80, I receive a copy of the packet
I originally sent *to* port 80. I'm aware of the difference between
TCP handshaking on the application and the transport layers - indeed,
I'm relying on it to initiate a half-open connection for a port
scanning application. I just don't understand why my application
behaves as expected when I try to scan a server half way across the
globe but when I try to scan my own machine the packets aren't making
their way to my application. The RST/ACK packets I mentioned were
just a specific instance - if a port is open and I should get a SYN
back from port 80 I still get the original packet that I sent instead.

I think without a small program that shows the issue it's going to be
nigh on impossible to tell. The CodeGuru post was specifically of
interest in your case because it shows why a hand made SYN doesn't
work on the local machine but will on remote machines. The behaviour
described is a little different to what you're seeing but close enough
to be pertinent. Sorry.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top