学习笔记之发送IP分组代码片段

学习笔记之发送IP分组代码片段


最近维护一个抓包程序,需要积累一些代码片段,先收藏。

#include "Winsock2.h"
#include "stdio.h"
#include "Ws2tcpip.h"
 
#pragma comment(lib,"ws2_32.lib")
 
typedef struct //定义IP报头
{ 
    unsigned short ip_verlen; //4位首部长度+4位版本号
    unsigned short ip_tos; //8位服务类型
    unsigned short ip_totallength;///16位总长度(字节)
    unsigned short ip_id; //16位标识
    unsigned short ip_offset; //3位标志位
    unsigned short ip_ttl; //8位生存时间 TTL
    unsigned short ip_protocol; //8位协议 (TCP, UDP 或其他)
    unsigned short ip_checksum; //16位IP首部校验和
    unsigned long ip_srcaddr; //32位源IP地址
    unsigned long ip_destaddr; //32位目的IP地址
}IP_HDR;
 
typedef struct  //定义UDP报头 
{ 
    unsigned short src_portno;//16位源端口 
    unsigned short dst_portno;//16位目的端口
    unsigned short udp_length;//16位长度
    unsigned short udp_checksum;//16位校验和
}UDP_HDR;
int main() 
{ 
    WSADATA wsd; 
    if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0) 
    { 
        printf("WSAStartup() failed: %d ", GetLastError());
        return -1; 
    } 
    SOCKET s = WSASocket(AF_INET, SOCK_RAW, IPPROTO_IP, NULL, 0,WSA_FLAG_OVERLAPPED); // Create a raw socket
    if (s == INVALID_SOCKET) 
    { 
        printf("WSASocket() failed: %d ", WSAGetLastError());
        return -1;
    } 
    DWORD bOpt = TRUE;
    int ret = setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char*) &bOpt, sizeof(bOpt)); // 使用IP_HDRINCL
    if (ret == SOCKET_ERROR) 
    { 
        printf("setsockopt(IP_HDRINCL) failed: %d ", WSAGetLastError());
        return -1; 
    } 
    const int BUFFER_SIZE = 80;
    char buffer[BUFFER_SIZE];
    const char *strMessage = "treat demo"; // Message to send 
    // Set IP header
   const u_short uToPort = 8000; 
    udpHdr.dst_portno = htons(uToPort); // 接收方端口 
    const u_short uFromPort = 1000; 
    udpHdr.src_portno = htons(uFromPort); // 发送伪造的端口 
    const unsigned short iUdpSize = sizeof(udpHdr) + strlen(strMessage); 
    udpHdr.udp_length = htons(iUdpSize); 
    udpHdr.udp_checksum = 0;
// 组建待发送的UDP报文 
    ZeroMemory(buffer, BUFFER_SIZE);
    char *ptr = buffer;
    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. 
    sockaddr_in remote;
    remote.sin_family = AF_INET; 
    remote.sin_port = htons(8000); 
    remote.sin_addr.s_addr = inet_addr("192.168.0.6"); 
    printf("TO %s:%d ", target_ip_address, uToPort); 
    ret = sendto(s, buffer, iTotalSize, 0, (SOCKADDR*) &remote, sizeof(remote)); // 发送伪造的报文 
    if (ret == SOCKET_ERROR)
    {
        printf("sendto() failed: %d ", WSAGetLastError());
    } 
    else
        printf("sent %d bytes ", ret); 
    closesocket(s); 
    WSACleanup();
    return 1; 
}

你可能感兴趣的:(技术收藏)