iphdrinc.c

来源:互联网 发布:电视直播软件 珠海台 编辑:程序博客网 时间:2024/06/14 18:29
// Module Name: iphdrinc.c//#pragma pack(1)

#define WIN32_LEAN_AND_MEAN

#include <winsock2.h>#include <ws2tcpip.h>

#include <stdio.h>#include <stdlib.h>

#define MAX_MESSAGE        4068#define MAX_PACKET         4096//// Set up some default values//#define DEFAULT_PORT       5150#define DEFAULT_IP         "10.0.0.1"#define DEFAULT_COUNT      5#define DEFAULT_MESSAGE    "This is a test"

//// Define the IP header. Make the version and length fields one// character since we can't declare two 4-bit fields without// the compiler aligning them on at least a 1-byte boundary.//typedef struct ip_hdr{   unsigned char  ip_verlen;        // IP version & length   unsigned char  ip_tos;           // IP type of service   unsigned short ip_totallength;   // Total length   unsigned short ip_id;            // Unique identifier   unsigned short ip_offset;        // Fragment offset field   unsigned char  ip_ttl;           // Time to live   unsigned char  ip_protocol;      // Protocol(TCP, UDP, etc.)   unsigned short ip_checksum;      // IP checksum   unsigned int   ip_srcaddr;       // Source address   unsigned int   ip_destaddr;      // Destination address} IP_HDR, *PIP_HDR, FAR* LPIP_HDR;//// Define the UDP header//typedef struct udp_hdr{   unsigned short src_portno;       // Source port number   unsigned short dst_portno;       // Destination port number   unsigned short udp_length;       // UDP packet length   unsigned short udp_checksum;     // UDP checksum (optional)} UDP_HDR, *PUDP_HDR;

//// Global variables//unsigned long  dwToIP,               // IP to send to              dwFromIP;             // IP to send from (spoof)unsigned short iToPort,              // Port to send to              iFromPort;            // Port to send from (spoof)DWORD          dwCount;              // Number of times to sendchar           strMessage[MAX_MESSAGE]; // Message to send

//// Description://    Print usage information and exit//void usage(char *progname){   printf("usage: %s [-fp:int] [-fi:str] [-tp:int] [-ti:str]/       [-n:int] [-m:str]/n", progname);   printf("       -fp:int   From (sender) port number/n");   printf("       -fi:IP    From (sender) IP address/n");   printf("       -fp:int   To (recipient) port number/n");   printf("       -fi:IP    To (recipient) IP address/n");   printf("       -n:int    Number of times to read message/n");   printf("       -m:str    Size of buffer to read/n/n");   ExitProcess(1);}//// Function: ValidateArgs//// Description://    Parse the command line arguments, and set some global flags to//    indicate the actions to perform//void ValidateArgs(int argc, char **argv){   int                i;

   iToPort = DEFAULT_PORT;   iFromPort = DEFAULT_PORT;   dwToIP = inet_addr(DEFAULT_IP);   dwFromIP = inet_addr(DEFAULT_IP);   dwCount = DEFAULT_COUNT;   strcpy(strMessage, DEFAULT_MESSAGE);

   for(i = 1; i < argc; i++)   {       if ((argv[i][0] == '-') || (argv[i][0] == '/'))       {           switch (tolower(argv[i][1]))           {               case 'f':        // From address                   switch (tolower(argv[i][2]))                   {                       case 'p':                           if (strlen(argv[i]) > 4)                               iFromPort = atoi(&argv[i][4]);                           break;                       case 'i':                           if (strlen(argv[i]) > 4)                               dwFromIP = inet_addr(&argv[i][4]);                           break;                       default:                           usage(argv[0]);                           break;                   }                   break;               case 't':        // To address                   switch (tolower(argv[i][2]))                   {                       case 'p':                           if (strlen(argv[i]) > 4)                               iToPort = atoi(&argv[i][4]);                           break;                       case 'i':                           if (strlen(argv[i]) > 4)                               dwToIP = inet_addr(&argv[i][4]);                           break;                       default:                           usage(argv[0]);                           break;                   }                   break;               case 'n':        // Number of times to send message                   if (strlen(argv[i]) > 3)                       dwCount = atol(&argv[i][3]);                   break;               case 'm':                   if (strlen(argv[i]) > 3)                       strcpy(strMessage, &argv[i][3]);                   break;               default:                   usage(argv[0]);                   break;           }       }   }   return;}

//// Function: checksum//// Description://    This function calculates the 16-bit one's complement sum//    for the supplied buffer//USHORT checksum(USHORT *buffer, int size){   unsigned long cksum=0;

   while (size > 1)   {       cksum += *buffer++;       size  -= sizeof(USHORT);   }   if (size)   {       cksum += *(UCHAR*)buffer;   }   cksum = (cksum >> 16) + (cksum & 0xffff);   cksum += (cksum >>16);

   return (USHORT)(~cksum);}

//// Function: main//// Description://    First parse command line arguments and load Winsock. Then//    create the raw socket and set the IP_HDRINCL option.//    Following this, assemble the IP and UDP packet headers by//    assigning the correct values and calculating the checksums.//    Then fill in the data and send to its destination.//int main(int argc, char **argv){   WSADATA            wsd;   SOCKET             s;   BOOL               bOpt;   struct sockaddr_in remote;       // IP addressing structures   IP_HDR             ipHdr;   UDP_HDR            udpHdr;   int                ret;   DWORD              i;   unsigned short     iTotalSize,   // Lots of sizes needed to fill                      iUdpSize,     // the various headers with                      iUdpChecksumSize,                      iIPVersion,                      iIPSize,                      cksum = 0;   char               buf[MAX_PACKET],                     *ptr = NULL;   IN_ADDR            addr;

   // Parse command line arguments, and print them out   //   ValidateArgs(argc, argv);   addr.S_un.S_addr = dwFromIP;   printf("From IP: <%s>/n     Port: %d/n", inet_ntoa(addr),       iFromPort);   addr.S_un.S_addr = dwToIP;   printf("To   IP: <%s>/n     Port: %d/n", inet_ntoa(addr),       iToPort);   printf("Message: [%s]/n", strMessage);   printf("Count:   %d/n", dwCount);

   if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)   {       printf("WSAStartup() failed: %d/n", GetLastError());       return -1;   }   //  Creating a raw socket   //   s = WSASocket(AF_INET, SOCK_RAW, IPPROTO_UDP, NULL, 0,0);   if (s == INVALID_SOCKET)   {       printf("WSASocket() failed: %d/n", WSAGetLastError());       return -1;   }

   // Enable the IP header include option   //   bOpt = TRUE;   ret = setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *)&bOpt,      sizeof(bOpt));   if (ret == SOCKET_ERROR)   {       printf("setsockopt(IP_HDRINCL) failed: %d/n", WSAGetLastError());       return -1;   }   // Initalize the IP header   //   iTotalSize = sizeof(ipHdr) + sizeof(udpHdr) + strlen(strMessage);

   iIPVersion = 4;   iIPSize = sizeof(ipHdr) / sizeof(unsigned long);   //   // IP version goes in the high-order 4 bits of ip_verlen. The   // IP header length (in 32-bit words) goes in the lower 4 bits.   //   ipHdr.ip_verlen = (iIPVersion << 4) | iIPSize;   ipHdr.ip_tos = 0;                         // IP type of service   ipHdr.ip_totallength = htons(iTotalSize); // Total packet len   ipHdr.ip_id = 0;                 // Unique identifier: set to 0   ipHdr.ip_offset = 0;             // Fragment offset field   ipHdr.ip_ttl = 128;              // Time to live   ipHdr.ip_protocol = 0x11;        // Protocol(UDP)   ipHdr.ip_checksum = 0 ;          // IP checksum   ipHdr.ip_srcaddr = dwFromIP;     // Source address   ipHdr.ip_destaddr = dwToIP;      // Destination address   //   // Initalize the UDP header   //   iUdpSize = sizeof(udpHdr) + strlen(strMessage);

   udpHdr.src_portno = htons(iFromPort) ;   udpHdr.dst_portno = htons(iToPort) ;   udpHdr.udp_length = htons(iUdpSize) ;   udpHdr.udp_checksum = 0 ;   //   // Build the UDP pseudo-header for calculating the UDP checksum.   // The pseudo-header consists of the 32-bit source IP address,   // the 32-bit destination IP address, a zero byte, the 8-bit   // IP protocol field, the 16-bit UDP length, and the UDP   // header itself along with its data (padded with a 0 if   // the data is odd length).   //   iUdpChecksumSize = 0;   ptr = buf;   ZeroMemory(buf, MAX_PACKET);

   memcpy(ptr, &ipHdr.ip_srcaddr,  sizeof(ipHdr.ip_srcaddr));   ptr += sizeof(ipHdr.ip_srcaddr);   iUdpChecksumSize += sizeof(ipHdr.ip_srcaddr);

   memcpy(ptr, &ipHdr.ip_destaddr, sizeof(ipHdr.ip_destaddr));   ptr += sizeof(ipHdr.ip_destaddr);   iUdpChecksumSize += sizeof(ipHdr.ip_destaddr);

   ptr++;   iUdpChecksumSize += 1;

   memcpy(ptr, &ipHdr.ip_protocol, sizeof(ipHdr.ip_protocol));   ptr += sizeof(ipHdr.ip_protocol);   iUdpChecksumSize += sizeof(ipHdr.ip_protocol);

   memcpy(ptr, &udpHdr.udp_length, sizeof(udpHdr.udp_length));   ptr += sizeof(udpHdr.udp_length);   iUdpChecksumSize += sizeof(udpHdr.udp_length);

   memcpy(ptr, &udpHdr, sizeof(udpHdr));   ptr += sizeof(udpHdr);   iUdpChecksumSize += sizeof(udpHdr);

   for(i = 0; i < strlen(strMessage); i++, ptr++)       *ptr = strMessage[i];   iUdpChecksumSize += strlen(strMessage);

   cksum = checksum((USHORT *)buf, iUdpChecksumSize);   udpHdr.udp_checksum = cksum;   //   // Now assemble the IP and UDP headers along with the data   // so we can send it   //   ZeroMemory(buf, MAX_PACKET);   ptr = buf;

   memcpy(ptr, &ipHdr, sizeof(ipHdr));   ptr += sizeof(ipHdr);   memcpy(ptr, &udpHdr, sizeof(udpHdr)); ptr += sizeof(udpHdr);   memcpy(ptr, strMessage, strlen(strMessage));

   // Apparently, this SOCKADDR_IN structure makes no difference.   // Whatever we put as the destination IP addr in the IP header   // is what goes. Specifying a different destination in remote   // will be ignored.   //   remote.sin_family = AF_INET;   remote.sin_port = htons(iToPort);   remote.sin_addr.s_addr = dwToIP;

   for(i = 0; i < dwCount; i++)   {       ret = sendto(s, buf, iTotalSize, 0, (SOCKADDR *)&remote,           sizeof(remote));       if (ret == SOCKET_ERROR)       {           printf("sendto() failed: %d/n", WSAGetLastError());           break;       }       else           printf("sent %d bytes/n", ret);   }   closesocket(s) ;   WSACleanup() ;

   return 0;}