Cygwin에서 WinPcap으로 간단한 IP dump utility.
build machine에서 WinPcap이 설치되어 잇어야하고,
WpdPack_4_1_1/WpdPack/Examples-pcap 의 include, lib가 설치되어 잇어야함.

1. Makefile

# Makefile for cygwin gcc
# Nate Lawson <nate@rootlabs.com>

OUTNAME=ipd

CC=gcc

PCAP_PATH = ../lib

CFLAGS = -g -Wall -O -mno-cygwin -I../include
#CFLAGS = -g -Wall -I../include

OBJS = \
wp_util.o \
ipd_main.o

LIBS = -L ${PCAP_PATH} -lwpcap

all: ${OBJS}
 ${CC} ${CFLAGS} -o ${OUTNAME}.exe ${OBJS} ${LIBS}

clean:
 rm -f ${OBJS} ${OUTNAME}.exe

.c.o:
 ${CC} ${CFLAGS} -c -o $*.o $<

2. wp_util

2.1 wp_util.h

/*-----------------------------------------------------------------------------
 wp_util.h
 General definition
 version  : 1.0
 Programed by : jakeoh
 Date  : 18Dec09-18Dec09
 Compiler :
 Description :
 18Dec09 jakeoh utility functions for WinPcap
-----------------------------------------------------------------------------*/

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

#ifndef WIN32
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#else
#include <winsock.h>
#endif

/*-----------------------------------------------------------------------------
        Predefine
-----------------------------------------------------------------------------*/
#define ROK 1
#define RFAIL -1

/*-----------------------------------------------------------------------------
        function prototypes
-----------------------------------------------------------------------------*/
extern int fnGetDeviceAll (void);

extern int fnDevMon (int nNo);
extern void fnPacket_Handler (u_char *pParam, const struct pcap_pkthdr *pstHeader, const u_char *pPkt_data);

extern pcap_t *fnOpenDevice (int nNo);
extern int fnCloseDevice (pcap_t *pHandle);
extern int     fnReadPacket (pcap_t *pHandle);

/*----------------------------------------------------------------------------
 End of wp_util.h
-----------------------------------------------------------------------------*/

2.2 wp_util.c

/*-----------------------------------------------------------------------------
 wp_util.c
 Utility functions for WinPcap
 18Dec09-18Dec09
 18Dec09 jakeoh from ~/WpdPack_4_1_1/WpdPack/Examples-pcap/basic_dump.c
 21Dec09 jakeoh fnGetDeviceAll (), fnDevMon (), fnPacket_Handler ()
 22Dec09 jakeoh fnOpenDevice (), fnCloseDevice (), fnMon ()
-----------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------
 Include files
-----------------------------------------------------------------------------*/
#include "wp_util.h"

/*-----------------------------------------------------------------------------
 Defines
-----------------------------------------------------------------------------*/

/*-----------------------------------------------------------------------------
 fnInet_ntop ()
 Date : 22Dec09-22Dec09
 Input :
 Output :
 Description
 22Dec09 jakeoh from inet_ntop ()
-----------------------------------------------------------------------------*/
const char *fnInet_ntop
(
 int family,
 const void *addrptr,
 char *strptr,
 size_t len
)
{
 const u_char *p = (const u_char *) addrptr;

 if (family == AF_INET)
 {
//  char temp[INET_ADDRSTRLEN];
  char temp[15+1];

  snprintf (temp, sizeof (temp), "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
  if (strlen (temp) >= len)
  {
//   errno = ENOSPC;
   return (NULL);
  }
  strcpy (strptr, temp);
  return (strptr);
 }
// errno = EAFNOSUPPORT;
 return (NULL);
} /* end of fnInet_ntop () */

/* From tcptraceroute, convert a numeric IP address to a string */
#define IPTOSBUFFERS    12

#if 0
/*-----------------------------------------------------------------------------
 iptos ()
 Date : 21Dec09-21Dec09
 Input :
 Output :
 Description
 21Dec09 jakeoh IP address to string
-----------------------------------------------------------------------------*/
char *iptos
(
 u_long in
)
{
 static char output[IPTOSBUFFERS][3*4+3+1];
 static short which;
 u_char *p;

 p = (u_char *) &in;
 which = (which + 1 == IPTOSBUFFERS ? 0 : which + 1);
 _snprintf_s (output[which], sizeof(output[which]), sizeof(output[which]),"%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
 return output[which];
}

/*-----------------------------------------------------------------------------
 ip6tos ()
 Date : 21Dec09-21Dec09
 Input :
 Output :
 Description
 21Dec09 jakeoh IPv6 to string
-----------------------------------------------------------------------------*/
char* ip6tos
(
 struct sockaddr *sockaddr,
 char *address,
 int addrlen
)
{
 socklen_t sockaddrlen;

#ifdef WIN32
 sockaddrlen = sizeof (struct sockaddr_in6);
#else
 sockaddrlen = sizeof (struct sockaddr_storage);
#endif


 if (getnameinfo (sockaddr,
  sockaddrlen,
  address,
  addrlen,
  NULL,
  0,
  NI_NUMERICHOST) != 0) address = NULL;

 return address;
}
#endif

/*-----------------------------------------------------------------------------
 fnDebugDump ()
 Programed by : jakeoh
 Date  : 07Jul05-07Jul05
 Input  : hex dump utility function
 Output  : success = ROK
    error = RFAIL
 Description :
 02Jul05 jakeoh draft
-----------------------------------------------------------------------------*/
void fnDebugDump
(
 unsigned char* pData,
 int dwLen
)
{
 int     nCnt0, nIndex;
 char szHex[4];
 char szBuff[81];

 memset (szBuff, 0x00, sizeof (szBuff));
 nIndex = 0;
 printf ("Len [%d]\n", dwLen);
 for (nCnt0=0; nCnt0 < dwLen; nCnt0++)
 {
  memset (szHex, 0x00, sizeof (szHex));
  sprintf (szHex, "%02x ", pData[nCnt0]);
  strcat (szBuff, szHex);
  nIndex++;
  if (nIndex%16 == 0)
  {
   printf ("%s\n", szBuff);
   memset (szBuff, 0x00, sizeof (szBuff));
  }
 }
 if (strlen (szBuff) > 0)
 {
  printf ("%s\n", szBuff);
 }
} /* end of fnDebugDump () */

/*-----------------------------------------------------------------------------
 fnIfPrint ()
 Date : 21Dec09-21Dec09
 Input : pcap_if_t
 Output : Information in pcap_if_t
 Description
 21Dec09 jakeoh Print out to interface info from pcap_if_t
-----------------------------------------------------------------------------*/
void fnIfPrint
(
 pcap_if_t *pIf
)
{
 char szTmp[128];
 pcap_addr_t *pAddr;

 /* Name */
 if (pIf->name)
  printf ("\tNAME           [%s]\n", pIf->name);

 /* Description */
 if (pIf->description)
  printf ("\tDESCRIPTION    [%s]\n", pIf->description);

 /* Loopback Address */
 printf ("\tLOOPBACK FLAG  [%s]\n", (pIf->flags & PCAP_IF_LOOPBACK)?"YES":"NO");

 /* IP address */
 for (pAddr=pIf->addresses; pAddr ; pAddr=pAddr->next)
 {
//  printf ("\tADDRESS FAMILY [%d]\n", pAddr->addr->sa_family);
  switch (pAddr->addr->sa_family)
  {
   case AF_INET:
    printf ("\tAddress Family [AF_INET]\n");
#if 1
    if (pAddr->addr)
     printf ("\tADDRESS        [%s]\n", fnInet_ntop (AF_INET, &((struct sockaddr_in *)pAddr->addr)->sin_addr, szTmp, sizeof (szTmp)));
    if (pAddr->netmask)
     printf ("\tNETMASK        [%s]\n", fnInet_ntop (AF_INET, &((struct sockaddr_in *)pAddr->netmask)->sin_addr, szTmp, sizeof (szTmp)));
    if (pAddr->broadaddr)
     printf ("\tBROADCAST      [%s]\n", fnInet_ntop (AF_INET, &((struct sockaddr_in *)pAddr->broadaddr)->sin_addr, szTmp, sizeof (szTmp)));
    if (pAddr->dstaddr)
     printf ("\tDEST ADDRESS   [%s]\n", fnInet_ntop (AF_INET, &((struct sockaddr_in *)pAddr->dstaddr)->sin_addr, szTmp, sizeof (szTmp)));
#else
    if (pAddr->addr)
     printf ("\tADDRESS        [%s]\n", inet_ntop (AF_INET, &((struct sockaddr_in *)pAddr->addr)->sin_addr, szTmp, sizeof (szTmp)));
    if (pAddr->netmask)
     printf ("\tNETMASK        [%s]\n", inet_ntop (AF_INET, &((struct sockaddr_in *)pAddr->netmask)->sin_addr, szTmp, sizeof (szTmp)));
    if (pAddr->broadaddr)
     printf ("\tBROADCAST      [%s]\n", inet_ntop (AF_INET, &((struct sockaddr_in *)pAddr->broadaddr)->sin_addr, szTmp, sizeof (szTmp)));
    if (pAddr->dstaddr)
     printf ("\tDEST ADDRESS   [%s]\n", inet_ntop (AF_INET, &((struct sockaddr_in *)pAddr->dstaddr)->sin_addr, szTmp, sizeof (szTmp)));
#endif
    break;
#if 0
   case AF_INET6:
    char szIPv6[128];

    printf ("\tAddress Family [AF_INET6]\n");
    if (pAddr->addr)
     printf ("\tADDRESS        [%s]\n", ip6tos (pAddr->addr, szIPv6, sizeof (szIPv6)));
    break;
#endif
   default:
    printf ("\tAddress Family [Unknwon]\n");
    break;
  }
 }
 printf ("\n");

} /* end of fnIfPrint */

/*-----------------------------------------------------------------------------
 fnGetDeviceAll ()
 Date : 18Dec09-18Dec09
 Input : void
 Output : Number of Device
 Description
 18Dec09 jakeoh Get all device and print out
-----------------------------------------------------------------------------*/
int fnGetDeviceAll
(
 void
)
{
 int nCnt=0;
 pcap_if_t *pAlldevs;
 pcap_if_t *pIft;
 char szErrBuf[PCAP_ERRBUF_SIZE];

 /* Retrieve the device list */
#if 1
 if (pcap_findalldevs (&pAlldevs, szErrBuf) == -1)
 {
  printf ("[%s] pcap_findalldevs () FAILED [%s]\n", __func__, szErrBuf);
  return RFAIL;
 }
#else
 if (pcap_findalldevs_ex ("rpcap://", NULL, &pAlldevs, szErrBuf) == -1)
 {
  printf ("[%s] pcap_findalldevs () FAILED [%s]\n", __func__, szErrBuf);
  return RFAIL;
 }
#endif
 else
  printf ("[%s] Device List [0x%08lx]\n", __func__, (unsigned long) pAlldevs);

 /* List out */
 for (pIft=pAlldevs; pIft; pIft=pIft->next)
 {
  printf ("\t[%d]\n", nCnt);
  fnIfPrint (pIft);
  nCnt++;
 }

 /* Free the device list */
 pcap_freealldevs (pAlldevs);

 printf ("[%s] Interface found [%d]\n", __func__, nCnt);

 return nCnt;
} /* end of fnGetDeviceAll () */

/*-----------------------------------------------------------------------------
 fnDevMon ()
 Date : 21Dec09-21Dec09
 Input : Device No
 Output : ROK, RFAIL
 Description
 21Dec09 jakeoh Open Device and Start monitoring
-----------------------------------------------------------------------------*/
int fnDevMon
(
 int nNo
)
{
 int nCnt;
 pcap_t *pHandle;
 pcap_if_t *pAlldevs;
 pcap_if_t *pIft;
 char szErrBuf[PCAP_ERRBUF_SIZE];

 pHandle = NULL;

 printf ("[%s] Device No [%d]\n", __func__, nNo);

 /* Get Device info */
 if (pcap_findalldevs (&pAlldevs, szErrBuf) == -1)
 {
  printf ("[%s] pcap_findalldevs () FAILED [%s]\n", __func__, szErrBuf);
  return RFAIL;
 }

 /* Jump to the selected device */
 for (pIft=pAlldevs, nCnt=0; nCnt < nNo; pIft=pIft->next, nCnt++);

 /* Open the device */
 if ((pHandle = pcap_open_live (pIft->name, // name of the device
  65536,  // portion of the packet to capture.
    // 65536 grants that the whole packet will be captured on all the MACs.
  1,  // promiscuous mode (nonzero means promiscuous)
  1000,  // read timeout
  szErrBuf // error buffer
  )) == NULL)
 {
  printf ("[%s] Unable to open the adapter. %s is not supported by WinPcap\n", __func__, pIft->name);
  printf ("[%s] ERR : %s\n", __func__, szErrBuf);

  /* Free the device list */
  pcap_freealldevs (pAlldevs);
  return RFAIL;
 }

 /* At this point, we don't need any more the device list. Free it */
 pcap_freealldevs (pAlldevs);

 printf ("[%s] Listening on %s...\n", __func__, pIft->description);

 /* start the capture */
 pcap_loop (pHandle, 0, fnPacket_Handler, NULL);

 /* Close */
 pcap_close (pHandle);

 return ROK;
} /* end of fnDevMon () */

/*-----------------------------------------------------------------------------
 fnPacket_Handler ()
 Date : 21Dec09-21Dec09
 Input :
 Output :
 Description
 21Dec09 jakeoh Callback function invoked by libpcap for every incoming packet
-----------------------------------------------------------------------------*/
void fnPacket_Handler
(
 u_char *pParam,
 const struct pcap_pkthdr *pstHeader,
 const u_char *pPkt_data
)
{
 struct tm *ltime;
 char timestr[16];
 time_t local_tv_sec;

 /*
  * unused parameters
  */
 (VOID)(pParam);
 (VOID)(pPkt_data);

 /* convert the timestamp to readable format */
 local_tv_sec = pstHeader->ts.tv_sec;
 ltime = localtime (&local_tv_sec);
 strftime (timestr, sizeof timestr, "%H:%M:%S", ltime);
 
 printf ("-> [%s,%.6d] [len:%d] [caplen:%d]\n", timestr, pstHeader->ts.tv_usec, pstHeader->len, pstHeader->caplen);
 fnDebugDump ((char *) pPkt_data, pstHeader->len);

} /* end of fnPacket_Handler () */

/*-----------------------------------------------------------------------------
 fnOpenDevice ()
 Date : 21Dec09-21Dec09
 Input : Device No
 Output : pcat_t *
 Description
 21Dec09 jakeoh Open selected device
-----------------------------------------------------------------------------*/
pcap_t *fnOpenDevice
(
 int nNo
)
{
 int nCnt;
 pcap_t *pHandle;
 pcap_if_t *pAlldevs;
 pcap_if_t *pIft;
 char szErrBuf[PCAP_ERRBUF_SIZE];

 pHandle = NULL;

 printf ("[%s] Device No [%d]\n", __func__, nNo);

 /* Get Device info */
 if (pcap_findalldevs (&pAlldevs, szErrBuf) == -1)
 {
  printf ("[%s] pcap_findalldevs () FAILED [%s]\n", __func__, szErrBuf);
  return pHandle;
 }

 /* Jump to the selected device */
 for (pIft=pAlldevs, nCnt=0; nCnt < nNo; pIft=pIft->next, nCnt++);

 /* Open the device */
 if ((pHandle = pcap_open_live (pIft->name, // name of the device
  65536,  // portion of the packet to capture.
    // 65536 grants that the whole packet will be captured on all the MACs.
  1,  // promiscuous mode (nonzero means promiscuous)
  1000,  // read timeout
  szErrBuf // error buffer
  )) == NULL)
 {
  printf ("[%s] Unable to open the adapter. %s is not supported by WinPcap\n", __func__, pIft->name);
  printf ("[%s] ERR : %s\n", __func__, szErrBuf);

  /* Free the device list */
  pcap_freealldevs (pAlldevs);
  return pHandle;
 }

 /* At this point, we don't need any more the device list. Free it */
 pcap_freealldevs (pAlldevs);

 return pHandle;
} /* end of fnOpenDevice () */


/*-----------------------------------------------------------------------------
 fnCloseDevice ()
 Date : 21Dec09-21Dec09
 Input : pcat_t*
 Output : ROK, RFAIL
 Description
 21Dec09 jakeoh Close selected device
-----------------------------------------------------------------------------*/
int fnCloseDevice
(
 pcap_t *pHandle
)
{
 pcap_close (pHandle);
 return ROK;
} /* end of fnCloseDevice () */

/*-----------------------------------------------------------------------------
 fnReadPacket ()
 Date : 22Dec09-22Dec09
 Input : pcap_t *
 Output : return code
 Description
 22Dec09 jakeoh Read packet from selected handle
-----------------------------------------------------------------------------*/
int fnReadPacket
(
 pcap_t *pHandle
)
{
 int nRet;
 char timestr[16];
 time_t local_tv_sec;
 struct tm *ltime;

 const u_char *pPkt_data;
 struct pcap_pkthdr *pstHeader;

 nRet = pcap_next_ex (pHandle, &pstHeader, &pPkt_data);
 if (nRet == 0) /* timeout elapsed */
  return 0;
 if (nRet < 0) /* error */
 {
  printf ("[%s] ERROR [%s]\n", __func__, pcap_geterr (pHandle));
  return nRet;
 }

 /* convert the timestamp to readable format */
 local_tv_sec = pstHeader->ts.tv_sec;
 ltime = localtime (&local_tv_sec);
 strftime (timestr, sizeof timestr, "%H:%M:%S", ltime);
 
 printf ("-> [%s,%.6d] [len:%d] [caplen:%d]\n", timestr, pstHeader->ts.tv_usec, pstHeader->len, pstHeader->caplen);
 fnDebugDump ((char *) pPkt_data, pstHeader->len);

 return nRet;
} /* end of fnReadPacket () */

/*-----------------------------------------------------------------------------
 End of wp_util.c
-----------------------------------------------------------------------------*/

3. ipd

3.1 gen.h

/*-----------------------------------------------------------------------------
 gen.h
 General definition
 version  : 1.0
 Programed by : jakeoh
 Date  : 18Dec09-18Dec09
 Compiler :
 Description :
 18Dec09 jakeoh Initial
-----------------------------------------------------------------------------*/

/*-----------------------------------------------------------------------------
        Predefine
-----------------------------------------------------------------------------*/
#define BUFSIZE256 256+1

/*-----------------------------------------------------------------------------
        function prototypes
-----------------------------------------------------------------------------*/

/*-----------------------------------------------------------------------------
 End of gen.h
-----------------------------------------------------------------------------*/


3.2 ipd_main.c

/*-----------------------------------------------------------------------------
 ipd_main.c
 IP Dump utility using winpcap library
 18Dec09-18Dec09
 18Dec09 jakeoh from ~/WpdPack_4_1_1/WpdPack/Examples-pcap/basic_dump.c
-----------------------------------------------------------------------------*/

/*-----------------------------------------------------------------------------
 Include files
-----------------------------------------------------------------------------*/
#include "gen.h"
#include "wp_util.h"

/*-----------------------------------------------------------------------------
 Defines
-----------------------------------------------------------------------------*/
int errno; /* global error number */

char gszAppName[30]; /* Application name */

/*-----------------------------------------------------------------------------
 main ()
 Date : 18Dec09-18Dec09
 Input :
 Output :
 Description
 18Dec09 jakeoh View device list, select device, monitoring device
-----------------------------------------------------------------------------*/
int main
(
 int argc, /* argument count */
 char **argv /* argument values */
)
{
 int nRet, nCnt;
 int nDev;
#if 0
 char szCmd[BUFSIZE256];
 char szTmp[BUFSIZE256], szBaseKey[BUFSIZE256];
 char *pEnd;
 int nShmKey;
 char *pShm;
#endif

 /* argument check */

 /* set App name */
 strcpy (gszAppName, argv[0]);

#if 0
 gnLogLevel = LOG_LVL_FULL;
 nRet = fnInitLogFiles ();
 if (nRet != RETOK)
 {
  printf ("[%s] ***ERROR*** Log init failed \n", __func__);
  exit (0);
 }

 logPrint2 (LDEBUG, gnLogLevel, gnTrcLogId, FL, "[%s] -------------------------------------\n", __func__);
 logPrint2 (LDEBUG, gnLogLevel, gnTrcLogId, FL, "[%s]  STARTUP [%s]\n", __func__, gszAppName);
 logPrint2 (LDEBUG, gnLogLevel, gnTrcLogId, FL, "[%s] -------------------------------------\n", __func__);
#endif
 printf ("[%s] -------------------------------------\n", __func__);
 printf ("[%s]  STARTUP [%s]\n", __func__, gszAppName);
 printf ("[%s] -------------------------------------\n", __func__);

#if 0
 /* Init signal */
 InitSignal ();

 fnTerminate ();
#endif

 /* View all device */
 nRet = fnGetDeviceAll ();

 /* Select device */
 printf ("[%s] Select Device No 0-%d : ", __func__, nRet-1);
 scanf ("%d", &nDev);
 /* Check device range */
 if (nDev < 0 || nDev >= nRet)
 {
  printf ("[%s] Invalid device no %d\n", __func__, nDev);
  exit (0);
 }

 /* Start monitor */
#if 0
 if (fnDevMon (nDev) == RFAIL)
 {
  printf ("[%s] Device open failed\n", __func__);
  exit (0);
 }
#else
 pcap_t *pHandle;

 /* Open Device */
 pHandle = (pcap_t *) fnOpenDevice (nDev);
 if (pHandle == NULL)
 {
  printf ("[%s] fnOpenDevice (%d) FAILED [0x%08lx]\n", __func__, nDev, (unsigned long) pHandle);
  printf ("[%s] TERMINATE [%s]\n", __func__, gszAppName);
  exit (0);
 }
 else
  printf ("[%s] fnOpenDevice (%d) [0x%08lx]\n", __func__, nDev, (unsigned long) pHandle);

 nCnt = 0;
 /* Monitoring Loop */
 while (1)
 {
  nRet = fnReadPacket (pHandle);
  if (nRet == 0)
  {
   printf ("[%s] Timeout elapsed\n", __func__);
   continue;
  }
  if (nRet == -1)
  {
   printf ("[%s] Error reading the packets: %s\n", __func__, pcap_geterr (pHandle));
   break;
  }
  nCnt++;
  if (nCnt >= 10)
   break;
 }

 /* Close Device */
 fnCloseDevice (pHandle);
#endif

 printf ("[%s] TERMINATE [%s]\n", __func__, gszAppName);
 return 0;
} /* end of main () */

/*-----------------------------------------------------------------------------
 End of ipd_main.c
-----------------------------------------------------------------------------*/



 

+ Recent posts