[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