Thursday, May 3, 2012

Researching Raw Sockets in Unix/Linux/Mac and Windows.

SOCK_RAW



Raw socket in Linux
http://yusufonlinux.blogspot.com/2010/11/raw-socket-in-linux.html


int fd = socket(AF_INET,SOCK_RAW,protocol)
setsockopt(fd,IPPROTO_IP,IP_HDRINCL,&var,sizeof(var)

sendmsg(int fd,struct msghdr*,int flags)
setting IP_HDRINCL socket option allows the application to construct the ip layer packet including the ip header, the kernel only adds the link layer header.



Accord to this article, this interface doesn't allow access to the tcp or udp protocol. For TCP/UDP access the packet socket interface is used.


Here is the man page for socket.

http://linux.die.net/man/7/ip

#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
/* superset of previous */
tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
udp_socket
= socket(AF_INET, SOCK_DGRAM, 0);
raw_socket
= socket(AF_INET, SOCK_RAW, protocol);

Description

Linux implements the Internet Protocol, version 4, described in RFC 791 and RFC 1122. ip contains a level 2 multicasting implementation conforming to RFC 1112. It also contains an IP router including a packet filter.

The programming interface is BSD-sockets compatible. For more information on sockets, see socket(7).

An IP socket is created by calling the socket(2) function as socket(AF_INET, socket_type, protocol). Valid socket types are SOCK_STREAM to open a tcp(7) socket, SOCK_DGRAM to open a udp(7) socket, or SOCK_RAW to open a raw(7) socket to access the IP protocol directly. protocol is the IP protocol in the IP header to be received or sent. The only valid values for protocol are 0 and IPPROTO_TCP for TCP sockets, and 0 and IPPROTO_UDP for UDP sockets. For SOCK_RAW you may specify a valid IANA IP protocol defined in RFC 1700 assigned numbers.

When a process wants to receive new incoming packets or connections, it should bind a socket to a local interface address using bind(2). Only one IP socket may be bound to any given local (address, port) pair. When INADDR_ANY is specified in the bind call, the socket will be bound to all local interfaces. When listen(2) or connect(2) are called on an unbound socket, it is automatically bound to a random free port with the local address set to INADDR_ANY.

A TCP local socket address that has been bound is unavailable for some time after closing, unless the SO_REUSEADDR flag has been set. Care should be taken when using this flag as it makes TCP less reliable.

Here is the packet man page

http://linux.die.net/man/7/packet

#include <sys/socket.h>
#include <netpacket/packet.h>
#include <net/ethernet.h> /* the L2 protocols */

packet_socket = socket(AF_PACKET, int socket_type, int protocol);
 
Packet sockets are used to receive or send raw packets at the device driver (OSI Layer 2) level. They allow the user to implement protocol modules in user space on top of the physical layer.

The socket_type is either SOCK_RAW for raw packets including the link level header or SOCK_DGRAM for cooked packets with the link level header removed. The link level header information is available in a common format in a sockaddr_ll. protocol is the IEEE 802.3 protocol number in network order. See the <linux/if_ether.h> include file for a list of allowed protocols. When protocol is set to htons(ETH_P_ALL) then all protocols are received. All incoming packets of that protocol type will be passed to the packet socket before they are passed to the protocols implemented in the kernel.
 
Only processes with effective UID 0 or the CAP_NET_RAW capability may open packet sockets.



Here are a few linux raw socket example programs: http://www.tenouk.com/Module43a.html

This steps through the process in a clear way:

http://security-freak.net/raw-sockets/raw-sockets.html


One of the first posts in developing the nping command line tool

http://seclists.org/nmap-dev/2009/q2/314  RFC on Nping: Raw packet probing nirvana

There are several tutorials about using pcap:

http://www.tcpdump.org/pcap.html

http://yuba.stanford.edu/~casado/pcap/section1.html
http://yuba.stanford.edu/~casado/pcap/section2.html

http://homes.dico.unimi.it/~gfp/SiRe/2002-03/progetti/libpcap-tutorial.html

There is a version for windows callled winpcap.  http://www.winpcap.org/

And the manual looks very comprehensive:  http://www.winpcap.org/docs/docs_412/html/main.html



Libpcap

I am seeing recommendations to use libpcap http://directory.fsf.org/wiki/Libpcap in order to provide cross platform packet capture support.

Library which provides a packet filtering mechanism based on the BSD packet filter (BPF). Most notably, tcpdump needs this to work, and there is also a perl module (still in beta) which can use this as well. In plain english, if you want to write your own network traffic analyzer, this is the place to start.

Wireshark uses this library.




Windows TCP/IP Raw Sockets

http://msdn.microsoft.com/en-us/library/windows/desktop/ms740548%28v=vs.85%29.aspx



To create a socket of type SOCK_RAW, call the socket or WSASocket function with the af parameter (address family) set to AF_INET or AF_INET6, the type parameter set to SOCK_RAW, and the protocol parameter set to the protocol number required. The protocol parameter becomes the protocol value in the IP header (SCTP is 132, for example).


Once an application creates a socket of type SOCK_RAW, this socket may be used to send and receive data. All packets sent or received on a socket of type SOCK_RAW are treated as datagrams on an unconnected socket.
 
sendto or WSASendTo function is normally used to send data on a socket of type SOCK_RAW.

recvfrom or WSARecvFrom function is normally used to receive data on a socket of type SOCK_RAW.

  • For IPv4 (address family of AF_INET), an application receives the IP header at the front of each received datagram regardless of the IP_HDRINCL socket option.
  • For IPv6 (address family of AF_INET6), an application receives everything after the last IPv6 header in each received datagram regardless of the IPV6_HDRINCL socket option. The application does not receive any IPv6 headers using a raw socket.
  • Received datagrams are copied into all SOCK_RAW sockets that satisfy the following conditions:
    • The protocol number specified in the protocol parameter when the socket was created should match the protocol number in the IP header of the received datagram.
    • If a local IP address is defined for the socket, it should correspond to the destination address as specified in the IP header of the received datagram. An application may specify the local IP address by calling the bind function. If no local IP address is specified for the socket, the datagrams are copied into the socket regardless of the destination IP address in the IP header of the received datagram.
    • If a foreign address is defined for the socket, it should correspond to the source address as specified in the IP header of the received datagram. An application may specify the foreign IP address by calling the connect or WSAConnect function. If no foreign IP address is specified for the socket, the datagrams are copied into the socket regardless of the source IP address in the IP header of the received datagram.
It is important to understand that some sockets of type SOCK_RAW may receive many unexpected datagrams. For example, a PING program may create a socket of type SOCK_RAW to send ICMP echo requests and receive responses. While the application is expecting ICMP echo responses, all other ICMP messages (such as ICMP HOST_UNREACHABLE) may also be delivered to this application. Moreover, if several SOCK_RAW sockets are open on a computer at the same time, the same datagrams may be delivered to all the open sockets. An application must have a mechanism to recognize the datagrams of interest and to ignore all others. For a PING program, such a mechanism might include inspecting the received IP header for unique identifiers in the ICMP header (the application's process ID, for example).


Note  To use a socket of type SOCK_RAW requires administrative privileges. Users running Winsock applications that use raw sockets must be a member of the Administrators group on the local computer, otherwise raw socket calls will fail with an error code of WSAEACCES. On Windows Vista and later, access for raw sockets is enforced at socket creation. In earlier versions of Windows, access for raw sockets is enforced during other socket operations.



No comments:

Post a Comment