#include <stdio.h>
#include <stdlib.h>
#include <pcap/pcap.h>
#include <net/ethernet.h>
#include <net/if_arp.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/if_ether.h>
typedef struct _PACKET
{
struct ether_header *stpEth;
struct ip *stpIP;
struct ether_arp *stpARP;
struct tcphdr *stpTCP;
}PACKET;
void PrintHexaNAscii(const unsigned char *, int);
void UEC_HPreEther(PACKET *);
void UEC_HPreARP(PACKET *);
void UEC_HDisplayIP(PACKET *);
void UEC_HPreTCP(PACKET *);
int const PROMISC = 1;
int const TIME_DELAY = 0;
int const READ_PACKET_Length = 1500;// 패킷의 최대 길이.
int main()
{
char *cpNICName;
const unsigned char *RBuf;
char caEBuf[PCAP_ERRBUF_SIZE];
struct pcap_pkthdr CInfo;
PACKET stPkt;
pcap_t *CD;
memset(&stPkt, 0x00, sizeof(PACKET));
// 화면 클리어
// write (1, "\033[1;1H\033[2J", 10);
cpNICName = pcap_lookupdev(caEBuf);
if(cpNICName == NULL)
{
perror(caEBuf);// 방어 코드
exit(100);
}
else
{
printf("### Interface : [%s]\n", cpNICName);
printf("### errorbuf : [%s]\n", caEBuf);
}
CD = pcap_open_live//장치 ID 윈도우의 핸들과 같음
(cpNICName, // 핸들 과 같음 식별자 ID
READ_PACKET_Length, // 패킷의 최대 길이.
PROMISC, //모든 패킷들을 잡겠다
TIME_DELAY, // 패킷을 기다리는시간
caEBuf);
if(CD == NULL)
{
perror(caEBuf);
exit(200);
}
else
{
printf("### Max Read Packet Length : [%d]Bytes\n", READ_PACKET_Length);
printf("### Promiscous Mode : [%s]\n", PROMISC ? "YES" : "NO");
printf("### Capture Time Delay : [%d]Sec\n",TIME_DELAY);
}
RBuf = pcap_next(CD, &CInfo);
printf("### Captured Packet Length : [%d]\n", CInfo.caplen);
stPkt.stpEth = (struct ether_header *)RBuf;
UEC_HPreEther(&stPkt);
UEC_HPreARP(&stPkt);
UEC_HDisplayIP(&stPkt);
UEC_HPreTCP(&stPkt);
PrintHexaNAscii(RBuf, CInfo.caplen);
pcap_close(CD);
return 0;
}
void PrintHexaNAscii(const unsigned char *buffer, int size)
{
int loop_temp = 0;
int counter = 0;
printf("Address 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D ");
printf("0E 0F 0123456789ABCDEF\n");
counter = 0;
if (200 < size) size = 200;
while(counter < size)
{
printf("0x%04X ", counter);
loop_temp = 0;
while(loop_temp < 16)
{
printf("%02X ", *buffer);
++buffer;
++loop_temp;
}
buffer = buffer - 16;
loop_temp = 0;
while(loop_temp < 16)
{
if(31 > *buffer || 127 <= *buffer)
{
putchar('.');
}
else
{
putchar(*buffer);
}
++buffer;
++loop_temp;
}
counter = counter + loop_temp;
putchar('\n');
}
}
void UEC_HPreEther(PACKET *stpPkt)
{
struct ether_header *stpEth;
if(0 == stpPkt)
{
return;
}
else if(0 == stpPkt->stpEth)
{
return;
}
else
{
stpEth = stpPkt->stpEth;
}
printf("### MAC [%02X:%02X:%02X:%02X:%02X:%02X] -> " // 맥어드레스의 출력
, stpEth->ether_shost[0]
, stpEth->ether_shost[1]
, stpEth->ether_shost[2]
, stpEth->ether_shost[3]
, stpEth->ether_shost[4]
, stpEth->ether_shost[5]);
printf("[%02X:%02X:%02X:%02X:%02X:%02X]\n"
, stpEth->ether_dhost[0]
, stpEth->ether_dhost[1]
, stpEth->ether_dhost[2]
, stpEth->ether_dhost[3]
, stpEth->ether_dhost[4]
, stpEth->ether_dhost[5]);
printf("### Layer2 Type : ");
switch(ntohs(stpEth->ether_type))
{
case ETHERTYPE_PUP:
printf("[ETHERTYPE_PUP]\n");
break;
case ETHERTYPE_IP:
stpPkt->stpIP= (struct ip *)(stpPkt->stpEth + 1);
printf("[ETHERTYPE_IP]\n");
break;
case ETHERTYPE_ARP:
printf("[ETHERTYPE_ARP]\n");
stpPkt->stpARP= (struct ether_arp *)(stpPkt->stpEth + 1);
break;
case ETHERTYPE_REVARP:
printf("[ETHERTYPE_REVARP]\n");
stpPkt->stpARP= (struct ether_arp *)(stpPkt->stpEth + 1);
break;
default:
printf("[Unknown Type]\n");
break;
}
return;
}
void UEC_HDisplayIP(PACKET *stpPkt)
{
struct ip *stpIP;
if(0 == stpPkt)
{
return;
}
else if(0 == stpPkt->stpIP)
{
return;
}
else
{
stpIP= stpPkt->stpIP;
}
printf("IP : Version : [%d]\n",
stpIP->ip_v);
printf("IP : Header Length : [%d]\n",
stpIP->ip_hl * 4);
printf("IP : Type Of Service : [%d]\n",
stpIP->ip_tos);
printf("IP : Total Length(IP Header + Data) : [%d]\n",
ntohs(stpIP->ip_len));
printf("IP : Identification : [%d]\n",
ntohs(stpIP->ip_id));
printf("IP : Don't Fragment Bit : [%s]\n",
( ntohs(stpIP->ip_off)&IP_DF ) ? "SET" : "NOT SET");
printf("IP : More Fragment Bit : [%s]\n",
( ntohs(stpIP->ip_off)&IP_MF ) ? "SET" : "NOT SET");
printf("IP : Fragment Offset : [%d]\n",
( ntohs(stpIP->ip_off)&IP_OFFMASK ));
printf("IP : Time To Live : [%d]\n",
stpIP->ip_ttl);
// Layer3 Protocol
printf("IP : Layer3 Protocol : [");
switch(stpIP->ip_p)
{
case IPPROTO_IP:
printf("IPPROTO_IP]\n");
break;
case IPPROTO_ICMP:
printf("IPPROTO_ICMP]\n");
break;
case IPPROTO_IGMP:
printf("IPPROTO_IGMP]\n");
break;
case IPPROTO_IPIP:
printf("IPPROTO_IPIP]\n");
break;
case IPPROTO_TCP:
printf("IPPROTO_TCP]\n");
stpPkt->stpTCP
= (struct tcphdr *)((char *)stpIP + (stpIP->ip_hl * 4));
break;
case IPPROTO_EGP:
printf("IPPROTO_EGP]\n");
break;
case IPPROTO_PUP:
printf("IPPROTO_PUP]\n");
break;
case IPPROTO_UDP:
printf("IPPROTO_UDP]\n");
break;
case IPPROTO_IDP:
printf("IPPROTO_IDP]\n");
break;
case IPPROTO_ROUTING:
printf("IPPROTO_ROUTING]\n");
break;
case IPPROTO_FRAGMENT:
printf("IPPROTO_FRAGMENT]\n");
break;
case IPPROTO_RAW:
printf("IPPROTO_RAW]\n");
break;
default:
printf("%d]\n", stpIP->ip_p);
break;
}
printf("IP : Check Sum : [%04X]\n",
ntohs(stpIP->ip_sum));
printf("IP : Source IP Address : [%s]\n",
inet_ntoa(stpIP->ip_src));
printf("IP : Destination IP Address : [%s]\n",
inet_ntoa(stpIP->ip_dst));
return;
}
void UEC_HPreARP(PACKET *stpPkt)
{
struct ether_arp *stpARP;
if(0 == stpPkt)
{
return;
}
else if(0 == stpPkt->stpARP)
{
return;
}
else
{
stpARP = stpPkt->stpARP;
}
printf("HARDWARE IDentifier : [");
switch(ntohs(stpARP->arp_hrd))
{
case ARPHRD_NETROM:
printf("NET/ROM pseud]\n");
break;
case ARPHRD_ETHER:
printf("Ethernet 10/100Mbps]\n");
break;
case ARPHRD_EETHER:
printf("Experimental Ethernet]\n");
break;
case ARPHRD_IEEE802:
printf("IEEE 802.2 Ethernet/TR/TB]\n");
break;
default:
printf("Not Support Type...]\n");
break;
}
printf("Protocol Address :[0x%04X]\n",ntohs(stpARP->arp_pro));
printf("Hardware Length :[%d]\n",stpARP->arp_hln);
printf("Protocol Length :[%d]\n",stpARP->arp_pln);
printf("ARP Command :[");
switch(ntohs(stpARP->arp_op))
{
case ARPOP_REQUEST:
printf("ARP Request]\n");
break;
case ARPOP_REPLY:
printf("ARP reply]\n");
break;
case ARPOP_RREQUEST:
printf("ARP RARP request]\n");
break;
case ARPOP_RREPLY:
printf("ARP RARP reply]\n");
break;
case ARPOP_InREQUEST:
printf("ARP InARP request]\n");
break;
case ARPOP_InREPLY:
printf("ARP InARP reply]\n");
break;
case ARPOP_NAK:
printf("ARP (ATM)ARP NAK]\n");
break;
default:
printf("Unknown Type...]\n");
break;
}
printf("MAC [%02X:%02X:%02X:%02X:%02X:%02X] -> "
, stpARP->arp_sha[0]
, stpARP->arp_sha[1]
, stpARP->arp_sha[2]
, stpARP->arp_sha[3]
, stpARP->arp_sha[4]
, stpARP->arp_sha[5]);
printf("[%02X:%02X:%02X:%02X:%02X:%02X]\n"
, stpARP->arp_tha[0]
, stpARP->arp_tha[1]
, stpARP->arp_tha[2]
, stpARP->arp_tha[3]
, stpARP->arp_tha[4]
, stpARP->arp_tha[5]);
printf("IP : [%d.%d.%d.%d] -> "
, stpARP->arp_spa[0]
, stpARP->arp_spa[1]
, stpARP->arp_spa[2]
, stpARP->arp_spa[3]);
printf("[%d.%d.%d.%d]\n"
, stpARP->arp_tpa[0]
, stpARP->arp_tpa[1]
, stpARP->arp_tpa[2]
, stpARP->arp_tpa[3]);
}
void UEC_HPreTCP(PACKET *stpPkt)
{
struct tcphdr *stpTCP;
if(0 == stpPkt)
{
return;
}
else if(0 == stpPkt->stpTCP)
{
return;
}
else
{
stpTCP = stpPkt->stpTCP;
}
printf("TCP : S Port : [%d]\n", ntohs(stpTCP->source));
printf("TCP : D Port : [%d]\n", ntohs(stpTCP->dest));
}