⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rawudp.cpp

📁 这个是网络编程
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    // Account for the size of the UDP header
    if (offset != 0)
        offset += sizeof(UDP_HDR);

    frag->ipv6_frag_nexthdr = (unsigned char)nextproto;
    frag->ipv6_frag_offset  = htons( (unsigned short)(((offset/8) << 3) | lastfragment));
    frag->ipv6_frag_id      = htonl(id);

    return sizeof(IPV6_FRAGMENT_HDR);
}

// 
// Function: InitUdpHeader
//
// Description:
//    Setup the UDP header which is fairly simple. Grab the ports and
//    stick in the total payload length.
//
int InitUdpHeader(
    char *buf, 
    SOCKADDR *src,
    SOCKADDR *dest, 
    int       payloadlen
    )
{
    UDP_HDR *udphdr=NULL;

    udphdr = (UDP_HDR *)buf;

    // Port numbers are already in network byte order
    if (src->sa_family == AF_INET)
    {
        udphdr->src_portno = ((SOCKADDR_IN *)src)->sin_port;
        udphdr->dst_portno = ((SOCKADDR_IN *)dest)->sin_port;
    }
    else if (src->sa_family == AF_INET6)
    {
        udphdr->src_portno = ((SOCKADDR_IN6 *)src)->sin6_port;
        udphdr->dst_portno = ((SOCKADDR_IN6 *)dest)->sin6_port;
    }
    udphdr->udp_length = htons(sizeof(UDP_HDR) + payloadlen);

    return sizeof(UDP_HDR);
}

//
// Function: ComputeUdpPseudoHeaderChecksumV4
//
// Description:
//    Compute the UDP pseudo header checksum. The UDP checksum is based
//    on the following fields:
//       o source IP address
//       o destination IP address
//       o 8-bit zero field
//       o 8-bit protocol field
//       o 16-bit UDP length
//       o 16-bit source port
//       o 16-bit destination port
//       o 16-bit UDP packet length
//       o 16-bit UDP checksum (zero)
//       o UDP payload (padded to the next 16-bit boundary)
//    This routine copies these fields to a temporary buffer and computes
//    the checksum from that.
//
void ComputeUdpPseudoHeaderChecksumV4(
    void    *iphdr,
    UDP_HDR *udphdr,
    char    *payload,
    int      payloadlen
    )
{
    IPV4_HDR     *v4hdr=NULL;
    unsigned long zero=0;
    char          buf[MAX_PACKET],
                 *ptr=NULL;
    int           chksumlen=0,
                  i;
    
    ptr = buf;

    v4hdr = (IPV4_HDR *)iphdr;

    // Include the source and destination IP addresses
    memcpy(ptr, &v4hdr->ip_srcaddr,  sizeof(v4hdr->ip_srcaddr));  
    ptr += sizeof(v4hdr->ip_srcaddr);
    chksumlen += sizeof(v4hdr->ip_srcaddr);

    memcpy(ptr, &v4hdr->ip_destaddr, sizeof(v4hdr->ip_destaddr)); 
    ptr += sizeof(v4hdr->ip_destaddr);
    chksumlen += sizeof(v4hdr->ip_destaddr);
    
    // Include the 8 bit zero field
    memcpy(ptr, &zero, 1);
    ptr++;
    chksumlen += 1;

    // Protocol
    memcpy(ptr, &v4hdr->ip_protocol, sizeof(v4hdr->ip_protocol)); 
    ptr += sizeof(v4hdr->ip_protocol);
    chksumlen += sizeof(v4hdr->ip_protocol);

    // UDP length
    memcpy(ptr, &udphdr->udp_length, sizeof(udphdr->udp_length)); 
    ptr += sizeof(udphdr->udp_length);
    chksumlen += sizeof(udphdr->udp_length);
    
    // UDP source port
    memcpy(ptr, &udphdr->src_portno, sizeof(udphdr->src_portno)); 
    ptr += sizeof(udphdr->src_portno);
    chksumlen += sizeof(udphdr->src_portno);

    // UDP destination port
    memcpy(ptr, &udphdr->dst_portno, sizeof(udphdr->dst_portno)); 
    ptr += sizeof(udphdr->dst_portno);
    chksumlen += sizeof(udphdr->dst_portno);

    // UDP length again
    memcpy(ptr, &udphdr->udp_length, sizeof(udphdr->udp_length)); 
    ptr += sizeof(udphdr->udp_length);
    chksumlen += sizeof(udphdr->udp_length);
   
    // 16-bit UDP checksum, zero 
    memcpy(ptr, &zero, sizeof(unsigned short));
    ptr += sizeof(unsigned short);
    chksumlen += sizeof(unsigned short);

    // payload
    memcpy(ptr, payload, payloadlen);
    ptr += payloadlen;
    chksumlen += payloadlen;

    // pad to next 16-bit boundary
    for(i=0 ; i < payloadlen%2 ; i++, ptr++)
    {
        printf("pad one byte\n");
        *ptr = 0;
        ptr++;
        chksumlen++;
    }

    // Compute the checksum and put it in the UDP header
    udphdr->udp_checksum = checksum((USHORT *)buf, chksumlen);

    return;
}

void ComputeUdpPseudoHeaderChecksumV6(
    void    *iphdr,
    UDP_HDR *udphdr,
    char    *payload,
    int      payloadlen
    )
{
    IPV6_HDR     *v6hdr=NULL;
    unsigned long length=0;
    char          buf[MAX_PACKET],
                  proto,
                 *ptr=NULL;
    int           chksumlen=0,
                  i;
    
    ptr = buf;

    v6hdr = (IPV6_HDR *)iphdr;

    memcpy(ptr, &v6hdr->ipv6_srcaddr,  sizeof(v6hdr->ipv6_srcaddr));  
    ptr += sizeof(v6hdr->ipv6_srcaddr);
    chksumlen += sizeof(v6hdr->ipv6_srcaddr);

    memcpy(ptr, &v6hdr->ipv6_destaddr,  sizeof(v6hdr->ipv6_destaddr));  
    ptr += sizeof(v6hdr->ipv6_destaddr);
    chksumlen += sizeof(v6hdr->ipv6_destaddr);

    printf("payload length = %d\n", payloadlen);
    length = htonl(payloadlen + sizeof(UDP_HDR));

    memcpy(ptr, &length, sizeof(length));
    ptr += sizeof(length);
    chksumlen += sizeof(length);

    memset(ptr, 0, 3);
    ptr += 3;
    chksumlen +=3;

    proto = IPPROTO_UDP;

    memcpy(ptr, &proto, sizeof(proto));
    ptr += sizeof(proto);
    chksumlen += sizeof(proto);
   
    // UDP source port
    memcpy(ptr, &udphdr->src_portno, sizeof(udphdr->src_portno)); 
    ptr += sizeof(udphdr->src_portno);
    chksumlen += sizeof(udphdr->src_portno);

    // UDP destination port
    memcpy(ptr, &udphdr->dst_portno, sizeof(udphdr->dst_portno)); 
    ptr += sizeof(udphdr->dst_portno);
    chksumlen += sizeof(udphdr->dst_portno);

    // UDP length again
    memcpy(ptr, &udphdr->udp_length, sizeof(udphdr->udp_length)); 
    ptr += sizeof(udphdr->udp_length);
    chksumlen += sizeof(udphdr->udp_length);
   
    // 16-bit UDP checksum, zero 
    memset(ptr, 0, sizeof(unsigned short));
    ptr += sizeof(unsigned short);
    chksumlen += sizeof(unsigned short);

    // payload
    memcpy(ptr, payload, payloadlen);
    ptr += payloadlen;
    chksumlen += payloadlen;

    // pad to next 16-bit boundary
    for(i=0 ; i < payloadlen%2 ; i++, ptr++)
    {
        printf("pad one byte\n");
        *ptr = 0;
        ptr++;
        chksumlen++;
    }

    // Compute the checksum and put it in the UDP header
    udphdr->udp_checksum = checksum((USHORT *)buf, chksumlen);

    return;
}


//
// Function: memfill
//
// Description:
//    Fills a block of memory with a given string pattern.
//
void memfill(
    char *dest,
    int   destlen,
    char *data,
    int   datalen
    )
{
    char *ptr=NULL;
    int   copylen;

    ptr = dest;
    while (destlen > 0)
    {
        copylen = ((destlen > datalen) ? datalen : destlen);
        memcpy(ptr, data, copylen);

        destlen -= copylen;
        ptr += copylen;
    }
    return;
}

//
// Function: PacketizeIpv4
//
// Description:
//    This routine takes the data buffer and packetizes it for IPv4.
//    Since the IPv4 stack takes care of fragmentation for us, this
//    routine simply initializes the IPv4 and UDP headers. The data
//    is returned in an array of WSABUF structures.
//
WSABUF *PacketizeIpv4(
    struct addrinfo *src,
    struct addrinfo *dest,
    char *payload, 
    int payloadlen
    )
{
    static WSABUF Packets[MAX_PACKET_FRAGMENTS];
    int           iphdrlen,
                  udphdrlen;

    // Allocate memory for the packet
    Packets[0].buf = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IPV4_HDR) + sizeof(UDP_HDR) + payloadlen);
    if (Packets[0].buf == NULL)
    {
        fprintf(stderr, "PacetizeV4: HeapAlloc failed: %d\n", GetLastError());
        ExitProcess(-1);
    }
    Packets[0].len = sizeof(IPV4_HDR) + sizeof(UDP_HDR) + payloadlen;

    // Initialize the v4 header
    iphdrlen = InitIpv4Header(
            Packets[0].buf, 
            src->ai_addr, 
            dest->ai_addr, 
            DEFAULT_TTL, 
            gProtocol, 
            payloadlen
            );
 
    // Initialize the UDP header
    udphdrlen = InitUdpHeader(
           &Packets[0].buf[iphdrlen], 
            src->ai_addr, 
            dest->ai_addr, 
            payloadlen
            );

    // Compute the UDP checksum
    ComputeUdpPseudoHeaderChecksumV4(
            Packets[0].buf, 
            (UDP_HDR *)&Packets[0].buf[iphdrlen], 
            payload, 
            payloadlen
            );

    // Copy the payload to the end of the header
    memcpy(&Packets[0].buf[iphdrlen + udphdrlen], payload, payloadlen);

    // Zero out the next WSABUF structure which indicates the end of
    //    the packets -- caller must free the buffers
    Packets[1].buf = NULL;
    Packets[1].len = 0;

    return Packets;
}

//
// Function: PacketizeIpv6
//
// Description:
//    This routine fragments data payload with the appropriate IPv6
//    headers. The individual fragments are returned via an array of
//    WSABUF structures. Each structure is a separate fragment of the
//    whole message. The end of the fragments is indicated by a WSABUF
//    entry with a NULL buffer pointer.
//
WSABUF *PacketizeIpv6(
    struct addrinfo *src,
    struct addrinfo *dest,
    char *payload, 
    int payloadlen
    )
{
    static WSABUF Packets[MAX_PACKET_FRAGMENTS];
    static ULONG  fragid=1;
    int           offset=0,        // offset into payload 
                  datalen,         // length of the payload
                  hdrlen,          // length of the header(s)
                  fragment,        // is this a fragment?
                  lastfragment,    // is this the last fragment?
                  iphdrlen,        // length of ip header 
                  udphdrlen,       // length of the udp header

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -