[Winpcap-users] Winpcap and Sockets

Ian Basham ianb at proconex.com
Wed Mar 21 14:28:07 GMT 2007


Here are 2 programs that demonstrate a problem I am having.

In a nutshell, normally the program on Machine B can be run over and 
over without any problems.  However, if the program on Machine A calls 
pcap_open and pcap_close, then the program on Machine B can never 
re-establish the socket, because the program on Machine A fails on the 
call to bind.


On Machine A, run this program.



#include "pcap.h"
#include <winsock2.h>

/*************************************************************

    Name:      hst3002

    Desc:      This routine shutdowns and closes the socket.

    Returns:   nothing


**************************************************************/

void hst3002 ( SOCKET Socket ) {

    int status;

    status = shutdown (Socket, 2);
    if (status == SOCKET_ERROR)    printf("shutdown failed\n");

    status = closesocket (Socket);   
    if (status == SOCKET_ERROR) printf("closesocket failed\n");

    status = WSACleanup();
    if (status == SOCKET_ERROR) printf("WSACleanup failed\n");

}

/*************************************************************

    Name:      hst3001

    Desc:      This routine:
                   creates a socket
                   sets up a socket name / address
                   associates the address with the socket

    Returns:   0 if successful.
               1 if fails

**************************************************************/

SOCKET hst3001 (unsigned short port) {

    WSADATA     Data;
    SOCKADDR_IN SockAddr;
    SOCKET      Socket;
    SOCKADDR_IN hostSockAddr;
    SOCKET      hostSocket;
    int addrLen = sizeof (SOCKADDR_IN);

    int status;

    /* start Windows Socket dll */
    status= WSAStartup (MAKEWORD(1,1), &Data);
    if (status != 0) {
        return (SOCKET_ERROR);
    }

    /* zero the socket address */
    memset (&SockAddr, 0, sizeof (SockAddr));

    /* set the socket name */
    SockAddr.sin_port = htons(port);
    SockAddr.sin_family = AF_INET;
    SockAddr.sin_addr.s_addr = htonl(INADDR_ANY);

    /* create the socket */
    Socket = socket(AF_INET, SOCK_STREAM, 0);
    if (Socket == INVALID_SOCKET) {
        printf("socket failed\n");
        status = WSACleanup();
        return (SOCKET_ERROR);
    }

    /* associate the socket with the address */
    status = bind(Socket, (LPSOCKADDR) &SockAddr, sizeof(SockAddr));
    if (status == SOCKET_ERROR) {
        printf("bind failed\n");
        return (SOCKET_ERROR);
    }

    /* allow the socket to take a connection */
    status = listen (Socket, 1);
    if (status == SOCKET_ERROR) {
        printf("listen failed\n");
        return (SOCKET_ERROR);
    }


    /* accept a connectio request */
    hostSocket= accept(Socket, (LPSOCKADDR) &hostSockAddr, &addrLen);
    if (hostSocket == INVALID_SOCKET) {
        return (SOCKET_ERROR);
    }

    return (hostSocket);

}


void main(void)
{

    int     ei_mlen;                 /* message length (input)       */
    int     numsnt;
    unsigned short port = 44965;

    unsigned char ei_imsg[200];

    char errbuf[PCAP_ERRBUF_SIZE];

    // you will need to put your own source here
    char *src = "\\Device\\NPF_{1A61C83D-0286-4DFF-BEC5-BFC85EBBC765}";

    SOCKET      hostSocket;

    pcap_t *hnd_pcap = NULL;


  
// if these next 2 lines are commented out,
// program works as expected
    hnd_pcap = pcap_open_live(src, 1514, 0, 10, errbuf);
    pcap_close(hnd_pcap);



    hostSocket = hst3001 (port);

    while (1) {

        ei_mlen = recv (hostSocket, ei_imsg, 200, 0);
        if ((ei_mlen == 0) || (ei_mlen == SOCKET_ERROR)) {
            hst3002 ( hostSocket );
            hostSocket = hst3001 (port);
        }

                Sleep(100);

        // just echoing message back
        numsnt= send(hostSocket, ei_imsg, ei_mlen, 0);
        if (numsnt != ei_mlen) {
            hst3002 ( hostSocket );
            hostSocket = hst3001 ( port );
        }
    }
}


On Machine B, run this program.

#include <stdio.h>
#include <windows.h>
#include <winsock.h>

#define MAXBUFLEN 2048

void main(void)
{
    unsigned short port = 44965;
    unsigned long qtr;
    int lenrcv;
    int status;

    unsigned char tbuffer [MAXBUFLEN];

    struct hostent *serverHostent;
   
    SOCKADDR_IN destSockAddr;
   
    SOCKET destSocket;
   
    WSADATA Data;

    status = WSAStartup (MAKEWORD(1, 1), &Data);
    if (status != 0)    printf("WSAStartup unsuccessful\n");


        // you will have to put the name of your host here
    serverHostent = gethostbyname ("LCNSIM");
    if  (serverHostent == 0) printf("error in finding host\n");

    memcpy(&destSockAddr.sin_addr, serverHostent->h_addr, 
serverHostent->h_length);
    destSockAddr.sin_port = htons(port);
    destSockAddr.sin_family = AF_INET;

    destSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (destSocket == INVALID_SOCKET) {
        printf("socket unsuccessful\n");
        status = WSACleanup();
        if (status == SOCKET_ERROR) printf("WSACleanup unsuccessful\n");
    }

    status = connect (destSocket, (LPSOCKADDR) &destSockAddr, 
sizeof(destSockAddr));

    if (status == SOCKET_ERROR) {
        printf ("connect failed\n");

        status = closesocket(destSocket);
        if (status == SOCKET_ERROR) printf("closesocket failed\n");

        status = WSACleanup();
        if (status == SOCKET_ERROR) printf("WSACleanup failed\n");

    }

    Sleep(1000);

    ioctlsocket (destSocket, FIONREAD, &qtr);

    if (qtr > 0) {
        lenrcv = recv (destSocket, tbuffer, MAXBUFLEN, 0);
    }


        // normally all the messages would go here, but not needed for 
this demo
    Sleep(5000);


    status = closesocket(destSocket);
    if (status == SOCKET_ERROR) printf("closesocket failed\n");

    status = WSACleanup();
    if (status == SOCKET_ERROR) printf("WSACleanup failed\n");
       
       
}



More information about the Winpcap-users mailing list