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.
Related
When I use TCP I need destination port (to be able to "talk" to other process on the other host) and source port (because TCP is connection oriented so I'll send data back to source like ack, seq and more).
On the other side, UDP which is connectionless needs also source port.
Why is it? (I don't need to send back data)
Probably, two reasons.
First, receivers often need to reply and it is useful to provision a standard tool for that.
Secondly, you may have multiple interfaces (network cards) and using source address, you decide which of them must be used to emit the packet.
You don't need to but there's still the possibility to send a response back (that is very useful actually) however as stated in the RCF 768
Source Port is an optional field, when meaningful, it indicates the port
of the sending process, and may be assumed to be the port to which a
reply should be addressed in the absence of any other information. If
not used, a value of zero is inserted.
https://www.rfc-editor.org/rfc/rfc768
I would like to add to the answers here. Apart from simply knowing what to reply to, the source port can belong to the list of well-known port numbers. These ports specify what kind of data is encapsulated in the UDP (or TCP!) packet.
For example, the source port 530 indicates that the packet contains a Remote Procedure Call, and 520 indicates a Routing Information Protocol packet.
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
Using SNMP queries to the MIB-II objects, how to identify devices acting as routers, ie, forwarding packets?
The only way to identify them is through the identifier, type or description, or can I identify it through the packet traffic?
If you're only looking to tell whether or not they forward traffic, then there is actually a MIB object to tell you just that:
IP-MIB::ipForwarding
ipForwarding OBJECT-TYPE
-- FROM IP-MIB
SYNTAX INTEGER {forwarding(1), notForwarding(2)}
MAX-ACCESS read-write
STATUS current
DESCRIPTION "The indication of whether this entity is acting as an IPv4
router in respect to the forwarding of datagrams received
by, but not addressed to, this entity. IPv4 routers forward
datagrams. IPv4 hosts do not (except those source-routed
via the host).
When this object is written, the entity should save the
change to non-volatile storage and restore the object from
non-volatile storage upon re-initialization of the system.
Note: a stronger requirement is not used because this object
was previously defined."
::= { iso(1) org(3) dod(6) internet(1) mgmt(2) mib-2(1) ip(4) 1 }
How does wireshark interpret physical packets?
As far as I know, all packets look to be the same, so how does it decode them to pass to next higher protocol?
When it's used to capture live traffic it knows the type of the interface and therefore the L2 encapsulation of packets, and when it reads a pcap file, the file has a field in the header indicating network type.
There are probably a number of different mechanisms. You can download the dissectors and study the source to find out the various methods.
I wrote a dissector for a network sniffer and ported it to Ethereal and then Wireshark (or maybe someone else ported it; I don't remember). But the basic logic is that the dissector gets added to the list of possible dissectors. Wireshark calls a dissector and it decodes the packet if it can. If not, it calls the next one in the chain.
In the code I wrote, I simply analyzed the packet (UDP in my situation) to determine if it fit the profile of the desired packet using checksums and known data in the packet. If it decided it was the packet I was interested in I just extracted the various pieces of interesting data from the packet. The function tvb_get_ptr returns a pointer to the start of the data.
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.