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

📄 rawudp.cpp

📁 这个是网络编程
💻 CPP
📖 第 1 页 / 共 3 页
字号:
                  plushdrs,        // IPv6 length field includes encapsulated headers
                  numpackets=0,    // number of fragments
                  originalpayload;

    originalpayload = payloadlen;
    do
    {
        // Compute the size of this fragment
        lastfragment = 0;
        fragment = 0;
        if ((payloadlen > gMtuSize) && (numpackets == 0))
        {
            // Data needs to be fragmented, this is the first packet
            hdrlen  = sizeof(IPV6_HDR) + sizeof(UDP_HDR) + sizeof(IPV6_FRAGMENT_HDR);
            datalen = gMtuSize - hdrlen;
            plushdrs = sizeof(UDP_HDR) + sizeof(IPV6_FRAGMENT_HDR);
            fragment = 1;

            printf("Require fragmentation: FIRST packet\n");
        }
        else if ((payloadlen > gMtuSize) && (numpackets > 0))
        {
            // Data needs to be fragmented, this is packet number > 0
            hdrlen = sizeof(IPV6_HDR) + sizeof(IPV6_FRAGMENT_HDR);
            datalen = gMtuSize - hdrlen;
            fragment = 1;
            plushdrs = sizeof(IPV6_FRAGMENT_HDR);

            printf("Require fragmentation: packet number > 0\n");
        }
        else if (numpackets == 0)
        {
            // Data doesn't need to be fragmented
            hdrlen = sizeof(IPV6_HDR) + sizeof(UDP_HDR);
            datalen = payloadlen;
            fragment = 0;
            plushdrs = sizeof(UDP_HDR);

            printf("No fragmentation required\n");
        }
        else
        {
            // This is the last fragment
            hdrlen = sizeof(IPV6_HDR) + sizeof(IPV6_FRAGMENT_HDR);
            datalen = payloadlen;
            fragment = 1;
            plushdrs = sizeof(IPV6_FRAGMENT_HDR);
            lastfragment = 1;

            printf("Require fragmentation: Last packet\n");
        }

        // Build packet
 
        // Allocate buffer for this fragment
        Packets[numpackets].buf = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, hdrlen + datalen);
        if (Packets[numpackets].buf == NULL)
        {
            fprintf(stderr, "PacketizeV6: HeapAlloc failed: %d\n", GetLastError());
            ExitProcess(-1);
        }
        Packets[numpackets].len = hdrlen + datalen;

        // Initialize the V6 header, if we have to fragment the next header field of
        //    the v6 header is that of the fragmentation header. Also the payload
        //    length includes the headers (UDP + fragmentation) and the payload itself.
        iphdrlen = InitIpv6Header(
                Packets[numpackets].buf, 
                src->ai_addr, 
                dest->ai_addr, 
                DEFAULT_TTL, 
                (fragment ? FRAGMENT_HEADER_PROTOCOL : gProtocol),
                datalen + plushdrs
                );

        // Build the fragmentation header if necessary
        if (fragment)
        {
            iphdrlen += InitIpv6FragmentHeader(
                   &Packets[numpackets].buf[iphdrlen],
                    offset,         // offset from start of packet
                    gProtocol,
                    fragid,
                    lastfragment
                    );
        }

        // The first fragment includes the UDP header, subsequent fragments don't
        if (numpackets == 0)
        {
            udphdrlen = InitUdpHeader(
                   &Packets[numpackets].buf[iphdrlen], 
                    src->ai_addr, 
                    dest->ai_addr, 
                    originalpayload //payloadlen
                    );

            // Compute the checksum
            ComputeUdpPseudoHeaderChecksumV6(
                    Packets[numpackets].buf, 
                    (UDP_HDR *)&Packets[numpackets].buf[iphdrlen], 
                    payload, 
                    payloadlen);
        }
        else
        {
            udphdrlen = 0;
        }

        // Copy the payload into this fragment
        memcpy(&Packets[numpackets].buf[iphdrlen + udphdrlen], &payload[offset], datalen);

        // Adjust our counters
        payloadlen = payloadlen - datalen;
        offset += datalen;
        numpackets++;

    } while (payloadlen > 0);

    fragid++;

    // Mark the next WSABUF entry with NULL and zero to indicate end of fragments
    Packets[numpackets].buf = NULL;
    Packets[numpackets].len = 0;

    return Packets;
}

// 
// Function: main
//
// Description:
//    First, parse command line arguments and load Winsock. Then 
//    create the raw socket and then 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 _cdecl main(int argc, char **argv)
{
    WSADATA            wsd;
    SOCKET             s;
    DWORD              bytes;
    WSABUF            *wbuf=NULL;
    struct addrinfo   *ressrc=NULL,
                      *resdest=NULL,
                      *resbind=NULL;
    int                packets,
                       rc,
                       i, j;

    // Parse command line arguments and print them out
    ValidateArgs(argc, argv);

    srand(GetTickCount());

    if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
    {
        printf("WSAStartup() failed: %d\n", GetLastError());
        return -1;
    }

    // Convert the source and destination addresses/ports
    ressrc = ResolveAddress(gSrcAddress, gSrcPort, gAddressFamily, gSocketType, gProtocol);
    if (ressrc == NULL)
    {
        fprintf(stderr, "Unable to resolve address '%s' and port '%s'\n", 
                gSrcAddress, gSrcPort);
        return -1;
    }

    if (bSender)
    {
        resdest = ResolveAddress(gDestAddress, gDestPort, ressrc->ai_family, ressrc->ai_socktype, ressrc->ai_protocol);
        if (resdest == NULL)
        {
            fprintf(stderr, "Unable to resolve address '%s' and port '%s'\n", 
                    gDestAddress, gDestPort);
            return -1;
        }
    }

    //  Creating a raw socket

    //  BUG - For IPv6 if we create the raw socket with IPPROTO_UDP then the Ipv6
    //  stack will thow away our IPv6 and UDP headers and put "valid" ones in their
    //  place. As a workaround, create the socket with a protocol value of an 
    //  unhandled protocol. Of course the IPv6 header should still indicate that 
    //  the encapsulated protocol is UDP.
  
    if (bSender)
        s = socket(ressrc->ai_family, SOCK_RAW, ((ressrc->ai_family == AF_INET6) ? 3 : ressrc->ai_protocol));
    else if (!bSender && bReadRaw)
        s = socket(ressrc->ai_family, SOCK_RAW, ressrc->ai_protocol);
    else
        s = socket(ressrc->ai_family, SOCK_DGRAM, ressrc->ai_protocol);
    if (s == INVALID_SOCKET)
    {
        fprintf(stderr, "socket failed: %d\n", WSAGetLastError());
        return -1;
    }

    if (bSender)
    {
        char   *payload=NULL;
        int     optlevel,
                option,
                optval;

        payload = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, gSendSize);
        if (payload == NULL)
        {
            fprintf(stderr, "HeapAlloc failed: %d\n", GetLastError());
            return -1;
        }
        memfill(payload, gSendSize, gMessage, strlen(gMessage));

        // Enable the IP header include option 
        optval = 1;
        if (ressrc->ai_family == AF_INET)
        {
            optlevel = IPPROTO_IP;
            option   = IP_HDRINCL;
        }
        else if (ressrc->ai_family == AF_INET6)
        {
            optlevel = IPPROTO_IPV6;
            option   = IPV6_HDRINCL;
        }
        rc = setsockopt(s, optlevel, option, (char *)&optval, sizeof(optval));
        if (rc == SOCKET_ERROR)
        {
            fprintf(stderr, "setsockopt: IP_HDRINCL failed: %d\n", WSAGetLastError());
            return -1;
        }

        // Packetize and/or perform necessary fragmentation on data
        if (ressrc->ai_family == AF_INET)
        {
            wbuf = PacketizeIpv4(
                ressrc,
                resdest,
                payload,
                gSendSize
                );
        }
        else if (ressrc->ai_family == AF_INET6)
        {
            wbuf = PacketizeIpv6(
                ressrc,
                resdest,
                payload,
                gSendSize
                );
        }
        // Count how many packets there are
        i=0;
        packets=0;
        while (wbuf[i].buf)
        {
            printf("packet %d buf 0x%p len %d\n",
                    i, wbuf[i].buf, wbuf[i].len);
            packets++;
            i++;
        }

        // 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 dest in remote
        // will be ignored.
        for(i=0; i < (int)gSendCount ;i++)
        {
            for(j=0; j < packets ;j++)
            {
                rc = sendto(
                        s,
                        wbuf[j].buf,
                        wbuf[j].len,
                        0,
                        resdest->ai_addr,
                        resdest->ai_addrlen
                        );
                bytes = rc;
                if (rc == SOCKET_ERROR)
                {
                    printf("sendto() failed: %d\n", WSAGetLastError());
                    break;
                }
                else
                {
                    printf("sent %d bytes\n", bytes);
                }
            }
        }

        // Free the packet buffers
        for(i=0; i < packets ;i++)
        {
            HeapFree(GetProcessHeap(), 0, wbuf[i].buf);
        }
    }
    else
    {
        SOCKADDR_STORAGE    safrom;
        char                buf[MAX_PACKET];
        int                 fromlen;

        rc = bind(
                s, 
                ressrc->ai_addr,
                ressrc->ai_addrlen
                );
        if (rc == SOCKET_ERROR)
        {
            fprintf(stderr, "bind failed: %d\n", WSAGetLastError());
            return -1;
        }

        printf("binding to: ");
        PrintAddress(ressrc->ai_addr, ressrc->ai_addrlen);
        printf("\n");

        while (1)
        {
            fromlen = sizeof(safrom);
            rc = recvfrom(
                    s, 
                    buf, 
                    MAX_PACKET, 
                    0, 
                    (SOCKADDR *)&safrom, 
                   &fromlen
                   );
            if (rc == SOCKET_ERROR)
            {
                fprintf(stderr, "recvfrom failed: %d\n", WSAGetLastError());
                break;
            }
            printf("Read %d bytes from ", rc);
            PrintAddress((SOCKADDR *)&safrom, fromlen);
            printf("\n");
        }
    }

    closesocket(s) ;
    WSACleanup() ;

    return 0;
}

⌨️ 快捷键说明

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