- TCP/IP Raw Sockets
- Determining if Raw Sockets are Supported
- Creating a Raw Socket
- Send and Receive Operations
- Common Uses of Raw Sockets
- Limitations on Raw Sockets
- Raw socket programming on windows with winsock
- Raw sockets using winsock
- Coding Raw Sockets
- IP and TCP Headers
- Raw Socket support on Windows
- 8 thoughts on “ Raw socket programming on windows with winsock ”
TCP/IP Raw Sockets
A raw socket is a type of socket that allows access to the underlying transport provider. This topic focuses only on raw sockets and the IPv4 and IPv6 protocols. This is because most other protocols with the exception of ATM do not support raw sockets. To use raw sockets, an application needs to have detailed information on the underlying protocol being used.
Winsock service providers for the IP protocol may support a socket type of SOCK_RAW. The Windows Sockets 2 provider for TCP/IP included on Windows supports this SOCK_RAW socket type.
There are two basic types of such raw sockets:
- The first type uses a known protocol type written in the IP header that is recognized by a Winsock service provider. An example of the first type of socket is a socket for the ICMP protocol (IP protocol type = 1) or the ICMPv6 protocol (IP procotol type = 58).
- The second type allows any protocol type to be specified. An example of the second type would be an experimental protocol that is not directly supported by the Winsock service provider such as the Stream Control Transmission Protocol (SCTP).
Determining if Raw Sockets are Supported
If a Winsock service provider supports SOCK_RAW sockets for the AF_INET or AF_INET6 address families, the socket type of SOCK_RAW should be included in the WSAPROTOCOL_INFO structure returned by WSAEnumProtocols function for one or more of the available transport providers.
The iAddressFamily member in the WSAPROTOCOL_INFO structure should specify AF_INET or AF_INET6 and the iSocketType member of the WSAPROTOCOL_INFO structure should specify SOCK_RAW for one of the transport providers.
The iProtocol member of the WSAPROTOCOL_INFO structure may be set to IPROTO_IP. The iProtocol member of the WSAPROTOCOL_INFO structure may also be set to zero if the service provider allows an application to use a SOCK_RAW socket type for other network protocols other than the Internet Protocol for the address family.
The other members in the WSAPROTOCOL_INFO structure indicate other properties of the protocol support for SOCK_RAW and indicate how a socket of SOCK_RAW should be treated. These other members of the WSAPROTOCOL_INFO for SOCK_RAW normally specify that the protocol is connectionless, message-oriented, supports broadcast/multicast (the XP1_CONNECTIONLESS, XP1_MESSAGE_ORIENTED, XP1_SUPPORT_BROADCAST, and XP1_SUPPORT_MULTIPOINT bits are set in the dwServiceFlags1 member), and can have a maximum message size of 65,467 bytes.
On WindowsВ XP and later, the NetSh.exe command can be used to determine if raw sockets are supported. The following command run from a CMD window will display data from the Winsock catalog on the console:
netsh winsock show catalog
The output will include a list that contains some of the data from the WSAPROTOCOL_INFO structures supported on the local computer. Search for the term RAW/IP or RAW/IPv6 in the Description field to find those protocols that support raw sockets.
Creating a Raw Socket
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).
An application may not specify zero (0) as the protocol parameter for the socket, WSASocket, and WSPSocket functions if the type parameter is set to SOCK_RAW.
Raw sockets offer the capability to manipulate the underlying transport, so they can be used for malicious purposes that pose a security threat. Therefore, only members of the Administrators group can create sockets of type SOCK_RAW on WindowsВ 2000 and later.
Send and Receive Operations
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.
The following rules apply to the operations over SOCK_RAW sockets:
The sendto or WSASendTo function is normally used to send data on a socket of type SOCK_RAW. The destination address can be any valid address in the socket’s address family, including a broadcast or multicast address. To send to a broadcast address, an application must have used setsockopt with SO_BROADCAST enabled. Otherwise, sendto or WSASendTo will fail with the error code WSAEACCES. For IP, an application can send to any multicast address (without becoming a group member).
When sending IPv4 data, an application has a choice on whether to specify the IPv4 header at the front of the outgoing datagram for the packet. If the IP_HDRINCL socket option is set to true for an IPv4 socket (address family of AF_INET), the application must supply the IPv4 header in the outgoing data for send operations. If this socket option is false (the default setting), then the IPv4 header should not be in included the outgoing data for send operations.
When sending IPv6 data, an application has a choice on whether to specify the IPv6 header at the front of the outgoing datagram for the packet. If the IPV6_HDRINCL socket option is set to true for an IPv6 socket (address family of AF_INET6), the application must supply the IPv6 header in the outgoing data for send operations. The default setting for this option is false. If this socket option is false (the default setting), then the IPv6 header should not be included in the outgoing data for send operations. For IPv6, there should be no need to include the IPv6 header. If information is available using socket functions, then the IPv6 header should not be included to avoid compatibility problems in the future. These issues are discussed in RFC 3542 published by the IETF. Using the IPV6_HDRINCL socket option is not recommended and may be deprecated in future.
The recvfrom or WSARecvFrom function is normally used to receive data on a socket of type SOCK_RAW. Both of these functions have an option to return the source IP address where the packet was sent from. The received data is a datagram from an unconnected socket.
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).
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.
Common Uses of Raw Sockets
One common use of raw sockets are troubleshooting applications that need to examine IP packets and headers in detail. For example, a raw socket can be used with the SIO_RCVALL IOCTL to enable a socket to receive all IPv4 or IPv6 packets passing through a network interface. For more information, see the SIO_RCVALL reference.
Limitations on Raw Sockets
On WindowsВ 7, WindowsВ Vista, WindowsВ XP with Service PackВ 2 (SP2), and WindowsВ XP with Service PackВ 3 (SP3), the ability to send traffic over raw sockets has been restricted in several ways:
TCP data cannot be sent over raw sockets.
UDP datagrams with an invalid source address cannot be sent over raw sockets. The IP source address for any outgoing UDP datagram must exist on a network interface or the datagram is dropped. This change was made to limit the ability of malicious code to create distributed denial-of-service attacks and limits the ability to send spoofed packets (TCP/IP packets with a forged source IP address).
A call to the bind function with a raw socket for the IPPROTO_TCP protocol is not allowed.
The bind function with a raw socket is allowed for other protocols (IPPROTO_IP, IPPROTO_UDP, or IPPROTO_SCTP, for example).
These above restrictions do not apply to Windows ServerВ 2008В R2, Windows ServerВ 2008 , Windows ServerВ 2003, or to versions of the operating system earlier than WindowsВ XP with SP2.
The Microsoft implementation of TCP/IP on Windows is capable of opening a raw UDP or TCP socket based on the above restrictions. Other Winsock providers may not support the use of raw sockets.
There are further limitations for applications that use a socket of type SOCK_RAW. For example, all applications listening for a specific protocol will receive all packets received for this protocol. This may not be what is desired for multiple applications using a protocol. This is also not suitable for high-performance applications. To get around these issues, it may be required to write a Windows network protocol driver (device driver) for the specific network protocol. On WindowsВ Vista and later, Winsock Kernel (WSK), a new transport-independent kernel mode Network Programming Interface can be used to write a network protocol driver. On Windows ServerВ 2003 and earlier, a Transport Driver Interface (TDI) provider and a Winsock helper DLL can be written to support the network protocol. The network protocol would then be added to the Winsock catalog as a supported protocol. This allows multiple applications to open sockets for this specific protocol and the device driver can keep track of which socket receives specific packets and errors. For information on writing a network protocol provider, see the sections on WSK and TDI in the Windows Driver Kit (WDK).
Applications also need to be aware of the impact that firewall settings may have on sending and receiving packets using raw sockets.
Raw socket programming on windows with winsock
Raw sockets using winsock
Raw sockets or «Raw Packets», enable a program to access the entire contents of a packet or datagram, both for reading and writing purpose.
In other words, you can fabricate a whole packet according to your likes and dislikes. For example, a TCP packet would contain an IP header, a TCP header, and then the actual data that needs to be transmitted.
When working with normal sockets, whatever we send to a socket is actually the data part. In such a scenario, the OS network stack takes the responsibility of adding the header with all fields set to relevant values.
When we send the data to a destination, the stack adds the headers and sends the packet, and when we receive some data, then the stack removes the headers and hands out the data to our application. So we are saved from the work of designing the headers.
For normal internet applications, there is no need to be concerned about the header operations as they are there for the safe transmission and reception of data, and once the transfer is complete, they are discarded. But there are applications that need raw sockets.
Raw sockets are widely used in the field of network security for creating both security and insecurity!
Coding Raw Sockets
In this article, we will take a look at the contents of a general TCP packet, and try to make a raw packet and transmit it.
We shall do this on Windows XP using the VC++ 6.0 compiler.
The examples shown here would construct a raw tcp packet and send it over the network interface.
Winsock has limited raw socket support across various version of windows, as discussed later on. As an alternative you can create raw sockets on windows using the winpcap library as well.
IP and TCP Headers
OK, so let’s have a look at the IP and TCP headers.
RFC 791 gives the structure of an IP header as:
Next comes the TCP header for transmission using the TCP protocol. RFC 793 gives the structure.
and at the end is your data, bla bla bla bla bla bla…………………..
To understand the significance of each field, read up the necessary RFC or some other good TCP/IP tutorial on the net as there are plenty.
If you have some knowledge of socket programming, then the headers should be self-explanatory. Now, why is the raw socket feature of importance to network security ?
Well, one important aspect of network security which needs this feature is scanning. Scanning is of many types. For example, scanning for open ports, scanning the type of OS, scanning for vulnerabilities etc.
Raw Socket support on Windows
First of all, it must be understood very clearly that raw sockets is not a feature of the network API (although it must be present there as an option) but of the «OS protocol stack».
To implement raw sockets, all we have to do is to inform the OS that the packet buffer we are providing will have the header and so the OS should transmit it as is without «adding any header»; that’s all, nothing more to do.
Operating systems like Linux have full raw socket support.
But the problem is with Windows. None of Windows 95, 98, 98SE supported raw sockets.
Raw sockets became available on Windows from Windows 2000; Windows XP continued this. But suddenly, raw socket support was removed from Windows XP through a patch in SP2. Vista doesn’t have it.
A security patch called MS05-019 (http://support.microsoft.com/kb/897656) is what disables raw sockets on XP SP2 and can do the same to even SP1.
Probably Windows 2003 SP1 also implements the same the result being the end of raw sockets.
An indepth summary is available at http://seclists.org/nmap-hackers/2005/0005.html. Windows 95, 98, 98SE do not support raw sockets, but this doesn’t end the story.
If you want the facility, then the solution is to use a third party packet driver like Winpcap. Winpcap can capture and send raw packets of all kinds.
Windows XP and XP SP1 have full raw socket support and so life is easy. So if you want to do raw socketing on Windows, then either use Winpcap or don’t feel desperate to install SP2, or otherwise use Windows 2003 which, as per my knowledge, has raw socket support. http://technet.microsoft.com/hi-in/library/bb457156(en-us).aspx should tell more.
So let’s brief up:
Note : Winsock Ver. > 2.0
So if your system does not support raw sockets, then switch to Linux or use Winpcap. There are articles on this site that explain how to use winpcap to send raw packets. Search for them.
The last line, setsockopt, tells the OS that the socket s will have the header included (IP_HDRINCL) at the IP (IPPROTO_IP) level in the data buffer it sends. IPPROTO_RAW creates an absolutely raw socket, and you have to write all headers yourself. IPPROTO_UDP, IPROTO_TCP are also available for the respective types of packets.
Now, we shall need two structures like this:
Did you notice a difference between the RFC specification and the structures declared above? IP header and version have swapped their positions.The urg, ack, and psh flags of the TCP header are all in reverse order ? Mistake ?
Well, this depends on the byte order that is implemented in the machine architecture. There are two types: Little Endian and Big Endian.
In Big Endian, the bytes and bits are arranged in their normal order as we read them, which means the MSB (most significant byte) comes first and the LSB (least significant byte) last.
But in Little Endian, the thing is totally reversed. And it must be remembered that all bits are byte wise reversed, which means they are reversed in groups of 8. That’s the rule for making segments of sizes 3 or 5 etc. If it’s a long or int, then a htons() will do the job.
Well, enough said, now let’s make our packet.
Get the remote host details in a sockaddr_in dest and call:
where payload is the size of the data after the TCP header. That’s it! We
are done.
To check whether the packets went out as you expected them to, use a sniffer like Ethereal and sniff them. Note: If you have any firewall running, then raw packets may be blocked.
VC++ can be used to compile this code. Simply create a project and put this file in it and click run. Notice the while loop. In a loop this will send too many raw TCP packets to the target system. Modify the values according to need.
A Tech Enthusiast, Blogger, Linux Fan and a Software Developer. Writes about Computer hardware, Linux and Open Source software and coding in Python, Php and Javascript. He can be reached at [email protected] .
8 thoughts on “ Raw socket programming on windows with winsock ”
And what about the fact that in the ip packet is initially field version, and only then the header size? In addition, the first two fields char structure, but they are in the specification should be 4 bits (two fields are equal to one char)? These must be packed in fragments through bitwise shift. On each line of 32 bits. This example is not workable.
Do you have an example of ICMpv6 packets sent via Winsock (other than ping)? Does Winsock raw sockets allow you to send ICMPv6 Destination Unreachable packet, for example?
good work,so clear
thank you
Very nice and informative, thanks.
amazing work and
and the pure beauty of coding socket in c
i’m your fan teacher
Sorry I should have read the whole thing before I commented. Disregard my stupid comment. This blog is excellent.
I don’t understand didn’t Microsoft limit raw sockets on Windows SP2?
Yes, the RAW socket is limited to the paket layer (OSI 3). Under this Header there is still the Ethernet Header (Link Layer, OSI 2) to determine the Destination hardware address (MAC) and senders MAC. There is also a field to determine the type of the first paket. In the example above the first paket is the the IP-Header. This are the first data the raw socket do provide.