wlsk888 2023-04-05 21:04 采纳率: 90.9%
浏览 12
已结题

C++dhcp数据包生成问题

我再学习dhcp数据包生成,可是下面代码,输出似乎并不是我期望的?谁能告诉我为什么?
它输出的是
不但在结尾“FF”后,多输出了好多00,而且0800后面和4500之间还有一些cc.

DHCP Release:
ffffffffffff1c1b0db38a250800cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc45000240000000008011284a0aa805bcffffffffcccccccccccccccccccccccccccccccccccccccccccccccccccccccc00440043022cb778cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc0101060012345678000000000aa805bc00000000000000000aa805011c1b0db38a250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063825363350107ff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

#define DHCP_SERVER_PORT 67
#define DHCP_CLIENT_PORT 68

// DHCP Message Types
#define DHCP_RELEASE    7
#define DHCP_DISCOVER   1

using namespace std;

#pragma pack(push,1)
typedef struct _ETHERNET_HEADER {
    unsigned char DestAddress[6];
    unsigned char SrcAddress[6];
    unsigned short Type;
} ETHERNET_HEADER;
#pragma pack(pop)

#pragma pack(push,1)
typedef struct _IPV4_HEADER {
    unsigned char VersionAndHeaderLength;
    unsigned char TypeOfService;
    unsigned short TotalLength;
    unsigned short Identification;
    unsigned short FlagsAndFragmentOffset;
    unsigned char TimeToLive;
    unsigned char Protocol;
    unsigned short HeaderChecksum;
    unsigned int SourceIpAddress;
    unsigned int DestinationIpAddress;
} IPV4_HEADER;
#pragma pack(pop)

#pragma pack(push,1)
typedef struct _UDP_HEADER {
    unsigned short SourcePort;
    unsigned short DestinationPort;
    unsigned short Length;
    unsigned short Checksum;
} UDP_HEADER;
#pragma pack(pop)

#pragma pack(push,1)
typedef struct _DHCP_MESSAGE {
    unsigned char OpCode;
    unsigned char HardwareType;
    unsigned char HardwareAddressLength;
    unsigned char Hops;
    unsigned int TransactionID;
    unsigned short SecondsElapsed;
    unsigned short Flags;
    unsigned int ClientIPAddress;
    unsigned int YourIPAddress;
    unsigned int ServerIPAddress;
    unsigned int GatewayIPAddress;
    unsigned char ClientHardwareAddress[16];
    unsigned char ServerName[64];
    unsigned char BootFileName[128];
    unsigned int MagicCookie;
    unsigned char Options[308]; // Maximum option size is 312 bytes (DHCPv4) or 576 bytes (DHCPv6)
} DHCP_MESSAGE;
#pragma pack(pop)

unsigned short ip_checksum(unsigned short* buffer, int size)
{
    unsigned long cksum = 0;

    while (size > 1)
    {
        cksum += *buffer++;
        size -= sizeof(unsigned short);
    }

    if (size)
    {
        cksum += *(unsigned char*)buffer;
    }

    cksum = (cksum >> 16) + (cksum & 0xFFFF);
    cksum += (cksum >> 16);

    return (unsigned short)(~cksum);
}

unsigned short udp_checksum(unsigned short* buffer, int size, unsigned int srcAddr, unsigned int destAddr)
{
    unsigned long cksum = 0;

    // Pseudo-Header
    cksum += (srcAddr >> 16) & 0xFFFF;
    cksum += srcAddr & 0xFFFF;
    cksum += (destAddr >> 16) & 0xFFFF;
    cksum += destAddr & 0xFFFF;
    cksum += htons(IPPROTO_UDP);
    cksum += htons(size);

    // UDP header
    while (size > 1)
    {
        cksum += *buffer++;
        size -= sizeof(unsigned short);
    }

    if (size)
    {
        cksum += *(unsigned char*)buffer;
    }

    cksum = (cksum >> 16) + (cksum & 0xFFFF);
    cksum += (cksum >> 16);

    return (unsigned short)(~cksum);
}

unsigned char* get_pack_data(string Myip, string MygatewayIP, string MymacAdd, string keyword)
{
    // Ethernet header
    ETHERNET_HEADER ethHdr = { 0 };
    memcpy(ethHdr.DestAddress, "\xFF\xFF\xFF\xFF\xFF\xFF", 6); // Broadcast address
    memcpy(ethHdr.SrcAddress, MymacAdd.c_str(), 6); // Your own MAC address
    ethHdr.Type = htons(0x0800); // IPv4

    // IP header
    IPV4_HEADER ipHdr = { 0 };
    ipHdr.VersionAndHeaderLength = 0x45;
    ipHdr.TypeOfService = 0;
    ipHdr.TotalLength = htons(sizeof(IPV4_HEADER) + sizeof(UDP_HEADER) + sizeof(DHCP_MESSAGE));
    ipHdr.Identification = 0;
    ipHdr.FlagsAndFragmentOffset = 0;
    ipHdr.TimeToLive = 128;
    ipHdr.Protocol = IPPROTO_UDP;
    ipHdr.SourceIpAddress = inet_addr(Myip.c_str()); // Your own IP address
    ipHdr.DestinationIpAddress = inet_addr("255.255.255.255"); // Broadcast address
    ipHdr.HeaderChecksum = ip_checksum((unsigned short*)&ipHdr, sizeof(IPV4_HEADER));

    // UDP header
    UDP_HEADER udpHdr = { 0 };
    udpHdr.SourcePort = htons(DHCP_CLIENT_PORT);
    udpHdr.DestinationPort = htons(DHCP_SERVER_PORT);
    udpHdr.Length = htons(sizeof(UDP_HEADER) + sizeof(DHCP_MESSAGE));
    udpHdr.Checksum = udp_checksum((unsigned short*)&udpHdr, sizeof(UDP_HEADER) + sizeof(DHCP_MESSAGE), ipHdr.SourceIpAddress, ipHdr.DestinationIpAddress);
    // DHCP message
    DHCP_MESSAGE dhcpMsg = { 0 };
    dhcpMsg.OpCode = 1; // BOOTP request
    dhcpMsg.HardwareType = 1; // Ethernet
    dhcpMsg.HardwareAddressLength = 6; // MAC address length
    dhcpMsg.TransactionID = htonl(0x12345678); // Unique transaction ID
    dhcpMsg.ClientIPAddress = inet_addr("0.0.0.0"); // 
    dhcpMsg.YourIPAddress = inet_addr("0.0.0.0");
    dhcpMsg.ServerIPAddress = inet_addr("0.0.0.0");
    dhcpMsg.GatewayIPAddress = inet_addr(MygatewayIP.c_str()); // Your gateway IP address
    memcpy(dhcpMsg.ClientHardwareAddress, MymacAdd.c_str(), 6); // Your own MAC address
    dhcpMsg.MagicCookie = htonl(0x63825363); // Magic cookie

    // DHCP options
    unsigned char* pOption = dhcpMsg.Options;
    *pOption++ = 53; // Option 53: DHCP Message Type
    *pOption++ = 1; // Length

    if (keyword == "Release") {
        *pOption++ = DHCP_RELEASE; // DHCP Release message
    }
    else {
        *pOption++ = DHCP_DISCOVER; // DHCP Discover message
    }

    *pOption++ = 255; // End of options marker

    // Output the DHCP packet as a hexadecimal string
    unsigned char* pPacket = (unsigned char*)ðHdr;
    int packetSize = sizeof(ETHERNET_HEADER) + sizeof(IPV4_HEADER) + sizeof(UDP_HEADER) + sizeof(DHCP_MESSAGE);

    unsigned char* data = new unsigned char[packetSize];
    memcpy(data, pPacket, packetSize);

    return data;
}

int main()
{
    string Myip = "10.168.5.188";
    string MygatewayIP = "10.168.5.1";
    string MymacAdd = "\x1C\x1B\x0D\xB3\x8A\x25";
    // Generate DHCP Release packet
    unsigned char* pPacket_release = get_pack_data(Myip, MygatewayIP, MymacAdd, "Release");

    // Output the DHCP Release packet as a hexadecimal string
    cout << "DHCP Release:" << endl;
    for (int i = 0; i < sizeof(ETHERNET_HEADER) + sizeof(IPV4_HEADER) + sizeof(UDP_HEADER) + sizeof(DHCP_MESSAGE); i++)
    {
        cout <<  setw(2) << setfill('0') << hex << (int)pPacket_release[i];
    }

    cout << endl;

    delete[] pPacket_release;

    // Generate DHCP Discover packet
    unsigned char* pPacket_discover = get_pack_data(Myip, MygatewayIP, MymacAdd, "Discover");

    // Output the DHCP Discover packet as a hexadecimal string
    cout << "Discover:" << endl;
    for (int i = 0; i < sizeof(ETHERNET_HEADER) + sizeof(IPV4_HEADER) + sizeof(UDP_HEADER) + sizeof(DHCP_MESSAGE); i++)
    {
        cout << setw(2) << setfill('0') << hex << (int)pPacket_discover[i];
    }

    cout << endl;

    delete[] pPacket_discover;

    return 0;
}


  • 写回答

2条回答 默认 最新

  • callinglove 2023-04-06 09:38
    关注

    问题就出在172-176行代码上,你数据拷贝出错了,依次拷贝这四个部分,没看懂你咋一次拷贝过去的

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 4月14日
  • 已采纳回答 4月6日
  • 创建了问题 4月5日

悬赏问题

  • ¥15 wpf中在模版中寻找元素
  • ¥15 MFC平台生成指定圆
  • ¥15 jmeter出现403
  • ¥500 求华为P30PRO手机硬盘数据恢复
  • ¥15 关于#vscode#的问题:ESP32开发板对接MQTT实现小灯泡的开关
  • ¥15 TMC2209串口模式下读取不到寄存器的值串口助手蓝色字体是发过去的消息,绿色字体是收到的消息,第二行发送读取寄存器的指令但是没有读取到寄存器的值串口助手如下图:接线如下图,如何解决?
  • ¥15 怎样删除 右键菜单里的 剪切(T)和复制(C)
  • ¥15 高通安卓11提取完整线刷包软件,或者优博讯dt50顺丰刷机包
  • ¥20 C,有个译码器,换了信道就跑不出原来数据
  • ¥15 MIMIC数据库安装问题