iphdrinc.c

// 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 send
char           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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于计算机专业的学生而言,参加各类比赛能够带来多方面的益处,具体包括但不限于以下几点: 技能提升: 参与比赛促使学生深入学习和掌握计算机领域的专业知识与技能,如编程语言、算法设计、软件工程、网络安全等。 比赛通常涉及实际问题的解决,有助于将理论知识应用于实践中,增强问题解决能力。 实践经验: 大多数比赛都要求参赛者设计并实现解决方案,这提供了宝贵的动手操作机会,有助于积累项目经验。 实践经验对于计算机专业的学生尤为重要,因为雇主往往更青睐有实际项目背景的候选人。 团队合作: 许多比赛鼓励团队协作,这有助于培养学生的团队精神、沟通技巧和领导能力。 团队合作还能促进学生之间的知识共享和思维碰撞,有助于形成更全面的解决方案。 职业发展: 获奖经历可以显著增强简历的吸引力,为求职或继续深造提供有力支持。 某些比赛可能直接与企业合作,提供实习、工作机会或奖学金,为学生的职业生涯打开更多门路。 网络拓展: 比赛是结识同行业人才的好机会,可以帮助学生建立行业联系,这对于未来的职业发展非常重要。 奖金与荣誉: 许多比赛提供奖金或奖品,这不仅能给予学生经济上的奖励,还能增强其成就感和自信心。 荣誉证书或奖状可以证明学生的成就,对个人品牌建设有积极作用。 创新与研究: 参加比赛可以激发学生的创新思维,推动科研项目的开展,有时甚至能促成学术论文的发表。 个人成长: 在准备和参加比赛的过程中,学生将面临压力与挑战,这有助于培养良好的心理素质和抗压能力。 自我挑战和克服困难的经历对个人成长有着深远的影响。 综上所述,参加计算机领域的比赛对于学生来说是一个全面发展的平台,不仅可以提升专业技能,还能增强团队协作、沟通、解决问题的能力,并为未来的职业生涯奠定坚实的基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值