|
Facebook Joinc ±×·ì
Joinc QA »çÀÌÆ®
joinc´Â Firefox¿Í chrome¿¡¼ Å×½ºÆ® Çß½À´Ï´Ù. IE¿¡¼´Â Å×À̺íÀÌ ±úÁö°Å³ª À̹ÌÁö°¡ º¸ÀÌÁö ¾ÊÀ» ¼ö ÀÖ½À´Ï´Ù. ƯÈ÷ ±¸±Û DocsÀ̹ÌÁöÀÇ °æ¿ì ¿¢¹Úó¸®µÉ ¼ö ÀÖ½À´Ï´Ù.
Docbook ¿ø¹®
libpcap ¸¦ ÀÌ¿ëÇÑ ÇÁ·Î±×·¡¹Ö| 교정 과정 |
|---|
| 교정 0.5 | 2003³â 1¿ù 28ÀÏ 21½Ã | | | ÃÖÃÊ ¹®¼ ÀÛ¼º |
À̹ø °Á´ libpcap À» »ç¿ëÇÑ ÆÐŶ ĸÃç¿¡ ´ëÇÑ ³»¿ëÀÌ´Ù.
Libpcap(ÀÌÇÏ pcap)Àº "Portable Packet Capturing Library"ÀÇ
ÁÙÀÓ¸»À̸ç, ÇØ¼®±×´ë·Î "°£´ÜÇÏ°Ô ÆÐŶÀ» ĸÃÄÇϱâ À§ÇÑ
ÇÔ¼ö¸ðÀ½(¶óÀ̺귯¸®)" ÀÌ´Ù.
¹°·Ð pcap ¿Ü¿¡µµ ÆÐŶĸÃĸ¦ À§ÇÑ µµ±¸µéÀÌ ÀÖ±â´Â ÇÏÁö¸¸,
´ëºÎºÐÀÇ °æ¿ì ¿î¿µÃ¼Á¦¿¡ Á¾¼ÓÀûÀÌ¿©¼, ¿î¿µÃ¼Á¦º°·Î Äڵ带 ´Ù½Ã
Â¥¾ß ÇÑ´Ù´Â ºÒÆíÇÔÀÌ ÀÖ´Ù. ´ëÇ¥ÀûÀÎ µµ±¸·Î´Â
SOCK_PACKET, LSF, SNOOP, SNIT µîÀÌ ÀÖ´Ù.
ÀÌ¿¡ ºñÇØ pcap ´Â ¿î¿µÃ¼Á¦¿¡ »ó°ü¾øÀÌ ¹ü¿ëÀûÀ¸·Î »ç¿ë°¡´ÉÇÑ
API¸¦ Á¦°øÇØÁÜÀ¸·Î, °ø¿ëÇÁ·Î±×·¥ ȤÀº °ø¿ë¶óÀ̺귯¸®ÀÇ Á¦ÀÛÀÌ
°¡´ÉÇϵµ·Ï µµ¿ÍÁØ´Ù. ¶ÇÇÑ °£´ÜÇÏ°Ô »ç¿ë°¡´ÉÇÑ
»ç¿ëÀÚ ·¹º§ ¶óÀ̺귯¸®ÀÌ´Ù.
libpcap ¸¦ ÀÌ¿ëÇÑ °¡Àå ´ëÇ¥ÀûÀÎ ÇÁ·Î±×·¥ÀÌ tcpdump ¿Í SAINT ¿Í
°°Àº ÇÁ·Î±×·¥µéÀÌ´Ù.
¶ÇÇÑ »ó¿ë IDS
[1]
Á¦Ç°ÀÇ »ó´ç¼ö°¡ ÆÐŶºÐ¼®À» À§Çؼ libpcap À»
»ç¿ëÇϰí ÀÖ´Ù.
¿©·¯ºÐÀÌ Unix °è¿ ¿î¿µÃ¼Á¦¸¦ »ç¿ëÇϰí ÀÖ´Ù¸é, °ÅÀÇ ´ëºÎºÐ
tcpdump ¸¦ °ð¹Ù·Î »ç¿ëÇÒ¼ö ÀÖÀ»°ÍÀÌ´Ù. tcpdump ¸¦ »ç¿ëÇÒ¼ö
ÀÖ´Ù´Â °ÍÀº ±× ±â¹ÝÀÌ µÇ´Â libpcap ¿ª½Ã ¼³Ä¡µÇ¾î ÀÖ´Ù´Â ¸»ÀÌ
µÈ´Ù.
±×·¯³ª ¸¸¾àÀÇ °æ¿ì ¼³Ä¡°¡ µÇ¾î ÀÖÁö ¾Ê´Ù¸é tcpdump.org
¿¡¼ ¹Þ¾Æ¼ ÄÄÆÄÀÏÈÄ ¼³Ä¡Çϱ⠹ٶõ´Ù.
ÄÄÆÄÀÏ ÇϱⰡ ±ÍÂú´Ù¸é
±×¸®°í ·¹µåÇòÀ̳ª µ¥ºñ¾È °è¿ÀÇ ¸®´ª½º »ç¿ëÀÚ¶ó¸é
ÇØ´ç ÆÐŰÁö¸¦ ¹èÆ÷ÇÏ´Â ftp »çÀÌÆ®¿¡¼ ´Ù¿î ¹Þ¾Æ¼ ¼³Ä¡ÇÏ¸é µÈ´Ù.
¼Ö¶ó¸®½º ¿î¿µÃ¼Á¦ ¶ó¸é
www.sunfreeware.com
¿¡¼ ÆÐŰÁö¸¦ ¹Þ¾Æ¼ ¼³Ä¡Çϱ⠹ٶõ´Ù.
ÆÐŶ ĸÃÄ´Â ³×Æ®¿÷ »ó¿¡¼ µ¹¾Æ´Ù´Ï´Â ÆÐŶÀ» µé¿©´Ù º¸´Â °É
¸»ÇÑ´Ù. ÆÐŶ ĸÃĶó´Â ¾î°¨»ó ÆÐŶÀ» "Àâ´Â"°Ô ¾Æ´Ñ°¡ ¶ó°í
»ý°¢ÇÒ¼ö ÀÖÁö¸¸, ÆÐŶÀ» "ÀâÁö"´Â ¾Ê°í ´ÜÁö µé¿©´Ù¸¸ º¼ »ÓÀÌ´Ù.
¸¸¾à ¿©·¯ºÐÀÇ È£½ºÆ®°¡ Æ÷ÇÔµÈ ³×Æ®¿÷À» °ü¸®ÇÏ´Â ¶ó¿ìÅͰ¡
ÀϹÝÀûÀÎ(½ºÀ§ÄªÀÌ ¾Æ´Ñ) ¶ó¿ìÅͶó¸é, ³»ºÎ·Î ÇâÇÏ´Â ¸ðµç
ÆÐŶÀº ºê·Îµåij½ºÆÃ(Broadcasting) µÈ´Ù. ÀÌ´Â ½ºÀ§Äª ¶ó¿ìÅͰ¡
¾Æ´ÑÇÑÀº ¸ðµç ·ÎÄÃ³×Æ®¿÷ÀÇ ÆÐŶÀ» µé¿©´Ù º¼¼ö ÀÖÀ½À»
ÀǹÌÇϱ⵵ ÇÑ´Ù. ¾î¶µç À̰æ¿ì ¿î¿µÃ¼Á¦´Â Àڽſ¡°Ô µµÂøµÈ
ÆÐŶÁß ¸ñÀûÁö°¡ ÀÚ½ÅÀÎ ÆÐŶ¸¸À» ó¸®Çؼ Application Layer ±îÁö
¿Ã·Á º¸³»°Ô µÈ´Ù.
libpcap À» »ç¿ëÇϸé ÀÌ·¯ÇÑ ÆÐŶÀÇ Ä¸Ãİ¡ °¡´ÉÇØÁø´Ù.
ÀÎÅÍ³Ý »óÀÇ ÆÐŶÀº »ó´ë¹æ¿¡°Ô º¸³¾°æ¿ì encapuslation
°úÁ¤À» °ÅÄ¡°í, ¹ÞÀº ÆÐŶ¿¡ ´ëÇØ¼´Â demultiplexing
°úÁ¤À» °ÅÄ£´Ù´Â °ÍÀ» ¾Ë°í ÀÖÀ»°ÍÀÌ´Ù -
TCP/IP °³¿ä(3) Âü°í -
libpcap À» »ç¿ëÇØ¼ ĸÃÄÇÑ ÆÐŶÀº demultiplexing °úÁ¤À»
°ÅÄ¡±â ÀüÀÇ ÆÐŶÀÌ´Ù. ÀÌ·¸°Ô ÇØ¼ ĸÃÄÇÑ ÆÐŶÀº
°¢ ÇÁ·ÎÅäÄÝ ´ÜÀ§·Î(±¸Á¶Ã¼) ÀÐ¾î¼ Ã³¸®ÇÏ¸é µÈ´Ù.
´ÙÀ½Àº encapuslation&demultiplexing °úÁ¤ÀÌ´Ù.
ÆÐŶ ĸÃÄ´Â ¿©·¯°¡Áö ¸ñÀûÀ¸·Î »ç¿ëµÉ¼ö ÀÖ´Ù.
NIDS(Network Intrusion Detection System) ÇÁ·Î±×·¥ÀÌ °¡Àå
´ëÇ¥ÀûÀÎ ÀÀ¿ëÀ̸ç, ³×Æ®¿÷ Æ®·¡ÇÈ °¨½Ã, ³×Æ®¿÷ µð¹ö±ëÀ» À§ÇÑ
¿ëµµ·Î »ç¿ë°¡´ÉÇÏ´Ù.
À̹øÀå¿¡¼´Â libpcap ¿¡¼ ÇʼöÀûÀ¸·Î »ç¿ëµÇ´Â Áß¿ä
API ¿¡ ´ëÇØ¼ ¾Ë¾Æº¼°ÍÀÌ´Ù.
int pcap_lookupnet(char *device, bpf_u_int32 *netp,
bpf_u_int32 *maskp, char *errbuf)
|
³×Æ®¿÷ µð¹ÙÀ̽º¿¡ ´ëÇÑ ³×Æ®¿÷ ¹× mask ¹øÈ£¸¦ µÇµ¹·ÁÁØ´Ù.
³×Æ®¿÷ ¹øÈ£´Â netp¿¡ mask ¹øÈ£´Â
maskp¿¡ ÀúÀåµÈ´Ù.
device´Â pcap_lookupdev µîÀ» ÅëÇØ
¾ò¾î¿Â ³×Æ®¿÷ µð¹ÙÀ̽º À̸§ÀÌ´Ù.
¿¡·¯°¡ ¹ß»ýÇÒ°æ¿ì -1 ÀÌ ¸®ÅϵǸç, ¿¡·¯ ³»¿ëÀÌ errbuf ¿¡
ÀúÀåµÈ´Ù.
pcap_open_live() ¿Í pcap_lookupnet() ¿¡¼ »ç¿ëÇϱâ À§ÇÑ
³×Æ®¿÷ µð¹ÙÀ̽º¿¡ ´ëÇÑ Æ÷ÀÎÅ͸¦ µÇµ¹·ÁÁØ´Ù.
¼º°øÇÒ °æ¿ì "eth0", "eth1" °ú °°Àº À̸§À» µÇµ¹·ÁÁÖ¸ç
½ÇÆÐÇÒ°æ¿ì 0À» µÇµ¹·ÁÁØ´Ù.
link layer ŸÀÔÀ» µÇµ¹·ÁÁØ´Ù(DLT_EN10MB °ú °°Àº)
¿¹Á¦ : pcap.c
#include <stdio.h>
#include <stdlib.h>
#include <pcap.h> //libpcap Çì´õ Æ÷Çè
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(int argc, char **argv)
{
char *dev; // »ç¿ëÁßÀÎ ³×Æ®¿÷ µð¹ÙÀ̽º À̸§
char *net; // ³×Æ®¿÷ ¾îµå·¹½º
char *mask; // ³×Æ®¿÷ mask ¾îµå·¹½º
int ret; //
char errbuf[PCAP_ERRBUF_SIZE];
bpf_u_int32 netp; // ip
bpf_u_int32 maskp; // submet mask
struct in_addr addr;
// ³×Æ®¿÷ µð¹ÙÀ̽º À̸§À» ¾ò¾î¿Â´Ù.
dev = pcap_lookupdev(errbuf);
// ¿¡·¯°¡ ¹ß»ýÇßÀ»°æ¿ì
if(dev == NULL)
{
printf("%s\n",errbuf);
exit(1);
}
// ³×Æ®¿÷ µð¹ÙÀ̽º À̸§ Ãâ·Â
printf("DEV: %s\n",dev);
// ³×Æ®¿÷ µð¹ÙÀ̽º À̸§ dev ¿¡ ´ëÇÑ
// mask, ip Á¤º¸ ¾ò¾î¿À±â
ret = pcap_lookupnet(dev,&netp,&maskp,errbuf);
if(ret == -1)
{
printf("%s\n",errbuf);
exit(1);
}
// ³×Æ®¿÷ ¾îµå·¹½º¸¦ Á¡¹ÚÀÌ 3ÇüÁ¦ ½ºÅ¸ÀÏ·Î
addr.s_addr = netp;
net = inet_ntoa(addr);
if(net == NULL)
{
perror("inet_ntoa");
exit(1);
}
printf("NET: %s\n",net);
// ¸¶Âù°¡Áö·Î mask ¾îµå·¹½º¸¦ Á¡¹ÚÀÌ 3ÇüÁ¦ ½ºÅ¸ÀÏ·Î
addr.s_addr = maskp;
mask = inet_ntoa(addr);
if(mask == NULL)
{
perror("inet_ntoa");
exit(1);
}
printf("MASK: %s\n",mask);
return 0;
}
|
´ÙÀ½Àº ÄÄÆÄÀÏ ¹æ¹ýÀÌ´Ù. ÄÄÆÄÀÏ È¯°æÀº
Redhat Linux 8.x, gcc 3.x ÀÌ´Ù.
[root@localhost test]# gcc -o pcap pcap.c -lpcap -I/usr/include/pcap
|
pcap.h ÀÇ À§Ä¡´Â ¿î¿µÃ¼Á¦ ¸¶´Ù ´Ù¸¦¼ö ÀÖÀ¸´Ï È®ÀÎÈÄ
ÄÄÆÄÀÏ Çϱ⠹ٶõ´Ù.
´ÙÀ½Àº ½ÇÇà°á°úÀÌ´Ù.
[root@localhost test]# ./pcap
DEV: eth0
NET: 192.168.xxx.x
MASK: 255.255.xxx.x
|
ÆÄÀϰü·Ã ÀÛ¾÷À» ÇÒ¶§ file descriptor(ÆÄÀÏÁöÁ¤ÀÚ)¸¦
ÀÌ¿ëÇØ¼ ÀÛ¾÷Çϴ°Ͱú ¸¶Âù°¡Áö·Î, ÆÐŶ ĸÃİü·Ã
ÀÛ¾÷À» ÇÒ¶§¿¡µµ packet capture descriptor ¸¦ °¡Áö°í
ÀÛ¾÷À» ÇÑ´Ù.
packet capture descriptor ´Â pcatp_t * ÇüÀ¸·Î ¼±¾ðµÇ¾î
ÀÖ´Ù.
pcap_t *pcap_open_live(char *device, int snaplen,
int promisc, int to_ms, char *ebuf)
|
ù¹øÂ° ÀÎÀÚ·Î ÁÖ¾îÁö´Â ³×Æ®¿÷ µð¹ÙÀ̽º
device¿¡ ´ëÇÑ packet capture
descriptor(ÀÌÇÏ PCD) À» ¸¸µé±â À§ÇÑ ÇÔ¼öÀÌ´Ù. ÆÐŶÀ»
ĸÃçÇÏ´Â ½ÇÁúÀûÀÎ ¸ðµçÀÏÀº pcap_open_live ÇÔ¼ö¸¦ È£ÃâÇØ¼
¸¸µé¾îÁø PCD ¸¦ ÀÌ¿ëÇØ¼ ÀÌ·ç¾îÁö°Ô µÈ´Ù.
linux Ä¿³Î 2.2 ÀÌ»óÀÇ °æ¿ì device ¸¦ "any" ȤÀº NULL·Î
ÇÒ°æ¿ì ¸ðµç ³×Æ®¿÷µð¹ÙÀ̽º¿¡ ´ëÇØ¼ ÆÐŶ ĸÃİ¡ ÀϾ°Ô
µÈ´Ù.
snaplenÀº ¹Þ¾ÆµéÀϼö ÀÖ´Â
ÆÐŶÀÇ ÃÖ´ë Å©±â(byte)ÀÌ´Ù.
promisc ´Â ³×Æ®¿÷ µð¹ÙÀ̽º¸¦
promiscuous mode ·Î ÇÒ°ÍÀÎÁö¸¦ °áÁ¤Çϱâ À§Çؼ »ç¿ëÇÑ´Ù.
promisc °¡ 1Àϰæ¿ì promiscuous ¸ðµå°¡ µÇ¸ç,
·ÎÄà ³×Æ®¿÷ÀÇ ¸ðµç ÆÐŶÀ» ĸÃÄÇÏ°Ô µÈ´Ù. 0 Àϰæ¿ì
¿¡´Â Àڱ⿡°Ô¸¸ ÇâÇÏ´Â ÆÐŶÀ» ĸÃÄÇÏ°Ô µÇ´Âµ¥, ¸î¸î
°æ¿ì¿¡ ÀÖ¾î¼ promiscuous ¸ðµå·Î ÀÛµ¿Çϱ⵵ ÇÑ´Ù.
to_ms ´Â Àб⠽ð£Ãʰú(time out)
ÁöÁ¤À» À§Çؼ »ç¿ëµÇ¸ç millisecond ´ÜÀ§ÀÌ´Ù.
ebuf ´Â pcap_open_live ÇÔ¼ö È£Ãâ¿¡
¹®Á¦°¡ »ý°åÀ»°æ¿ì ¿¡·¯ ¸Þ½ÃÁö¸¦ ÀúÀåÇϱâ À§Çؼ
»ç¿ëÇÑ´Ù. ¸¸¾à pcap_open_live ÇÔ¼ö È£Ãâ½Ã ¿¡·¯°¡
¹ß»ýÇÒ°æ¿ì NULL À» ¸®ÅÏÇÏ°í ¿¡·¯³»¿ëÀ» ebuf ¿¡ º¹»çÇÑ´Ù.
fname ¸¦ °¡Áö´Â ÆÄÀÏ·Î ºÎÅÍ
ÆÐŶÀ» ÀоîµéÀδÙ. ¸¸¾à fname ÀÌ "-" ÀÏ °æ¿ì
stdinÀ¸·Î ºÎÅÍ ÀоîµéÀδÙ.
ebuf ´Â ¿¡·¯¸Þ½ÃÁö¸¦ ÀúÀåÇϱâ
À§Çؼ »ç¿ëµÈ´Ù.
À̹øÀå¿¡¼´Â ½ÇÁ¦ ÆÐŶÀ» ĸÃÄÇÏ´Â °ü·Ã API µé¿¡ ´ëÇØ¼
¾Ë¾Æº¼°ÍÀÌ´Ù. ÀÌ ÆÐŶ ĸó °ü·Ã API ¸¦ Á¦´ë·Î ÀÌÇØÇϰí
»ç¿ëÇϱâ À§Çؼ´Â TCP/IP¿Í ÀÌ´õ³Ý ÇÁ·ÎÅäÄÝÀÇ ±¸Á¶¿¡
´ëÇØ¼ ¾î´ÀÁ¤µµ ÀÌÇØ¸¦ ÇØ¾ß ÇÑ´Ù. ±×·³À¸·Î API ¸¦ ´Ù·ç±â
Àü¿¡ ÀÌµé ´ëÇ¥ÀûÀÎ ÇÁ·ÎÅäÄݵ鿡 ´ëÇÑ Çì´õ Á¤º¸¿¡
´ëÇØ¼ °£·«ÇÏ°Ô ¸ÕÀú ¾Ë¾Æº¸µµ·Ï ÇϰڴÙ.
ÆÐŶ Read °ü·Ã API¿¡¼´Â ÆÐŶÀ» ÀоúÀ»¶§,
Demultiplexing ÀÌ µÇÁö ¾ÊÀº ¿ÏÀüÇÑ ±¸Á¶ÀÇ ÆÐŶÀ»
³Ñ°ÜÁØ´Ù. ±×·³À¸·Î ÃÖ¼ÒÇÑ ÀÌµé °¢ ÆÐŶÀÇ ±¸Á¶Ã¼
Á¤º¸¸¦ ¾Ë°í ÀÖ¾î¾ß °¢ °èÃþ(Layer)ÀÇ µ¥ÀÌŸ¸¦
Àоî¿Ã¼ö ÀÖ´Ù.
´ÙÀ½Àº TCP, IP, Eternet ±¸Á¶Ã¼Á¤º¸ÀÌ´Ù.
tcp Çì´õ ±¸Á¶Ã¼
struct tcphdr
{
u_int16_t th_sport; /* source port */
u_int16_t th_dport; /* destination port */
tcp_seq th_seq; /* sequence number */
tcp_seq th_ack; /* acknowledgement number */
# if __BYTE_ORDER == __LITTLE_ENDIAN
u_int8_t th_x2:4; /* (unused) */
u_int8_t th_off:4; /* data offset */
# endif
# if __BYTE_ORDER == __BIG_ENDIAN
u_int8_t th_off:4; /* data offset */
u_int8_t th_x2:4; /* (unused) */
# endif
u_int8_t th_flags;
# define TH_FIN 0x01
# define TH_SYN 0x02
# define TH_RST 0x04
# define TH_PUSH 0x08
# define TH_ACK 0x10
# define TH_URG 0x20
u_int16_t th_win; /* window */
u_int16_t th_sum; /* checksum */
u_int16_t th_urp; /* urgent pointer */
};
|
IP Çì´õ ±¸Á¶Ã¼
struct ip
{
#if __BYTE_ORDER == __LITTLE_ENDIAN
unsigned int ip_hl:4; /* header length */
unsigned int ip_v:4; /* version */
#endif
#if __BYTE_ORDER == __BIG_ENDIAN
unsigned int ip_v:4; /* version */
unsigned int ip_hl:4; /* header length */
#endif
u_int8_t ip_tos; /* type of service */
u_short ip_len; /* total length */
u_short ip_id; /* identification */
u_short ip_off; /* fragment offset field */
#define IP_RF 0x8000 /* reserved fragment flag */
#define IP_DF 0x4000 /* dont fragment flag */
#define IP_MF 0x2000 /* more fragments flag */
#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
u_int8_t ip_ttl; /* time to live */
u_int8_t ip_p; /* protocol */
u_short ip_sum; /* checksum */
struct in_addr ip_src, ip_dst; /* source and dest address */
};
|
ETHERNET Çì´õ ±¸Á¶Ã¼
struct ethhdr
{
unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
unsigned char h_source[ETH_ALEN]; /* source ether addr */
unsigned short h_proto; /* packet type ID field */
};
|
ip, tcp Çì´õ ÆÄÀÏÀº /usr/include/netinet ¹Ø¿¡¼ ãÀ»¼ö
ÀÖÀ¸¸ç, ethernet Çì´õ ÆÄÀÏÀº /usr/include/linux/if_ether.h
¿¡¼ ãÀ»¼ö ÀÖ´Ù.
Ethernet Çì´õ¿Í IP Çì´õÀÇ °æ¿ì demultiplexing °úÁ¤À»
°ÅÄ¡±â À§Çؼ »óÀ§ Layer ÀÇ ÇÁ·ÎÅäÄÝ Å¸ÀÔÀ»
ÁöÁ¤Çϰí ÀÖÀ½À» ¾Ë¼ö ÀÖ´Ù.
Ethernet Çì´õÀÇ h_proto ¿Í IP Çì´õÀÇ ip_p °¡
°¢ »óÀ§ Layer ÀÇ ÇÁ·ÎÅäÄÝ Å¸ÀÔÀ» ¾Ë·ÁÁÖ±â À§Çؼ
»ç¿ëµÈ´Ù.
ºÎ¿¬¼³¸íÀ» ÇÏÀÚ¸é ¿î¿µÃ¼Á¦°¡ ÆÐŶÀ» ¹ÞÀ¸¸é °¡Àå ¸ÕÀú
Link ·¹À̾ °ÅÄ¡´Âµ¥, Link ·¹À̾¼´Â
Ethernet Çì´õ¸¦ ºÐ¼®Çؼ ÆÐŶÀÌ Network ·¹ÀÌ¾î ·Î
Àü´ÞµÇ´Â ÆÐŶÀÎÁö È®ÀÎÇØ¼ Network ·¹À̾î·Î Àü´ÞµÈ´Ù¸é
ÇØ´ç ÆÐŶÀÌ IP ÆÐŶÀÎÁö
¾Æ´Ï¸é ICMP, IGMP ¿Í °°Àº ÆÐŶÀÎÁö¸¦ °Ë»çÇÑÈÄ
Network ·¹À̾îÀÇ ¾Ë¸ÂÀº 󸮷çƾÀ¸·Î º¸³¾°ÍÀÌ´Ù.
Network ·¹À̾¼´Â ÆÐŶÀ» ¹ÞÀº ´ÙÀ½
ÀÚ½ÅÀÇ ÇÁ·ÎÅäÄÝ Çì´õ¸¦
°Ë»çÇØ¼ ÀÌ ÆÐŶÀÌ Transport ·¹À̾î·Î Àü´ÞµÇ´Â
ÆÐŶÀÎÁö È®ÀÎÇϰí, Transport ·¹À̾î·Î Àü´ÞµÈ´Ù¸é
UDP ÀÎÁö, TCP ÀÎÁö¸¦ È®ÀÎÇÑ´ÙÀ½¿¡ Transport ·¹À̾îÀÇ
Àû´çÇÑ Ã³¸®·çƾÀ¸·Î ÆÐŶÀ» ´øÁú°ÍÀÌ´Ù. ÃÖÈÄ¿¡
´Â TCP Çì´õ¸¸ ³²°Ô µÇ´Âµ¥, TCP Çì´õÀÇ PORT ¸¦ °Ë»çÇØ¼
¾î¶² ¾îÇø®ÄÉÀ̼ǿ¡°Ô Àü´ÞµÇ¾î¾ß ÇÏ´ÂÁö¸¦ ÃÖÁ¾
°áÁ¤ÇÏ°Ô µÈ´Ù.
u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h)
|
´ÙÀ½ ÆÐŶ¿¡ ´ëÇÑ Æ÷ÀÎÅ͸¦ ¸®ÅÏÇÑ´Ù.
¿ì¸®´Â ÀÌ ÆÐŶÀ» ÀÐÀ½À¸·Î½á ÆÐŶÀÇ Á¤º¸¸¦ ¾ò¾î¿Ã¼ö
ÀÖ´Ù. ½ÇÁö·Î ÀÌ ÇÔ¼ö¸¦ ÀÌ¿ëÇØ¼ ÆÐŶĸÃÄ¿Í °ü·ÃµÈ
¸ðµç ÀÏÀ» ÇÒ¼ö ÀÖ´Ù. ³ª¸ÓÁö ÆÐŶĸÃÄ¿Í °ü·ÃµÈ
ÇÔ¼öµéÀº (pcap_loop °°Àº) ÀÌ ÇÔ¼öÀÇ ±â´É
Ãß°¡¹öÁ¯ À̶ó°í º¼¼ö ÀÖ´Ù.
int pcap_loop(pcap_t *p, int cnt,
pcap_handler callback, u_char *user)
|
p ´Â PCD À̸ç,
cnt ´Â ÆÐŶ ĸÃĸ¦ ¸î¹ø¿¡ °ÉÃļ
ÇÒ°ÍÀÎÁö¸¦ °áÁ¤Çϱâ À§Çؼ »ç¿ëÇÑ´Ù.
¸¸¾à 0ÀÌ ÁöÁ¤µÇ¸é °è¼Ó ÆÐŶÀ» ¹Þ¾ÆµéÀÌ°Ô µÈ´Ù.
callback ´Â ÆÐŶÀÌ µé¾î¿ÔÀ»¶§
½ÇÇàÇÏ´Â ÇÔ¼öÀÇ Æ÷ÀÎÅÍÀÌ´Ù. º¸ÅëÀº ÆÐŶÇÊÅ͸µ°ú °ü·ÃµÈ
ÇÔ¼ö°¡ ½ÇÇàµÉ°ÍÀÌ´Ù.
int pcap_dispatch(pcap_t *p, int cnt,
pcap_handler callback, u_char *user)
|
pcap_loop ¿Í °ÅÀÇ ºñ½ÁÇÏ´Ù.
int pcap_compile(pcap_t *p, struct bpf_program *fp,
char *str, int optimize, bpf_u_int32 netmask)
|
µé¾î¿À´Â ÆÐŶÀ» ÇÊÅ͸µ ÇØ¼ ¹Þ¾ÆµéÀ̱â À§Çؼ »ç¿ëÇÑ´Ù.
¿¹¸¦ µé¾î tcpdump ¿¡¼ port 80 À¸·Î ¿À´Â ÆÐŶ¸¸À»
ĸÃÄÇϱâ À§Çؼ ´ÙÀ½°ú °°ÀÌ »ç¿ëÇÏ´Â°É º¸¾ÒÀ»°Í
ÀÌ´Ù.
[root@coco /root]# tcpdump port 80
Kernel filter, protocol ALL, TURBO mode (575 frames), datagram packet socket
tcpdump: listening on all devices
|
tcpdump ¸í·É ½ÇÇà½Ãų¶§ µÚ¿¡ ÁØ ¿É¼ÇÀÎ "port 80" ÀÌ
filter rule À̸ç, str ¾Æ±Ô¸ÕÆ®¸¦
ÅëÇØ¼ Àü´ÞµÈ´Ù.
fp bfp_program ±¸Á¶Ã¼ÀÇ Æ÷ÀÎÅÍÀ̸ç
pcap_compile ¿¡ ÀÇÇØ¼ ä¿öÁø´Ù.
netmask´Â ·ÎÄà ³×Æ®ÀÇ netmask ÀÌ´Ù.
filter rule ¿¡ ´ëÇÑ ³»¿ëÀº tcpdump ÀÇ man ÆäÀÌÁö¿¡
»ó¼¼ÇÏ°Ô ³ª¿Í ÀÖÀ¸´Ï Âü°íÇϱ⠹ٶõ´Ù.
pcap_compile À» ÅëÇØ¼ ÁöÁ¤µÈ ÇÊÅ͸¦ Àû¿ë½Ã۱â
À§Çؼ »ç¿ëµÇ¸ç, ¾ÕÀ¸·Î µé¾î¿À´Â ÆÐŶ¿¡ ´ëÇØ¼´Â
ÀÌ ÇÊÅÍ·ê¿¡ ÀÇÇØ¼ ÇÊÅ͸µ µÈ´Ù.
pcap ÀÇ ±âº»ÀûÀÎ API ¸¦ »ìÆìºÃÀ¸´Ï
Á÷Á¢ Äڵ带 ÀÛ¼ºÇØ º¸µµ·Ï ÇϰڴÙ.
¿¹Á¦ : pcap_test.c
#include <sys/time.h>
#include <netinet/in.h>
#include <net/ethernet.h>
#include <pcap/pcap.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <netinet/ip_icmp.h>
#define PROMISCUOUS 1
#define NONPROMISCUOUS 0
// IP Çì´õ ±¸Á¶Ã¼
struct ip *iph;
// TCP Çì´õ ±¸Á¶Ã¼
struct tcphdr *tcph;
// ÆÐŶÀ» ¹Þ¾ÆµéÀϰæ¿ì ÀÌ ÇÔ¼ö¸¦ È£ÃâÇÑ´Ù.
// packet °¡ ¹Þ¾ÆµéÀÎ ÆÐŶÀÌ´Ù.
void callback(u_char *useless, const struct pcap_pkthdr *pkthdr,
const u_char *packet)
{
static int count = 1;
struct ether_header *ep;
unsigned short ether_type;
int chcnt =0;
int length=pkthdr->len;
// ÀÌ´õ³Ý Çì´õ¸¦ °¡Á®¿Â´Ù.
ep = (struct ether_header *)packet;
// IP Çì´õ¸¦ °¡Á®¿À±â À§Çؼ
// ÀÌ´õ³Ý Çì´õ Å©±â¸¸Å offset ÇÑ´Ù.
packet += sizeof(struct ether_header);
// ÇÁ·ÎÅäÄÝ Å¸ÀÔÀ» ¾Ë¾Æ³½´Ù.
ether_type = ntohs(ep->ether_type);
// ¸¸¾à IP ÆÐŶÀ̶ó¸é
if (ether_type == ETHERTYPE_IP)
{
// IP Çì´õ¿¡¼ µ¥ÀÌŸ Á¤º¸¸¦ Ãâ·ÂÇÑ´Ù.
iph = (struct ip *)packet;
printf("IP ÆÐŶ\n");
printf("Version : %d\n", iph->ip_v);
printf("Header Len : %d\n", iph->ip_hl);
printf("Ident : %d\n", ntohs(iph->ip_id));
printf("TTL : %d\n", iph->ip_ttl);
printf("Src Address : %s\n", inet_ntoa(iph->ip_src));
printf("Dst Address : %s\n", inet_ntoa(iph->ip_dst));
// ¸¸¾à TCP µ¥ÀÌŸ ¶ó¸é
// TCP Á¤º¸¸¦ Ãâ·ÂÇÑ´Ù.
if (iph->ip_p == IPPROTO_TCP)
{
tcph = (struct tcp *)(packet + iph->ip_hl * 4);
printf("Src Port : %d\n" , ntohs(tcph->source));
printf("Dst Port : %d\n" , ntohs(tcph->dest));
}
// Packet µ¥ÀÌŸ ¸¦ Ãâ·ÂÇÑ´Ù.
// IP Çì´õ ºÎÅÍ Ãâ·ÂÇÑ´Ù.
while(length--)
{
printf("%02x", *(packet++));
if ((++chcnt % 16) == 0)
printf("\n");
}
}
// IP ÆÐŶÀÌ ¾Æ´Ï¶ó¸é
else
{
printf("NONE IP ÆÐŶ\n");
}
printf("\n\n");
}
int main(int argc, char **argv)
{
char *dev;
char *net;
char *mask;
bpf_u_int32 netp;
bpf_u_int32 maskp;
char errbuf[PCAP_ERRBUF_SIZE];
int ret;
struct pcap_pkthdr hdr;
struct in_addr net_addr, mask_addr;
struct ether_header *eptr;
const u_char *packet;
struct bpf_program fp;
pcap_t *pcd; // packet capture descriptor
// »ç¿ëÁßÀÎ µð¹ÙÀ̽º À̸§À» ¾ò¾î¿Â´Ù.
dev = pcap_lookupdev(errbuf);
if (dev == NULL)
{
printf("%s\n", errbuf);
exit(1);
}
printf("DEV : %s\n", dev);
// µð¹ÙÀ̽º À̸§¿¡ ´ëÇÑ ³×Æ®¿÷/¸¶½ºÅ© Á¤º¸¸¦ ¾ò¾î¿Â´Ù.
ret = pcap_lookupnet(dev, &netp, &maskp, errbuf);
if (ret == -1)
{
printf("%s\n", errbuf);
exit(1);
}
// ³×Æ®¿÷/¸¶½ºÆ® Á¤º¸¸¦ Á¡¹ÚÀÌ 3ÇüÁ¦ ½ºÅ¸ÀÏ·Î º¯°æÇÑ´Ù.
net_addr.s_addr = netp;
net = inet_ntoa(net_addr);
printf("NET : %s\n", net);
mask_addr.s_addr = maskp;
mask = inet_ntoa(mask_addr);
printf("MSK : %s\n", mask);
printf("=======================\n");
// µð¹ÙÀ̽º dev ¿¡ ´ëÇÑ packet capture
// descriptor ¸¦¾ò¾î¿Â´Ù.
pcd = pcap_open_live(dev, BUFSIZ, NONPROMISCUOUS, -1, errbuf);
if (pcd == NULL)
{
printf("%s\n", errbuf);
exit(1);
}
// ÄÄÆÄÀÏ ¿É¼ÇÀ» ÁØ´Ù.
if (pcap_compile(pcd, &fp, argv[2], 0, netp) == -1)
{
printf("compile error\n");
exit(1);
}
// ÄÄÆÄÀÏ ¿É¼Ç´ë·Î ÆÐŶÇÊÅÍ ·êÀ» ¼¼ÆÃÇÑ´Ù.
if (pcap_setfilter(pcd, &fp) == -1)
{
printf("setfilter error\n");
exit(0);
}
// ÁöÁ¤µÈ Ƚ¼ö¸¸Å ÆÐŶĸÃĸ¦ ÇÑ´Ù.
// pcap_setfilter À» Åë°úÇÑ ÆÐŶÀÌ µé¾î¿Ã°æ¿ì
// callback ÇÔ¼ö¸¦ È£ÃâÇϵµ·Ï ÇÑ´Ù.
pcap_loop(pcd, atoi(argv[1]), callback, NULL);
}
|
ÄÄÆÄÀÏ ¹æ¹ýÀº ¾Æ·¡¿Í °°´Ù.
[root@localhost pcap_test]# gcc -o pcap_test pcap_test.c -lpcap -I/usr/include/pcap
|
´ÙÀ½Àº ÇÊÀÚÀÇ Linux ¹Ú½º¿¡¼ Å×½ºÆ®ÇÑ °á°úÀÌ´Ù.
[root@localhost pcap_test]# ./pcap_test -1 "port 80"
DEV : eth0
NET : 192.168.100.0
MSK : 255.255.255.0
=======================
IP ÆÐŶ
Version : 4
Header Len : 5
Ident : 51804
TTL : 64
Src Address : 192.168.100.130
Dst Address : 218.234.19.87
Src Port : 4996
Dst Port : 80
45000034ca5c400040065cfbc0a86482
daea1357138400502e7a303b2e7cc456
801021f0badb00000101080a0014e136
22631d7b485454502f312e3120323030
204f
IP ÆÐŶ
Version : 4
Header Len : 5
Ident : 41787
TTL : 54
Src Address : 218.234.19.87
Dst Address : 192.168.100.130
Src Port : 80
Dst Port : 4996
|
ÀÌ»ó °£´ÜÇÏ°Ô libpcap ÀÇ »ç¿ë¹æ¹ý¿¡ ´ëÇØ¼ ¾Ë¾Æº¸¾Ò´Ù.
À̹ø ±Û¿¡¼´Â libpcap ÀÇ »ç¿ë¹ý¿¡¸¸ ÃÊ÷À» ¸ÂÃß°í Àִµ¥,
´ÙÀ½¹ø °Á¿¡¼´Â ¸î°¡Áö "ÀÀ¿ë" ¿¡ ´ëÇØ¼ ¾Ë¾Æº¸µµ·Ï ÇϰڴÙ.
|
category_network programing
|
|
|