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

📄 rcvall.cpp

📁 < WINDOWS网络编程>>英文版,一本详细讲解WINDOWS平台下网络编程的国外经典书籍,适合英文水平高的牛人
💻 CPP
字号:
//
// Module:
//    rcvall.cpp
//
// Abstract:
//    This sample shows how to use the ioctls SIO_RCVALL,
//    SIO_RCVALL_MCAST, and SIO_RCVALL_IGMPMCAST. This sample
//    captures all packets of the given type and also is able
//    to set filters on source and destination IP addresses
//    and ports. This sample is Windows 2000 and later.
//
// Usage:
//    rcvall.exe [-t ip|igmp|multicast] -i int -sa IP -sp port
//               -da IP -dp port
//           -t string           Filter traffic type
//                 ip            Capture all IP packets
//                 igmp          Capture all IGMP packets only
//                 multicast     Capture all multicast IP packets
//           -i int              Capture on this interface
//                                This is a zero based index of the 
//                                local interfaces
//           -sa IP              Filter on source address
//           -sp Port            Filter on source port
//           -da IP              Filter on dest address
//           -dp Port            Filter on dest port
//
// Build:
//    cl rcvall.cpp parser.cpp ws2_32.lib
//
// Author:
//    Anthony Jones
//

#include "parser.h"

#include <mstcpip.h>
#include <ws2tcpip.h>

#include <stdio.h>
#include <stdlib.h>

DWORD  dwIoControlCode=SIO_RCVALL,
       dwProtocol=IPPROTO_IP,
       dwInterface=0;

//
// Filters (Globals)
//
unsigned int   uiSourceAddr=0,
               uiDestAddr=0;
unsigned short usSourcePort = 0,
               usDestPort = 0;
BOOL           bFilter=FALSE;

void PrintInterfaceList();
int  GetInterface(SOCKET s, SOCKADDR_IN *ifx, int num);

//
// Function: usage
// 
// Description:
//    Prints usage information.
//
void usage(char *progname)
{
    printf("usage: %s -t traffic-type [interface-num]\n\n", progname);
    printf("       -t string           Filter traffic type\n");
    printf("             Available traffic types:\n");
    printf("               ip          Capture all IP packets\n");
    printf("               igmp        Capture all IGMP packets only\n");
    printf("               multicast   Capture all multicast IP packets\n");
    printf("       -i int              Capture on this interface\n");
    printf("             Available interfaces:\n");
    PrintInterfaceList();
    printf("       -sa IP              Filter on source address\n");
    printf("       -sp Port            Filter on source port\n");
    printf("       -da IP              Filter on dest address\n");
    printf("       -dp Port            Filter on dest port\n");

    WSACleanup();
    ExitProcess(-1);
}

//
// Function: ValidateArgs
// 
// Description:
//    This function parses the command line arguments and
//    sets global variables to indicate how the app should act.
//
void ValidateArgs(int argc, char **argv)
{
    int   i;
    char *ptr;

    for(i=1; i < argc ;i++)
    {
        if (strlen(argv[i]) < 2)
            continue;
        if ((argv[i][0] == '-') || (argv[i][0] == '/'))
        {
            switch (tolower(argv[i][1]))
            {
                case 't':        // traffic type
                    if (i+1 >= argc)
                        usage(argv[0]);
                    ptr = &argv[i][3];
                    while (*ptr)
                        *ptr++ = (char) tolower(*ptr);

                    if (!strcmp(argv[i+1], "ip"))
                    {
                        printf("Setting SIO_RCVALL and IPPROTO_IP\n");
                        dwIoControlCode = SIO_RCVALL;
                        dwProtocol = IPPROTO_IP;
                    }
                    else if (!strcmp(argv[i+1], "igmp"))
                    {
                        printf("Setting SIO_RCVALL_IGMPMCAST and IPPROTO_IGMP\n");
                        dwIoControlCode = SIO_RCVALL_IGMPMCAST;
                        dwProtocol = IPPROTO_IGMP;
                    }
                    else if (!strcmp(argv[i+1], "multicast"))
                    {
                        printf("Setting SIO_RCVALL_MCAST and IPPROTO_UDP\n");
                        dwIoControlCode = SIO_RCVALL_MCAST;
                        dwProtocol = IPPROTO_UDP;
                    }
                    else
                        usage(argv[0]);
                    i++;
                    break;
                case 'i':        // interface number
                    if (i+1 >= argc)
                        usage(argv[0]);
                    dwInterface = atoi(argv[++i]);
                    break;
                case 's':        // Filter on source ip or port
                    if (i+1 >= argc)
                        usage(argv[0]);
                    if (tolower(argv[i][2]) == 'a')
                        uiSourceAddr = ntohl(inet_addr(argv[++i]));
                    else if (tolower(argv[i][2]) == 'p')
                        usSourcePort = (unsigned short)atoi(argv[++i]);
                    else
                        usage(argv[0]);
                    bFilter = TRUE;
                    break;
                case 'd':        // Filter on dest ip or port
                    if (i+1 >= argc)
                        usage(argv[0]);
                    if (tolower(argv[i][2]) == 'a')
                        uiDestAddr = ntohl(inet_addr(argv[++i]));
                    else if (tolower(argv[i][2]) == 'p')
                        usDestPort = (unsigned short)atoi(argv[++i]);
                    else
                        usage(argv[0]);
                    bFilter = TRUE;
                    break;
                default:
                    usage(argv[0]);
            }
        }
    }
    return;
}

//
// Function: PrintInterfaceList
//
// Description:
//    This function prints all local IP interfaces.
//
void PrintInterfaceList()
{
    SOCKET_ADDRESS_LIST *slist=NULL;
    SOCKET               s;
    char                 buf[2048];
    DWORD                dwBytesRet;
    int                  ret,
                         i;

    s = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
    if (s == SOCKET_ERROR)
    {
        printf("socket() failed: %d\n", WSAGetLastError());
        return;
    }
    ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buf, 2048,
                &dwBytesRet, NULL, NULL);
    if (ret == SOCKET_ERROR)
    {
        printf("WSAIoctl(SIO_ADDRESS_LIST_QUERY) failed: %d\n",
            WSAGetLastError());
        return;
    }
    slist = (SOCKET_ADDRESS_LIST *)buf;
    for(i=0; i < slist->iAddressCount ;i++)
    {
        printf("               %-2d ........ [%s]\n", i, 
            inet_ntoa(((SOCKADDR_IN *)slist->Address[i].lpSockaddr)->sin_addr));
    }
    closesocket(s);
    return;
}

//
// Function: GetInterface
//
// Description:
//    This function retrieves a zero based index and returns
//    the IP interface corresponding to that.
//
int GetInterface(SOCKET s, SOCKADDR_IN *ifx, int num)
{
    SOCKET_ADDRESS_LIST *slist=NULL;
    char                 buf[2048];
    DWORD                dwBytesRet;
    int                  ret;

    ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buf, 2048,
                &dwBytesRet, NULL, NULL);
    if (ret == SOCKET_ERROR)
    {
        printf("WSAIoctl(SIO_ADDRESS_LIST_QUERY) failed: %d\n",
            WSAGetLastError());
        return -1;
    }
    slist = (SOCKET_ADDRESS_LIST *)buf;

    if (num >= slist->iAddressCount)
        return -1;

    ifx->sin_addr.s_addr = ((SOCKADDR_IN *)slist->Address[num].lpSockaddr)->sin_addr.s_addr;

    return 0;
}

//
// Function: main
//
// Description:
//    This function loads Winsock, parses the command line, and
//    begins receiving packets. Once a packet is received they
//    are decoded. Because we are receiving IP datagrams, the
//    receive call will return whole datagrams.
//
int _cdecl main(int argc, char **argv)
{
    SOCKET        s;
    WSADATA       wsd;
    SOCKADDR_IN   if0;
    int           ret,
                  count;
    unsigned int  optval;
    DWORD         dwBytesRet,
                  dwFlags,
                  nproc;
    char          rcvbuf[MAX_IP_SIZE];
    WSABUF        wbuf;

    // Load Winsock
    //
    if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
    {
        printf("WSAStartup() failed: %d\n", GetLastError());
        return -1;
    }
    // Parse the command line
    //
    ValidateArgs(argc, argv);
    if (bFilter)
    {
        printf("Source Port: %d\n", usSourcePort);
        printf("Dest   Port: %d\n", usDestPort);
    }
    // Create a raw socket for receiving IP datagrams
    //
    s = WSASocket(AF_INET, SOCK_RAW, dwProtocol, NULL, 0, WSA_FLAG_OVERLAPPED);
    if (s == INVALID_SOCKET)
    {
        printf("WSASocket() failed: %d\n", WSAGetLastError());
        return -1;
    }
    // Get an interface to read IP packets on
    //
    if (GetInterface(s, &if0, dwInterface) != 0)
    {
        printf("Unable to obtain an interface\n");
        return -1;
    }
    printf("Binding to IF: %s\n", inet_ntoa(if0.sin_addr));
    //
    // This socket MUST be bound before calling the ioctl
    //
    if0.sin_family = AF_INET;
    if0.sin_port = htons(0);

    if (bind(s, (SOCKADDR *)&if0, sizeof(if0)) == SOCKET_ERROR)
    {
        printf("bind() failed: %d\n", WSAGetLastError());
        return -1;
    }
    //
    // Set the SIO_RCVALLxxx ioctl
    //
    optval = 1;
    if (WSAIoctl(s, dwIoControlCode, &optval, sizeof(optval),
            NULL, 0, &dwBytesRet, NULL, NULL) == SOCKET_ERROR)
    {
        printf("WSAIotcl(%d) failed; %d\n", dwIoControlCode,
            WSAGetLastError());
        return -1;
    }
    // Start receiving IP datagrams until interrupted
    // 
    count = 0;
    while (1)
    {
        wbuf.len = MAX_IP_SIZE;
        wbuf.buf = rcvbuf;
        dwFlags  = 0;

        ret = WSARecv(s, &wbuf, 1, &dwBytesRet, &dwFlags, NULL, NULL);
        if (ret == SOCKET_ERROR)
        {
            printf("WSARecv() failed: %d\n", WSAGetLastError());
            return -1;
        }
        // Decode the IP header
        //
        if (!(nproc = DecodeIPHeader(&wbuf, uiSourceAddr, usSourcePort,
                uiDestAddr, usDestPort)))
        {
            printf("Error decoding IP header!\n");
            break;
        }
    }
    // Cleanup
    //
    closesocket(s);
    WSACleanup();
    return 0;
}

⌨️ 快捷键说明

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