There is a simple example about network broadcasting in QtSDK. It is easy to send and receive broadcast information. And in the receiver side, I want to know whose broadcast packet I just received. I try QUdpSocket.peerName() in readyRead signal callback function,but I get empty string. Any clue?
You can retrieve the sender's IP address when reading the packet with QUdpSocket::readDatagram(). You need to pass to readDatagram() a pointer to a QHostAddress in which to store the address:
QHostAddress senderAddress;
yourSocket->readDatagram(&data, size, &senderAddress);
// senderAddress now represents the sender address
You can get the address as a QString or integer from senderAddress if you need to, see the documentation for QHostAddress.
If you want a host name, you can use QHostInfo to do a reverse lookup (but you are not guaranteed to get a name).
From the docs:
Returns the name of the peer as specified by connectToHost(), or an empty QString if connectToHost() has not been called.
So, if you've called connectToHost() you should get a result. You might also try peerAddress(). Unless you always connect via a name, I wouldn't expect that you'll always be able to do a reverse lookup and get a name.
Related
I'm using eBPF and BCC to print out IP addresses of the packets I'm receiving.
For the kernel, I've programmed a code to print out from ip_t -> dst;
which I assume it's an address of the destination.
For the user space, I've programmed a code to print out the user address from the bytecode.
I've checked many times with other variables to see if my program shows me the correct values of data stored within the packet header and it all worked well except for the addresses.
So, for the user level I get : destination ip address = 203.237.53.121
which is the static IP address I have given to the server.
However, when I print out ip_t -> dst, I get : 3421320703
I don't understand why they would have different out puts.
I'm trying to ultimately build a program which I can just aim to get packets only from a specific sender IP address and etc.
It would be great if anyone could help me out.
Thanks :)
I have a machine with 4 Ethernet Interfaces (ensf1s1, ensf1s2, ensf1s3, ensf1f4) and using GNAT.Sockets I need to be able to send/recieve data over each interface.
The code I am using is
Create_Socket(SendFrom1, Family_Inet, Socket_Datagram);
Create_Socket(SendFrom2, Family_Inet, Socket_Datagram);
...
Bind_Socket(SendFrom1, SendFrom1Address);
Bind_Socket(SendFrom2, SendFrom2Address);
...
Channel1 := Stream(SendFrom1, SendToAddress1);
Channel2 := Stream(SendFrom2, SendToAddress2);
...
With IP addresses configured as 192.168.1.(101/102/103/104) I am getting all messages sent over a single interface with the correctly specified Source and Destination IPs in the packet.
I read in another question that having multiple NICs on the same subnet could cause a problem to some OS's so I changed to 192.168.1.101, 192.168.2.102 etc with a Subnet mask of 255.255.0.0. Using the same code with Addresses corrected this only sent data intended for the interface which previously sent all messages but nothing on the other 3.
Have I missed something in my Socket configuration to ensure a Socket is binded to the adaptor with the SendFromAddress specified? The OS is RHEL 7 if that's relevant.
Your question is related to how sockets are working.
If you bind your socket to a specific address, you will receive packets only for that destination address.
To receive packets from any of your four interfaces, you may bind to the INADDR_ANY address. You will do this as follows:
Address : GNAT.Sockets.Sock_Addr_Type;
SendFromAll : GNAT.Sockets.Socket_Type;
...
Address.Port := 0; -- Or whatever fixed port you like
Address.Addr := GNAT.Sockets.Any_Inet_Addr;
GNAT.Sockets.Bind_Socket (SendFromAll, Address);
Using this implementation, the SendFromAll socket will receive data from any interface. With Receive_Socket, you can get the sender address. Then when you send data back to the client using the SendFromAll socket, the system will pick an interface depending on the destination address and the network routing tables. On Linux, it will depend on the routing policy (ip rule) and on the routing tables (ip route).
Client : GNAT.Sockets.Sock_Addr_Type;
Buffer : Ada.Streams.Stream_Element_Array (0 .. 8192);
Last : Ada.Streams.Stream_Element_Offset;
....
GNAT.Sockets.Receive_Socket (SendFromAll, Buffer, Last, Client);
GNAT.Sockets.Send_Socket (SendFromAll, Buffer (Buffer'First .. Last), Last, Client);
Now if you really need to bind a socket to an interface, you must get the IP address of that interface. If you have several interfaces, you have to get their own IP addresses. There is no easy way with GNAT.Sockets to do this. You can use the Get_Host_By_Name function but you must setup different names for each interface (otherwise you'll get the same IP for each socket).
Another way which is not possible with GNAT.Sockets is to use the SO_BINDTODEVICE socket option. You bind the socket to the interface name (you don't need to get the IP).
What may happen to you is that you are using the same IP address for each Bind_Socket call.
I am working on a network module and need to send out packet to specific destinations (think as software router).
I want to send a sk_buff to some IP address, passing it to dev_queue_xmit().
However, I am feeling complex with dst_entry concept.
Can dev_queue_xmit send a skb, without a valid dst_entry, when the skb has necessary link layer info ?
After some testing, I eventually concluded that skb need not have a valid dst_entry for successfully transmitting a packet. All that it needs is a valid buffer, with skb->data pointing to correct mac_header location.
I am using MiWi Pro wireless networking protocol and I was running some tests with unicast function, but I encountered a problem.
Unicast Main Issue:
The end device doesn't receive the messages from its parent coordinator whether the unicast message is sent using the short or long address of the end device.
So let's say we have this configuration.
Coordinator1 has short address of 0300 AND
End_Device1 has short address of 0301
So these are the things I noticed ..
Sending a unicast message from Coordinator1 to End_Device1 either by short or long address doesn't work. However, sending a uincast message from the End_Device1 to Coordinator1 works fine.
I also noticed when you send the message from Coordinator1 to End_Device1, Coordinator1 receives the message even though its the one who sent it. It's really strange because End_Device1 should be receiving the message.
What do you think is preventing the parent coordinator from communicating with its end device and what can be done to fix it?
Coordinator1 if it's the root coordinator it must have the address 0000. you may have some routing problem otherwise.
Are you sure about the address of the end device ? The library is quite confusing on it. I've got a similar problem up to the point I realize the address I toke for the device was actually not the correct one.
probably try to send packets using the permanent address of the RFD device because if there is change in network the short address can be varied so use MiApp_UnicastAddress( longAddressRfd, true, true ) here the 2nd parameter in this function is The boolean to indicate if the destination address above is permanent address or alternative network address.1st parameter is the long address and third parameter is a boolean to indicate the security was enabled or not.try this
If a socket is bound to IN6ADDR_ANY or INADDR_ANY and you use a call such as recvfrom() to receive messages on the socket. Is there a way to find out which interface the message came from?
In the case of IPv6 link-scope messages, I was hoping that the from argument of recvfrom() would have the scope_id field initialized to the interface Id. Unfortunately it is set to 0 in my test program.
Anybody know of a way to find out this information?
dwc is right, IPV6_PKTINFO will work for IPv6 on Linux.
Moreover, IP_PKTINFO will work for IPv4 — you can see details in manpage ip(7)
I've constructed an example that extracts the source, destination and interface addresses. For brevity, no error checking is provided. See this duplicate: Get destination address of a received UDP packet.
// sock is bound AF_INET socket, usually SOCK_DGRAM
// include struct in_pktinfo in the message "ancilliary" control data
setsockopt(sock, IPPROTO_IP, IP_PKTINFO, &opt, sizeof(opt));
// the control data is dumped here
char cmbuf[0x100];
// the remote/source sockaddr is put here
struct sockaddr_in peeraddr;
// if you want access to the data you need to init the msg_iovec fields
struct msghdr mh = {
.msg_name = &peeraddr,
.msg_namelen = sizeof(peeraddr),
.msg_control = cmbuf,
.msg_controllen = sizeof(cmbuf),
};
recvmsg(sock, &mh, 0);
for ( // iterate through all the control headers
struct cmsghdr *cmsg = CMSG_FIRSTHDR(&mh);
cmsg != NULL;
cmsg = CMSG_NXTHDR(&mh, cmsg))
{
// ignore the control headers that don't match what we want
if (cmsg->cmsg_level != IPPROTO_IP ||
cmsg->cmsg_type != IP_PKTINFO)
{
continue;
}
struct in_pktinfo *pi = CMSG_DATA(cmsg);
// at this point, peeraddr is the source sockaddr
// pi->ipi_spec_dst is the destination in_addr
// pi->ipi_addr is the receiving interface in_addr
}
Apart from binding to each interface, I'm not aware of a way with IPv4, per se.
IPv6 has added the IPV6_PKTINFO socket option to address this shortcoming. With that option in effect, a struct in6_pktinfo will be returned as ancillary data.
Its been a while since I've been doing C/C++ TCP/IP coding but as far as I remember on every message (or derived socket) you can get into the IP headers information. These headers should include the receiving address which will be the IP of the interface you are asking about.
Outside of opening a separate socket on each interface as Glomek suggested, the only way I know to do this definitively on Windows is to use a raw socket, e.g.,
SOCKET s = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
Each receive from this socket will be an IP packet, which contains both the source and destination addresses. The program I work on requires me to put the socket in promiscuous mode using the SIO_RCVALL option. Doing this means I get every IP packet the interface "sees" on the network. To extract packets expressly for my application requires me to filter the data using the addresses and ports in the IP and TCP/UDP headers. Obviously, that's probably more overhead than you're interested in. I only mention it to say this - I've never used a raw socket without putting it in promiscuous mode. So I'm not sure if you can bind it to INADDR_ANY and just use it as a regular socket from that point forward or not. It would seem to me that you can; I've just never tried it.
EDIT: Read this article for limitations regarding raw sockets on Windows. This biggest hurdle I faced on my project was that one has to be a member of the Administrators group to open a raw socket on Windows 2000 and later.