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

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 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥170 如图所示配置eNSP
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改
  • ¥20 wireshark抓不到vlan
  • ¥20 关于#stm32#的问题:需要指导自动酸碱滴定仪的原理图程序代码及仿真
  • ¥20 设计一款异域新娘的视频相亲软件需要哪些技术支持
  • ¥15 stata安慰剂检验作图但是真实值不出现在图上
  • ¥15 c程序不知道为什么得不到结果