Topic : Raw IP Networking FAQ
Author : Thamer Al-Harbash
Page : << Previous 4  Next >>
Go to page :


       Depending on what you want to send, you initially open a
            socket and give it its type.

            sockd = socket(AF_INET,SOCK_RAW,<protocol>);

            You can choose from any protocol including IPPROTO_RAW.
            The protocol number goes into the IP header verbatim.
            IPPROTO_RAW places 0 in the IP header.

            Most systems have a socket option IP_HDRINCL which allows
            you to include your own IP header along with the rest of
            the packet. If your system doesn't have this option, you
            may or may not be able to include your own IP header. If
            it is available, you should use it as such:


            char on = 1;
            setsockopt(sockd,IPPROTO_IP,IP_HDRINCL,&on,sizeof(on));


            Of course, if you don't want to include an IP header, you
            can always specify a protocol in the creation of the
            socket and slip your transport level header under it.

            You then build the packet and use a normal sendto().

            2.2.2) How do I build a TCP/IP packet?
            

            Examples can be found at http://www.whitefang.com/rin/
            which attempt to illustrate the details involved. They
            also illustrate some of the bugs mentioned below.

            Briefly, you need to actually write the packet out in
            memory and hand it over to the socket where it will
            hopefully fire it away and await more packets.

            2.2.3) How can I listen for packets with a raw socket?
            

            Traditionally the BSD socket API did not allow you to
            listen to just any incoming packet via a raw socket.
            Although Linux (2.0.30 was the last version I had a look
            at), did allow this, it has to do with their own
            implementation of the TCP/IP stack. Correct BSD semantics
            allow you to get some packets which match a certain
            category (see below).

            There's a logical reason behind this; for example TCP
            packets are always handled by the kernel. If the port is
            open, send a SYN-ACK and establish the connection, or
            send back a RST. On the other hand, some types of ICMP (I
            compiled a small list below), the kernel can't handle.
            Like an ICMP echo reply, is passed to a matching raw
            socket, since it was meant for a user program to receive
            it.

            The solution is to firewall that particular port if it
            was a UDP or TCP packet, and sniff it with a packet
            capturing API (a list is mentioned above). This prevents
            the TCP/IP stack from handling the packet, thus it will
            be ignored and you can handle it yourself without
            intervention.

            If you don't firewall it, and reply yourself you'll wind
            up having additional responses from your operating
            system!

            Here's a concise explanation of the semantics of a raw
            BSD socket, taken from a Usenet post by W. Richard
            Stevens

            From <rstevens@kohala.com> (Sun Jul 6 12:07:07 1997) :

            "The semantics of BSD raw sockets are:

            -  TCP and UDP: no one other than the kernel gets these.            

            -  ICMP: a copy of each ICMP gets passed to each matching raw      
               socket, except for a few that the kernel generates the reply    
               for: ICMP echo request, timestamp request, and mask request.    

            -  IGMP: all of these get passed to all matching raw sockets.      

            -  all other protocols that the kernel doesn't deal with (OSPF,    
               etc.): these all get passed to all matching raw sockets."        

            After looking at the icmp_input() routine from the
            4.4BSD's TCP/IP stack, it seems the following ICMP types
            will be passed to matching raw sockets:

                Echo Reply: (0)

                Router Advertisement (9)

                Time Stamp Reply (13)

                Mask Reply (18)


        2.3) What bugs should I look out for when using a raw socket?


Page : << Previous 4  Next >>