I want to include an IP packet in Socket programming. I have a readymade Ip packet which contains igmp packet. I don't want to design igmp protocol but want to use that packet to sent igmp query. By some how the Ip packet I have must be recognize as IP packet and not as TCP/UDP data.
You have to use the raw socket with sendmsg. This need root permission.
And if you want to send IGMP packets you should use the setsockopt() API to do so.
Related
I need to send a multicast udp from multihomed computer. Found that in case socket is not bound to some specific interface, default interface will be used (whatever it could mean). My question: is it possible to specify something like inaddr_any to send multicast udp from all available interfaces or is it only possible to do that by enumerating all interfaces and manually send from each? Is there a standard for that?
Thank you
You can set which network interface IPv4 multicast packets leave from by setting the IP_MULTICAST_IF socket option. The value passed to setsockopt should be the address of a struct in_addr containing the IP address of the interface in question.
If you want to send a multicast packet on multiple interfaces, you'll need to call sendto multiple times, setting the IP_MULTICAST_IF option before each one.
This is a quick question for linux c programming raw sockets. If I wanted to just listen to any interface with a raw socket, must I actually bind to an ip address or interface to listen to traffic? From what I understand, I feel like I should be able to just call sock(); and then start recvfrom() traffic. Maybe I'm wrong, but I've seen some programs that don't use it.
You are right, the only thing you will need to do is call socket() and then recvfrom(). Nevertheless be aware of the fact that there are some limitations with listening using SOCK_RAW.
If you're not using raw sockets on a "send-and-forget" basis, you will
be interested in reading the reply packet(s) for your raw packet(s).
The decision logic for whether a packet will be delivered to a raw
socket can be enumarated as such:
TCP and UDP packets are never delivered to raw sockets, they are always handled by the kernel protocol stack.
Copies of ICMP packets are delivered to a matching raw socket. For some of the ICMP types (ICMP echo request, ICMP timestamp request,
mask request) the kernel, at the same time, may wish to do some
processing and generate replies.
All IGMP packets are delivered to raw sockets: e.g. OSPF packets.
All other packets destined for protocols that are not processed by a kernel subsystem are delivered to raw sockets.
The fact that you're dealing with a protocol for which reply packets
are delivered to your raw socket does not necessarily mean that you'll
get the reply packet. For this you may also need to consider:
setting the protocol accordingly while creating your socket via socket(2)system call. For instance, if you're sending an ICMP
echo-request packet, and want to receive ICMP echo-reply, you can set
the protocol argument (3rd argument) to IPPROTO_ICMP).
setting the protocol argument in socket(2) to 0, so any protocol number in the received packet header will match.
defining a local address for your socket (via e.g. bind(2)), so if the destination address matches the socket's local address, it'll be
delivered to your application also.
For more details you can read e.g. this.
If you meant to capture the traffic on a interface, you can use libpcap.
I have a very simple question that I cannot seem to find an answer for anywhere:
Using Linux C sockets, is it possible to bind() and then recvfrom() UDP packets on an IP address other than the local address?
i.e, if a host has been given the LAN address 10.0.0.4, and I want it to be able to receive UDP packets sent to the address 10.0.0.5 on port 5505 (for example) how would this be achieved?
I simply cannot find any examples of this use of bind/recvfrom, which seems like it should be quite commonplace.
Update
I am trying to communicate packet streams between multiple hosts. Each host streams UDP packets on its own address, and any of the other hosts can listen in by recvfrom()ing on a specific address.
No, you can't generally bind to a non-local unicast address. On an Ethernet, such packets would be addressed to the hardware address of the owner of that IP address, and by default you NIC won't even forward such packets to your kernel.
You can achieve the effect you want by using IP Multicast. You would pick a particular multicast address for your application and bind to that, and then use the IP_ADD_MEMBERSHIP socket option to join the multicast group. You can then use recvfrom() in the usual way.
How do I send UDP packet from a specific interface on Linux using C? Should I use bind? Is it possible to send UDP from the interface not having IP address?
Thanks.
Use bind. You cannot send UDP packets via an interface that does not have an IP address, because UDP uses the Internet Protocol and the Internet Protocol requires an IP address.
You can bind a socket to a specific interface by using the SO_BINDTODEVICE socket option, however this requires root privileges.
Alternately, you can set the IP_PKTINFO option, and use sendmsg for sending, setting the in_pktinfo's ipi_ifindex to the index of your interface.
You need to use socket option IP_MULTICAST_IF.
See here: Multicast-HOWTO-6.html
I'm working on a client-server application written in C. I want to broadcast a message to all the machines available on the local network.
How can I do that using the usual socket system calls in C?
Just send the message to the broadcast address of your subnet, which for 192.168.0.0/24 is 192.168.0.255, or just broadcast to 255.255.255.255.
you have to use UDP to send a broadcast message over a network. when creating your socket using the socket() function, specify AF_INET for the family parameter and SOCK_DGRAM for the type parameter. on some systems, you have to enable the sending of broadcast packet by setting the SO_BROADCAST socket option to 1, using setsockopt().
then use the sendto() function call to send a datagram, and use 255.255.255.255 as the destination address. (for datagram sockets, you don't need to call connect(), since there is no 'connection').
in standard implementations, this address broadcasts to all computer in the local network, this means that the packet will not cross gateway boundaries and will not be received by computers using a network mask diferent from the network mask of the sending computer.
Have a look at UDP sockets.
I recomend Beej's Guide to Network Programming. Have a look at 6.3 Datagram Sockets
You can use the special address of 255.255.255.255 to send a broadcast message to every computer on the local network.
For more info see section IP Network Broadcasting.