I have an application that sends broadcast messages and listens for response packets. Below is the code snippet.
m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
m_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
m_socket.Bind(new IPEndPoint(IPAddress.Any, 2000));
m_socket.BeginSendTo(
buffer,
0,
buffer.Length,
SocketFlags.None,
new IPEndPoint(IPAddress.Broadcast, 2000),
Callback),
null
);
When I run the application the broadcast message was not being sent. On my machine I have three network adapters. One is my local network adapter and other two are VMWare network virtual adapters. When I run my application I can see (using wireshark network capture) that the broadcast message is being sent from one of the VMWare network adapters.
I would like to modify the code so that the broadcast message will be sent from all network adapters on the pc. What is the best way to do that?
You can use the following to get all your IP Addresses (and a lot more). So you can iterate through the list and bind (like Jon B said) to the specific IP you want when you send out your multicast.
foreach (var i in System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces())
foreach (var ua in i.GetIPProperties().UnicastAddresses)
Console.WriteLine(ua.Address);
When you call Bind(), you are setting the local IP end point. Instead of using IPAddress.Any, use the IP address of the NIC that you want to send from. You'll need to do this separately for each NIC.
Check this http://salaam.codeplex.com/
I and my friend developed a class library called Salaam. download the source code or use the binaries (.dll) to use it.
You can use IPAddress.Any when constructing the tcpListener. This will bind the tcp listener to all interfaces
Related
I have a laptop which has a wireless adapter with ip address "192.168.5.60". This laptop will send UDP Multicast packets.
I have a desktop pc which has a network adapter ip ""192.168.5.90". I installed a software named "Multicast Tester" which joins multicast group("239.194.190.22:4000") on this desktop pc.
Problem is if i use another software which i installed from internet on laptop and send multicast udp packets to "239.194.190.22:4000" i can receive these packets in desktop pc.
If I use my program to send these packets, i can't receive multicast packets.
My code :
UdpClient udpClient = new UdpClient();
udpClient.client.bind(new IPEndPoint(IPAddress.Parse("192.168.5.60"), 0));
udpClient.JoinMulticastGroup(IPAddress.Parse("239.194.190.22"));
udpClient.send(myData, myData.length, new IPEndPoint(IPAddress.Parse("239.194.190.22"), 4000));
Note : Both computers have multiple nics.
From your description, the problem is that your sender is sending out its system default multicast interface which happens to be an interface not on the link with the 192.168.5/24 network. If you use IP_MULTICAST_IF with either the sender's ip or the index of the interface (as shown by ipconfig) instead of IP_MULTICAST_TTL then the TTL of 1 is fine since you are then using the shared link, i.e:
_udpClient.Client.SetSocketOption(SocketOptionLevel.IP,
SocketOptionName.MulticastInterface, IPAddress.Parse("192.168.5.60").GetAddressBytes());
(Where you may need to do some more work on the address to make it a DWORD in network order, and based on ip options and enums)
I just solved it. It looks like default TTL value for UDP Multicast packets is '1'. !
I changed it to '16' by using this code:
_udpClient.Client.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MuticastTimeToLive, 16);
I need something simillar to this:
var client = new UdpClient();
IPEndPoint ep = new IPEndPoint(IPAddress.Parse("23.114.44.195"), 11000);
client.Connect(ep);
byte[] data = Encoding.ASCII.GetBytes("test");
client.Send(data, data.Length);
The listener runs on that IP at PORT: 11000, but i don't want to port forward in my router (because I want to publish this app).
So, here is the question: How to send string via UDP without Port Forwarding?
You can use NAT hole punching, which doesn't require manual port forwarding configuration. It's quite simple technique. Please note that remote endpoint (receiver) should implement it too, not just sender.
In the simplest case, it works as:
[sender] <-> |internet| <-> [remote router with NAT] <-> [receiver]
Please note sender is not behind NAT.
To punch a hole from senderIP:portX to receiverIP:portY:
sender binds to portX and waits for communication initialisation from receiver. receiver binds to portY and sends a dummy packet to senderIP:portX. sender gets receiverIP (which is actually its router IP) and portY from the package and now sends meaningful data to this address. NAT remembered that communication with senderIP:portX was going from receivers local IP and portY, so all data coming from senderIP:portX to the router's portY will be redirected to receivers local IP.
For the case when both sender and receiver are behind NATs, you need a rendezvous server, for details check the link.
Recently I completed my network sniffer for the company that I am currently working with.
I want to know:
Is there any way to edit the captured packets before reaching the destination? (UDP/TCP)
Is there any other procedure to capture packets?
Here is my code template/procedure:
1. At first, when loading I get all the devices/hostnames on the computer.
IPHostEntry HostEntry = Dns.GetHostEntry((Dns.GetHostName()));
2. For sniffing the socket to capture the packets has to be a raw socket, with the address family being of type internetwork, and protocol being IP.
mainSocket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP);
3. Bind the socket to the selected IP address.
mainSocket.Bind(new IPEndPoint(IPAddress.Parse(TEXT-OF-YOUR-HOST-ENTRY), 0));
4. Set the socket options.
5. Capture outgoing packets to byte[] array.
mainSocket.IOControl(IOControlCode.ReceiveAll, YOUR-TRUE-BYTES, YOUR-OUTGOING-BYTES);
6. Start receiving the packets asynchronously.
mainSocket.BeginReceive(BYTE-DATA, 0, BYTE-DATA-LENGTH, SocketFlags.None, new AsyncCallback(YOUR-RECEIVE-FUNCTION), null);
7. Analyze/Parse the bytes received. And don't forget to call another to BeginReceive so that we continue to receive the incoming packets.
8. Finally for parsing, you can create your own class or using the already invented classes/dlls to study your captured packages.
Thats all I have.
I hope this helps for someone trying to start some network sniffer in C#.
I hope that someone shows me the better ways to do this.
Also is there any chance to edit the packages I captured before they reach their destination?
Thank you for your time.
I am using C# sockets to have a connection between a device (client) and a computer (server).
All is working good except for the fact that I am trying to avoid the user to enter the IP address and port number wherein to connect to on the device. Instead I want a listbox or drop down list of all IP addresses with listening sockets. Just wondering if there's a way to get all the IP addresses and port numbers of hosts with listening (socket)?
Thanks for any help! :)
What you're asking to do is called a port scan. It basically involves testing each IP address in a range and each port and reporting the success of that attempt. It's slow and it will cause a lot of alarms if there is any kind of threat monitoring on the network because port scanning is one of the ways attackers try to find network vulnerabilities.
So in short, this is a bad idea and probably won't be responsive enough for you to use for this purpose. Instead what you might consider is using a central server as a "directory" that each server would register with.
Or you can send out a broadcast on your subnet and wait for servers to respond. This is how some of the peer networking works in Windows for example. Note that this assumes you are the developer of the server as well and you can add in the logic necessary for the server to listen for broadcasts.
By using UDP broadcast, you can send out the data to the Server which are listening at the fixed port. The following is the working example.
foreach (IPAddress ip in allLocalNetworkAddresses.AddressList)
{
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
//Allow sending broadcast messages
client.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.Broadcast, 1);
//Create endpoint, broadcast.
IPEndPoint AllEndPoint = new IPEndPoint(IPAddress.Broadcast, Port);
byte[] sendData = Encoding.ASCII.GetBytes("1");
//Send message to everyone on this network
client.SendTo(sendData, AllEndPoint);
Console.Write("Client send '1' to " + AllEndPoint.ToString() +
Environment.NewLine);
I am being sent an xml feed via multicast, but I don't know the multicast group address. Can I just use localhost instead?
Socket socket =
new Socket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);
IPEndPoint ip = new IPEndPoint(IPAddress.Any,8888);
socket.Bind(ip);
socket.SetSocketOption
(SocketOptionLevel.IP,
SocketOptionName.AddMembership,
new MulticastOption(IPAddress.Parse("127.0.0.1"),IPAddress.Any));
byte[] data = new byte[1024];
int length = socket.Receive(data);
...
No.
You (your client) needs to join the multicast group, you'll AddMembership to the multicast group IP, then connect.
Otherwise you won't be able to receive the multicast feed. Your code would work with a UDP broadcast though.
Strictly speaking, if you open a listening port for multicast data on a non-multicast address, then you are essentially listening to standard UDP. The difference between multicast and UDP is in the IP address. Its a special IPV4 address range that is not tied to a fixed host. Rather it is recognized by the routers on the edges of your network in a pseudo publish-subscribe fashion. Within your sub-net multicast is for all intents and purposes the same as broadcast.
If you write to a multicast address, it is available to all hosts on your subnet. If your router supports multicast, then it will provide it upstream to any clients that announce that they are interested in it. THink of it as publish/subscribe for subnets.
All of this to say, if you are looking for a localhost equivalent to multicast, then you probably need to look at broadcast instead.
Unlike unicast, you do need to know the group address for multicast.