ãã®ããã¹ãã¯ã pcapã䜿çšããTim Carstens Programmingã«ãã2002幎ã®èšäºã®ç¿»èš³ã§ãã ãã·ã¢èªã®ã€ã³ã¿ãŒãããã«ã¯ããŸãå€ãã®PCAPæ
å ±ããããŸããã ãã®ç¿»èš³ã¯ãäž»ã«ãã©ãã£ãã¯ãã£ããã£ã®ãããã¯ã«èå³ã®ãã人åãã«äœæãããŸããããåæã«è±èªãäžæã«è©±ããŸããã å®éãã«ããã®äžã§ã¯ã翻蚳ãã®ãã®ã§ãã
ãšã³ããªãŒ
ãã®èšäºã®å¯Ÿè±¡è
ãæ±ºå®ããããšããå§ããŸãããã æããã«ãèšäºã«èšèŒãããŠããã³ãŒããçè§£ããã«ã¯ãCã®åºæ¬çãªç¥èãå¿
èŠã§ãïŒãã¡ãããåã«çè«ãçè§£ãããå Žåãé€ããŸãïŒãããããããã°ã©ãã³ã°ã®å¿è
ã§ããå¿
èŠã¯ãããŸããããã¹ãŠã®æŠå¿µã詳现ã«èª¬æããŸãã ãŸããPCAPã¯ã¹ãããã£ã³ã°ãå®è£
ããããã®ã©ã€ãã©ãªã§ããããããããã¯ãŒã¯ã®æäœã«é¢ããåºæ¬çãªç¥èãçè§£ã«åœ¹ç«ã¡ãŸãã ããã§ç޹ä»ãããã¹ãŠã®ã³ãŒãäŸã¯ãããã©ã«ãã®ã«ãŒãã«ã䜿çšããŠFreeBSD 4.3ã§ãã¹ããããŠããŸãã
æåã«çè§£ããããšã¯ãPCAPã¹ããã¡ãŒã®äžè¬çãªæ§é ã§ãã æ¬¡ã®ããã«ãªããŸãã
- ãŸãããã©ãã£ãã¯ãåä¿¡ããã€ã³ã¿ãŒãã§ã€ã¹ã®èå¥åãå®çŸ©ããããšããå§ããŸãããã Linuxã§ã¯
eth0
ãããªãã®ãBSDã§ã¯xl1
ãªã©ã«ãªããŸãã ãã®èå¥åãæååã§æå®ããããPCAPã«æäŸããŠãããããšãã§ããŸãã - 次ã«ãPCAPãåæåããå¿
èŠããããŸãã ãã®æ®µéã§ã䜿çšããããã€ã¹ã®PCAPåã転éããå¿
èŠããããŸãã å¿
èŠã«å¿ããŠãè€æ°ã®ããã€ã¹ãããã©ãã£ãã¯ããã£ããã£ã§ããŸãã ã»ãã·ã§ã³èšè¿°åã䜿çšããŠããããåºå¥ããŸãã ãã¡ã€ã«ã®æäœäžãšåæ§ã«ããã©ãã£ãã¯ãã£ããã£ã»ãã·ã§ã³ã«ååãä»ããŠãä»ã®åæ§ã®ã»ãã·ã§ã³ãšåºå¥ã§ããããã«ããå¿
èŠããããŸãã
- ç¹å®ã®ãã©ãã£ãã¯ïŒããšãã°ãTCP / IPãã±ããã®ã¿ããŸãã¯ããŒã23ããã®ã¿ã®ãã±ãããªã©ïŒãåä¿¡ããå Žåã¯ãäžé£ã®ã«ãŒã«ãäœæãããããããã³ã³ãã€ã«ãããŠãç¹å®ã®ã»ãã·ã§ã³ã«é©çšããå¿
èŠããããŸãã ããã¯3段éã®å¯æ¥ã«é¢é£ããããã»ã¹ã§ãã äžé£ã®ã«ãŒã«ã¯æåã¯è¡ã«ããããã®åŸãçè§£å¯èœãªPCAP圢åŒã«ã³ã³ãã€ã«ãããŸãã ã³ã³ãã€ã«ã¯ãããã°ã©ã å
ã§é¢æ°ãåŒã³åºãããšã§å®è¡ãããå€éšã¢ããªã±ãŒã·ã§ã³ã®äœ¿çšãšã¯é¢ä¿ãããŸããã æ¬¡ã«ãå¿
èŠãªã»ãã·ã§ã³ã«ãã®ãã£ã«ã¿ãŒãé©çšããããã«PCAPã«æç€ºããŸãã
- æåŸã«ãPCAPã«ãã©ãã£ãã¯ã®ãã£ããã£ãéå§ããããæç€ºããŸãã
pcap_loop
ã䜿çšããå ŽåãPCAPã¯ãæå®ããæ°ã®ãã±ãããåä¿¡ãããŸã§åäœããŸãã åœŒã¯æ°ããããã±ãŒãžãåãåããã³ã«ãå®çŸ©ãã颿°ãåŒã³åºããŸãã ãã®é¢æ°ã¯äœã§ãã§ããŸãã 圌女ã¯ããã±ãŒãžãèªã¿ããã®æ
å ±ããŠãŒã¶ãŒã«è»¢éãããããã¡ã€ã«ã«ä¿åããããäœãããªãã£ããããããšãã§ããŸãã - ãã£ããã£ãžã§ããå®äºããããã»ãã·ã§ã³ãéããããšãã§ããŸãã
ããã¯å®éã«ã¯éåžžã«ç°¡åãªããã»ã¹ã§ãã 5ã€ã®ã¹ãããã®ã¿ã§ããã®ãã¡ã®1ã€ã¯ãªãã·ã§ã³ã§ãïŒã¹ããã3ïŒã åã¹ããããšãã®å®è£
ãèŠãŠã¿ãŸãããã
ããã€ã¹å®çŸ©
ãšãŠãç°¡åã§ãã èãããããã€ã¹ã決å®ããæ¹æ³ã¯2ã€ãããŸãã
1ã€ç®ã¯ããã©ãã£ãã¯ããã£ããã£ããããã€ã¹ã®ååããŠãŒã¶ãŒã«ããã°ã©ã ã«äŒããããšã§ãã æ¬¡ã®ã³ãŒããæ€èšããŠãã ããã
#include <stdio.h> #include <pcap.h> int main(int argc, char *argv[]) { char *dev = argv[1]; printf("Device: %s\n", dev); return(0); }
ãŠãŒã¶ãŒã¯ãããã°ã©ã ã®æåã®åŒæ°ãšããŠããã€ã¹ã®ååãæå®ããŠããã€ã¹ãå®çŸ©ããŸãã çŸåšã dev
è¡ã«ã¯ãPCAPãçè§£ã§ãã圢åŒã§ãªãã¹ã³ããã€ã³ã¿ãŒãã§ã€ã¹ã®ååãå«ãŸããŠããŸãïŒãã¡ããããŠãŒã¶ãŒãã€ã³ã¿ãŒãã§ã€ã¹ã®å®éã®ååãæäŸããå ŽåïŒ
2çªç®ã®æ¹æ³ãéåžžã«ç°¡åã§ãã ããã°ã©ã ãèŠãŠã¿ãŸãããã
#include <stdio.h> #include <pcap.h> int main(int argc, char *argv[]) { char *dev, errbuf[PCAP_ERRBUF_SIZE]; dev = pcap_lookupdev(errbuf); if (dev == NULL) { fprintf(stderr, "Couldn't find default device: %s\n", errbuf); return(2); } printf("Device: %s\n", dev); return(0); }
ãã®å ŽåãPCAPã¯åã«ããã€ã¹åãç¬èªã«èšå®ããŸãã ãã§ãåŸ
ã£ãŠããã£ã ããšããªãã¯èšãã ã errbuf
æååãã©ãããããã ã»ãšãã©ã®PCAPã³ãã³ãã§ã¯ãåŒæ°ã®1ã€ãšããŠæååãæž¡ãããšãã§ããŸãã ã©ããªç®çã®ããã«ïŒ ã³ãã³ãã倱æããå ŽåãPCAPã¯éä¿¡ãããæååã«ãšã©ãŒã®èª¬æãæžã蟌ã¿ãŸãã ãã®å Žåã pcap_lookupdev()
ã倱æãããšããšã©ãŒã¡ãã»ãŒãžãerrbuf
ã«é
眮ãããŸãã ãã£ãããã§ããã ããã¯ããã©ãã£ãã¯ããã£ããã£ããããã®ããã€ã¹åã®èšå®æ¹æ³ã§ãã
ã¹ãããã£ã³ã°çšã®ããã€ã¹ãã»ããã¢ãããã
ãã©ãã£ãã¯ãã£ããã£ã»ãã·ã§ã³ãäœæããã¿ã¹ã¯ãéåžžã«ç°¡åã§ãã ãã®ããã«ã pcap_open_live()
颿°ã䜿çšããŸãã ãã®é¢æ°ã®ãããã¿ã€ãïŒ
pcap_t *pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
æåã®åŒæ°ã¯ãåã®ã»ã¯ã·ã§ã³ã§å®çŸ©ããããã€ã¹ã®ååã§ãã snaplen
ã¯ãPCAPããã£ããã£ã§ããæå€§ãã€ãæ°ãå®çŸ©ããæŽæ°ã§ãã promisc
ãtrue
ã«èšå®ãããšãããã€ã¹ãå€èªäžèœã¢ãŒãã«èšå®ãããŸãïŒãšã«ãããããšãfalse
ã«èšå®ãããŠããŠããå Žåã«ãã£ãŠã¯ã€ã³ã¿ãŒãã§ãŒã¹ãå€èªäžèœã¢ãŒãã«ãªãããšããããŸãïŒã to_ms
ã¯ããªç§åäœã®èªã¿åãæéã§ãïŒå€0ã¯ã¿ã€ã ã¢ãŠããªããæå³ããŸã;å°ãªããšãäžéšã®ãã©ãããã©ãŒã ã§ã¯ããããã®ãã±ããã®åæãçµäºããåã«ååãªãã±ãããåŸ
æ©ããŠã¹ãããã£ã³ã°ã忢ã§ããããšãæå³ããŸãããããã£ãŠããŒã以å€ã®æéã䜿çšããå¿
èŠããããŸãïŒã æåŸã«ã ebuf
ã¯ãšã©ãŒã¡ãã»ãŒãžãä¿åã§ããè¡ã§ãïŒä»¥åerrbuf
è¡ã£ãããã«ïŒã ãã®é¢æ°ã¯ãã»ãã·ã§ã³ãã³ãã«ãè¿ããŸãã
å®èšŒããããã«ã次ã®ã³ãŒããæ€èšããŠãã ããã
#include <pcap.h> ... pcap_t *handle; handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf); if (handle == NULL) { fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf); return(2); }
ãã®ã³ãŒãã¯ã dev
倿°ã«é
眮ãããããã€ã¹ãéãã BUFSIZ
ïŒ BUFSIZ
ã§å®çŸ©ãããŠãã宿°ïŒã§æå®ãããæ°ã®ãã€ããèªã¿åãããã«æç€ºããŸãã ãšã©ãŒãçºçãããŸã§ãã©ãã£ãã¯ããã£ããã£ããããã«ããã€ã¹ãéå¯èŽã¢ãŒãã«åãæ¿ãããšã©ãŒã®å Žåã¯ãã®èª¬æãerrbuf
è¡ã«å
¥ããŸãã ãããŠããšã©ãŒãçºçããå Žåããã®è¡ã䜿çšããŠãåé¡ã®ãã£ãã¡ãã»ãŒãžã衚瀺ããŸãã
èªã¿ããã/èãåããªãã¹ãããã£ã³ã°ã¢ãŒãã«é¢ããæ³šæïŒ2ã€ã®æ¹æ³ã¯ã¹ã¿ã€ã«ã倧ããç°ãªããŸãã éåžžãã€ã³ã¿ãŒãã§ã€ã¹ã¯èªã¿ãããã¢ãŒãã§ãéä¿¡ããããã©ãã£ãã¯ã®ã¿ããã£ããã£ããŸãã ã¹ããã¡ãŒã«ãã£ãŠãã£ããã£ãããã®ã¯ãããããéä¿¡ããããã©ãã£ãã¯ããŸãã¯ããã«ã«ãŒãã£ã³ã°ããããã©ãã£ãã¯ã®ã¿ã§ãã éã«ãéå¯èŽã¢ãŒãã§ã¯ãã±ãŒãã«ãééãããã¹ãŠã®ãã©ãã£ãã¯ããã£ããã£ãããŸãã éã¹ã€ããã³ã°ç°å¢ã§ã¯ãããã¯ãã¹ãŠã®ãããã¯ãŒã¯ãã©ãã£ãã¯ã«ãªããŸãã ãã®æ¹æ³ã®æãããªå©ç¹ã¯ããã©ãã£ãã¯ãã£ããã£ã®ç®çã«å¿ããŠãããå€ãã®ãã±ããããã£ããã£ã§ããããšã§ãã ãã ããæ¬ ç¹ããããŸãã å€èªäžèœã¢ãŒãã¯ç°¡åã«æ€åºãããäžæ¹ã®ããŒãã¯ä»æ¹ãå€èªäžèœã¢ãŒãã§ãããã©ãããæç¢ºã«å€æã§ããŸãã ãŸããéã¹ã€ããç°å¢ïŒãããAPRã䜿çšããã«ãŒã¿ãŒãªã©ïŒã§ã®ã¿æ©èœããŸãã ãã1ã€ã®æ¬ ç¹ã¯ããã©ãã£ãã¯ãå€ããããã¯ãŒã¯ã§ã¯ãã·ã¹ãã ãªãœãŒã¹ããã¹ãŠã®ãã±ããããã£ããã£ããŠåæããã®ã«ååã§ãªãå¯èœæ§ãããããšã§ãã
ãã¹ãŠã®ããã€ã¹ããèªã¿åã£ããã±ããã«åããªã³ã¯å±€ããããŒãæäŸããããã§ã¯ãããŸããã ã€ãŒãµãããããã€ã¹ãããã³äžéšã®éã€ãŒãµãããããã€ã¹ã¯ãã€ãŒãµãããããããŒãæäŸã§ããŸãããBSDããã³OS Xã®ç絡ããã€ã¹ãPPPã€ã³ã¿ãŒãã§ã€ã¹ãã¢ãã¿ãªã³ã°ã¢ãŒãã®Wi-Fiã€ã³ã¿ãŒãã§ã€ã¹ãªã©ã®ä»ã®ã¿ã€ãã®ããã€ã¹ã¯æäŸããŸããã
ããã€ã¹ãæäŸãããªã³ã¯å±€ããããŒã®ã¿ã€ããå€å¥ããããã䜿çšããŠãã±ããã®ã³ã³ãã³ããåæããå¿
èŠããããŸãã pcap_datalink()
ã¯ããªã³ã¯å±€ããããŒã®ã¿ã€ããè¿ããŸãã ïŒ ãªã³ã¯å±€ããããŒå€ã®ãªã¹ããåç
§ããŠãã ãããæ»ãå€ã¯ããã®ãªã¹ãã®DHT_å€ã§ãïŒ
ããã°ã©ã ãããã€ã¹ã«ãã£ãŠæäŸããããªã³ã¯ã¬ãã«ããããŒããµããŒãããŠããªãå Žåãåæ§ã®ã³ãŒãã䜿çšããŠåäœã忢ããå¿
èŠããããŸãã
if (pcap_datalink(handle) != DLT_EN10MB) { fprintf(stderr, "Device %s doesn't provide Ethernet headers -not supported\n", dev); return(2); }
ããã€ã¹ãã€ãŒãµãããããããŒããµããŒãããŠããªãå Žåã«æ©èœããŸãã ããã¯ãã€ãŒãµãããããããŒã䜿çšãã以äžã®ã³ãŒãã§æ©èœããå ŽåããããŸãã
ãã©ãã£ãã¯ãã£ã«ã¿ãªã³ã°
å€ãã®å Žåãç¹å®ã®çš®é¡ã®ãã©ãã£ãã¯ã®ã¿ããã£ããã£ããããšã«é¢å¿ããããŸãã ããšãã°ãå¿
èŠãªã®ã¯ãããŒã23ïŒtelnetïŒããã®ãã©ãã£ãã¯ããã£ããã£ããŠãã¹ã¯ãŒããæ€çŽ¢ããããšã ãã§ãã ãŸãã¯ãããŒã21ïŒFTPïŒãä»ããŠéä¿¡ããããã¡ã€ã«ãã€ã³ã¿ãŒã»ããããããšãã§ããŸãã DNSãã©ãã£ãã¯ïŒUDPããŒã53ïŒã®ã¿ããã£ããã£ãããå ŽåããããŸãã ãã ãããã¹ãŠã®ã€ã³ã¿ãŒããããã©ãã£ãã¯ãç²ç®çã«ãã£ããã£ãããå Žåã¯ãŸãã§ãã 颿°pcap_compile()
ããã³pcap_setfilter()
èŠãŠã¿ãŸãããã
ããã»ã¹ã¯éåžžã«ç°¡åã§ãã pcap_open_live()
ãåŒã³åºããŠãã¹ãããã£ã³ã°ã»ãã·ã§ã³ãå®è¡ããåŸããã£ã«ã¿ãŒãé©çšã§ããŸãã ããªãã¯ããªãéåžžã®if
/ else if
åŒã䜿çšããªãã®ã§ããïŒ 2ã€ã®çç±ïŒ1ã€ç®ã¯ãBAPãçŽæ¥ãã£ã«ã¿ãªã³ã°ãããããPCAPãã£ã«ã¿ãŒã¯ããå¹ççã§ãã ãããã£ãŠãBPFãã©ã€ããŒããããçŽæ¥è¡ããããå¿
èŠãªãªãœãŒã¹ã¯ã¯ããã«å°ãªããªããŸãã 2çªç®ã¯ãPCAPãã£ã«ã¿ãŒãåçŽã§ãããšããããšã§ãã
ãã£ã«ã¿ãŒãé©çšããåã«ãã³ã³ãã€ã«ããå¿
èŠããããŸãã ãã£ã«ã¿ãŒæ¡ä»¶ã¯ãéåžžã®æååïŒãŸãã¯char
é
åïŒã«å«ãŸããŠããŸãã æ§æã¯tcpdump.orgã®ããŒã ããŒãžã«ããªã詳ããææžåãããŠããŸãã ç§ã¯ããªãèªèº«ã®èæ
®ã®ããã«ãããããªãã«ä»»ããŸãã ãã ããåçŽãªãã¹ãåŒã䜿çšããŸãããããããäžèšã®äŸãããããã®æ¡ä»¶ã®æ§æèŠåãç¬ç«ããŠå°ãåºãã®ã«ååè³¢ãã§ãããã
ãã£ã«ã¿ãŒãã³ã³ãã€ã«ããã«ã¯ã pcap_compile()
颿°ãåŒã³åºããŸãã ãããã¿ã€ãã§ã¯ããã®é¢æ°ã次ã®ããã«å®çŸ©ããŠããŸãã
int pcap_compile(pcap_t *p, struct bpf_program *fp, char *str, int optimize, bpf_u_int32 netmask)
æåã®åŒæ°ã¯ã»ãã·ã§ã³èšè¿°åã§ãïŒåã®äŸã§ã¯pcap_t* handle
ïŒã 次ã¯ãã³ã³ãã€ã«æžã¿ããŒãžã§ã³ã®ãã£ã«ã¿ãŒãä¿åããå Žæãžã®ãã€ã³ã¿ãŒã§ãã æ¬¡ã¯ãéåžžã®æåå圢åŒã®åŒèªäœã§ãã æ¬¡ã«ããã£ã«ã¿ãŒåŒãæé©åãããã©ãããæ±ºå®ããæŽæ°ãå
¥ããŸãïŒ0-ãããã1-ã¯ãïŒã æåŸã«ããã£ã«ã¿ãŒãé©çšãããããã¯ãŒã¯ã®ãããã¯ãŒã¯ãã¹ã¯ãå®çŸ©ããå¿
èŠããããŸãã 颿°ã¯ãšã©ãŒæã«-1ãè¿ããŸãã ä»ã®ãã¹ãŠã®å€ã¯æåãæå³ããŸãã
ãã£ã«ã¿ãŒãã³ã³ãã€ã«ããåŸããããé©çšããæéã§ãã pcap_setfilter()
åŒã³åºããŸãã PCAPã®èª¬æåœ¢åŒã«åŸã£ãŠããã®é¢æ°ã®ãããã¿ã€ããæ€èšããå¿
èŠããããŸãã
int pcap_setfilter(pcap_t *p, struct bpf_program *fp)
ããã¯éåžžã«åçŽæå¿«ã§ãã æåã®åŒæ°ã¯ã»ãã·ã§ã³èšè¿°åã§ã2çªç®ã¯ãã£ã«ã¿ãŒã®ã³ã³ãã€ã«æžã¿ããŒãžã§ã³ãžã®ãã€ã³ã¿ãŒã§ãïŒããã¯åã®pcap_compile()
颿°ãšåã倿°ã§ãªããã°ãªããŸããïŒã
ããããããã®äŸã¯çè§£ãæ·±ããã®ã«åœ¹ç«ã€ã§ãããã
PCAPãã£ã«ã¿ãŒã®èšå®ãã³ã³ãã€ã«ãããã³é©çšã®äŸ #include <pcap.h> ... pcap_t *handle; /* */ char dev[] = "rl0"; /* */ char errbuf[PCAP_ERRBUF_SIZE]; /* */ struct bpf_program fp; /* */ char filter_exp[] = "port 23"; /* */ bpf_u_int32 mask; /* */ bpf_u_int32 net; /* IP */ if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) { fprintf(stderr, "Can't get netmask for device %s\n", dev); net = 0; mask = 0; } handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf); if (handle == NULL) { fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf); return(2); } if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) { fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle)); return(2); } if (pcap_setfilter(handle, &fp) == -1) { fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(handle)); return(2); }
ãã®ããã°ã©ã ã¯ãæ··åã¢ãŒãã§rl0
ããã€ã¹ã®ããŒã23ãééãããã©ãã£ãã¯ãæ¢ç¥ããããã«æ§æãããŠããŸãã
åã®äŸã«ã¯ãŸã 説æããŠããªã颿°ãå«ãŸããŠããããšã«æ°ã¥ããããããŸããã pcap_lookupnet()
ã¯ãããã€ã¹åãåãåããšãIPv4ãããã¯ãŒã¯çªå·ãšå¯Ÿå¿ãããããã¯ãŒã¯ãã¹ã¯ãè¿ã颿°ã§ãïŒãããã¯ãŒã¯çªå·ã¯ããããã¯ãŒã¯ãã¹ã¯ãšã®IPv4 ANDã¢ãã¬ã¹ã§ãããããã¢ãã¬ã¹ã®ãããã¯ãŒã¯éšåã®ã¿ãå«ãŸããŸãïŒã ãã£ã«ã¿ãŒãé©çšããã«ã¯ããããã¹ã¯ãç¥ãå¿
èŠããããããããã¯äžå¯æ¬ ã§ãã
ç§ã®çµéšã§ã¯ããã®ãã£ã«ã¿ãŒã¯äžéšã®ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã§ã¯æ©èœããŸããã ç§ã®ãã¹ãç°å¢ã§ã¯ãã«ãŒãã«ãåããOpenBSD 2.9ã¯ããã©ã«ãã§ãã®ã¿ã€ãã®ãã£ã«ã¿ãŒããµããŒãããŠããŸãããããã©ã«ãã®ã«ãŒãã«ãåããFreeBSD 4.3ã¯ãµããŒãããŠããŸããã ããªãã®çµéšã¯ç°ãªãå ŽåããããŸãã
æ¬ç©ã®ã¹ãããã£ã³ã°
çŸåšã®æ®µéã§ã¯ãããã€ã¹ãèå¥ãããã©ãã£ãã¯ããã£ããã£ããããã«æºåãããã£ã«ã¿ãŒãé©çšããæ¹æ³ãåŠã³ãŸããã ä»ãããããã€ãã®ããã±ãŒãžãå
¥æãããšãã§ãã ãã±ããããã£ããã£ããã«ã¯ãäž»ã«2ã€ã®æ¹æ³ããããŸãã 1ã€ã®ãã±ããããã£ããã£ããããnåã®ãã±ããããã£ããã£ããããŸã§å®è¡ãããã«ãŒãã«å
¥ãããšãã§ããŸãã ãŸãã1ã€ã®ããã±ãŒãžããã£ããã£ããæ¹æ³ã瀺ããæ¬¡ã«ã«ãŒãã®äœ¿ç𿹿³ãæ€èšããŸãã ãããã¿ã€ãpcap_next()
èŠãŠpcap_next()
ïŒ
u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h)
æåã®åŒæ°ã¯ã»ãã·ã§ã³ãã³ãã«ã§ãã 2çªç®ã¯ããã±ããã«é¢ããäžè¬æ
å ±ãå
·äœçã«ã¯ããã±ããããã£ããã£ãããæéããã±ããã®é·ããããã³ç¹å®ã®éšåã®é·ãïŒæçåãããŠããå Žåãªã©ïŒãå«ãæ§é ãžã®ãã€ã³ã¿ãŒã§ãã pcap_next()
ã¯ãæ§é äœã«èšè¿°ãããŠããããã±ãŒãžãžã®u_char
ãã€ã³ã¿ãŒãè¿ããŸãã ããã±ãŒãžã®èªã¿åãã«ã€ããŠã¯åŸã§èª¬æããŸãã
ããã¯ã pcap_next()
ã䜿çšããŠãã±ããããã£ããã£ãããã¢ã§ãã
ã·ã³ã°ã«ãã±ãããã£ãã㣠#include <pcap.h> #include <stdio.h> int main(int argc, char *argv[]) { pcap_t *handle; /* */ char *dev; /* */ char errbuf[PCAP_ERRBUF_SIZE]; /* */ struct bpf_program fp; /* */ char filter_exp[] = "port 23"; /* */ bpf_u_int32 mask; /* */ bpf_u_int32 net; /* IP */ struct pcap_pkthdr header; /* PCAP */ const u_char *packet; /* */ /* */ dev = pcap_lookupdev(errbuf); if (dev == NULL) { fprintf(stderr, "Couldn't find default device: %s\n", errbuf); return(2); } /* */ if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) { fprintf(stderr, "Couldn't get netmask for device %s: %s\n", dev, errbuf); net = 0; mask = 0; } /* */ handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf); if (handle == NULL) { fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf); return(2); } /* */ if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) { fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle)); return(2); } if (pcap_setfilter(handle, &fp) == -1) { fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(handle)); return(2); } /* */ packet = pcap_next(handle, &header); /* */ printf("Jacked a packet with length of [%d]\n", header.len); /* */ pcap_close(handle); return(0); }
ã¢ããªã±ãŒã·ã§ã³ã¯ã pcap_loockupdev()
ãä»ããŠåä¿¡ããããã€ã¹ã®ãã©ãã£ãã¯ããã£ããã£ããç¡å·®å¥ã¢ãŒãã«ããŸãã ãã±ãããããŒã23ïŒtelnetïŒäžã«ããããšãæ€åºãããŠãŒã¶ãŒã«ãã±ããã®ãµã€ãºïŒãã€ãåäœïŒãäŒããŸãã ç¹°ãè¿ããŸãããããã°ã©ã ã«ã¯pcap_close()
åŒã³åºããå«ãŸããŠããŸãããããã«ã€ããŠã¯åŸã§èª¬æããŸãïŒãã ããããªãçè§£ãããããã®ã§ãïŒã
ãã©ãã£ãã¯ããã£ããã£ãã2çªç®ã®æ¹æ³ã¯ã pcap_loop()
ãŸãã¯pcap_dispatch()
ã䜿çšããããšpcap_loop()
ïŒãããã¯pcap_loop()
䜿çšããŸãïŒã ããã2ã€ã®é¢æ°ã®äœ¿çšãçè§£ããã«ã¯ãã³ãŒã«ããã¯é¢æ°ã®æŠå¿µãçè§£ããå¿
èŠããããŸãã
ã³ãŒã«ããã¯é¢æ°ã¯æ°ãããã®ã§ã¯ãªããå€ãã®APIã§äžè¬çãªãã®ã§ãã ã³ãŒã«ããã¯é¢æ°ã®èåŸã«ããæŠå¿µã¯éåžžã«åçŽã§ãã ç¹å®ã®çš®é¡ã®ã€ãã³ããåŸ
æ©ããŠããããã°ã©ã ããããšããŸãã äŸãšããŠãããã°ã©ã ãããŒã®æŒäžãåŸ
æ©ãããšããŸãã ãŠãŒã¶ãŒãããŒãæŒããã³ã«ãç§ã®ããã°ã©ã ã¯ãã®ããŒã¹ãããŒã¯ãåŠçãã颿°ãåŒã³åºããŸãã ããã¯ã³ãŒã«ããã¯é¢æ°ã§ãã ãããã®é¢æ°ã¯PCAPã§äœ¿çšãããŸãããããŒãæŒããããšãã«åŒã³åºãã®ã§ã¯ãªããPCAPããã±ããããã£ããã£ãããšãã«åŒã³åºãããŸãã ã³ãŒã«ããã¯é¢æ°ã¯ããã®ç¹ã§éåžžã«äŒŒãŠããpcap_loopïŒïŒããã³pcap_dispatchïŒïŒã§ã®ã¿äœ¿çšã§ããŸãã ãããã¯ããããããã±ããããã£ã«ã¿ãŒãééãããã³ã«ã³ãŒã«ããã¯é¢æ°ãåŒã³åºããŸãïŒãã¡ãããã£ã«ã¿ãŒããªãå Žåãããã§ãªãå Žåããã£ããã£ããããã¹ãŠã®ãã±ãããã³ãŒã«ããã¯é¢æ°ãåŒã³åºããŸãïŒã
ãããã¿ã€ãpcap_loop()
以äžã«ç€ºããŸãã
int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
æåã®åŒæ°ã¯ã»ãã·ã§ã³ãã³ãã«ã§ãã æ¬¡ã«ããã£ããã£ãããå¿
èŠããããã±ããpcap_loop()
æ°ãpcap_loop()
äŒããæŽæ°ãæ¥ãŸãïŒè² ã®å€ã¯ããšã©ãŒãçºçããåã«ã«ãŒããå®è¡ããå¿
èŠãããããšã瀺ããŸãïŒã 3çªç®ã®åŒæ°ã¯ãã³ãŒã«ããã¯é¢æ°ã®ååïŒèå¥åã®ã¿ããã©ã¡ãŒã¿ãŒãªãïŒã§ãã æåŸã®åŒæ°ã¯äžéšã®ã¢ããªã±ãŒã·ã§ã³ã§åœ¹ç«ã¡ãŸãããã»ãšãã©ã®å Žåãåã«NULLã«èšå®ãããŸãã pcap_loop()
ãæž¡ãåŒæ°ã«å ããŠãã³ãŒã«ããã¯é¢æ°ã«æž¡ãåŒæ°ããããšããŸãã æåŸã®åŒæ°ã¯ããããè¡ãå Žæã«ãããŸããã æããã«ãæ£ããçµæãåŸãããã«ãããããu_char *
åã«ãã£ã¹ãããå¿
èŠããããŸãã åŸã§èŠãããã«ãPCAPã¯u_char *
圢åŒã§æ
å ±ãéä¿¡ããããã€ãã®è峿·±ãæ¹æ³ã䜿çšããŸãã PCAPããããè¡ãæ¹æ³ã®äŸã瀺ããåŸããã®æç¹ã§ãããè¡ãæ¹æ³ãæããã«ãªããŸãã ããã§ãªãå Žåã¯ãCãã«ãããã¹ããåç
§ããŠãã ããããã€ã³ã¿ãŒã®èª¬æã¯ãã®ããã¥ã¡ã³ãã®ç¯å²å€ã§ãã pcap_dispatch()
äœ¿çšæ³pcap_dispatch()
ã»ãŒåãã§ãã pcap_dispatch()
ãšpcap_loop()
ã®å¯äžã®éãã¯ã pcap_dispatch()
ã¯ã·ã¹ãã ããåä¿¡ããæåã®äžé£ã®ãã±ããã®ã¿ãåŠçããpcap_loopïŒïŒã¯ã«ãŠã³ã¿ãŒããªããªããŸã§ãã±ãããŸãã¯ããããåŠçãç¶ããããšã§ãã éãã®è©³çްã«ã€ããŠã¯ãå
¬åŒã®PCAPããã¥ã¡ã³ããåç
§ããŠãã ããã
pcap_loop()
ã䜿çšããŠäŸãäžããåã«ãã³ãŒã«ããã¯é¢æ°ã®åœ¢åŒã確èªããå¿
èŠããããŸãã ã³ãŒã«ããã¯é¢æ°ã®ãããã¿ã€ããåå¥ã«æ±ºå®ããããšã¯ã§ããŸãããããããªããšã pcap_loop()
ã¯ãã®äœ¿ç𿹿³ãç¥ããŸããã ãããã£ãŠããã®åœ¢åŒãã³ãŒã«ããã¯é¢æ°ã®ãããã¿ã€ããšããŠäœ¿çšããå¿
èŠããããŸãã
void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet);
ãã£ãšè©³ããåæããŠã¿ãŸãããã ãŸãã颿°ã«ã¯void
åãå¿
èŠã§ãã pcap_loop()
ã¯æ»ãå€ãã©ãããããç¥ããªãã®ã§ãããã¯è«ççã§ãã æåã®åŒæ°ã¯æåŸã®åŒæ°pcap_loop()
察å¿ããŸãã pcap_loop()
æåŸã®åŒæ°ã§æž¡ãããå€ã«é¢ä¿ãªããã³ãŒã«ããã¯é¢æ°ã®æåã®åŒæ°ã§æž¡ãããŸãã 2çªç®ã®åŒæ°ã¯PCAPããããŒã§ããããã«ã¯ããã±ããããã£ããã£ãããææããã±ããã®å€§ãããªã©ã«é¢ããæ
å ±ãå«ãŸããŸãã pcap_pkthdr
æ§é pcap_pkthdr
ãpcap.hãã¡ã€ã«ã§æ¬¡ã®ããã«å®çŸ©ãããŠããŸãã
struct pcap_pkthdr { struct timeval ts; bpf_u_int32 caplen; bpf_u_int32 len; };
ãããã®å€ã¯åççã«æç¢ºã§ãªããã°ãªããŸããã æåŸã®è°è«ã¯ãã¹ãŠã®äžã§æãè峿·±ããã®ã§ãããåå¿è
ã®ããã°ã©ããŒãçè§£ããã®ãæãé£ãããã®ã§ãã ããã¯u_char
ãžã®å¥ã®ãã€ã³ã¿ã§ããã pcap_loop()
ã«ãã£ãŠãã£ããã£ããããã±ããã«å«ãŸããããŒã¿ã»ã¯ã·ã§ã³ã®æåã®ãã€ããæããŸãã
ãããããã®å€æ°ïŒãã±ãããšåŒã°ããïŒããããã¿ã€ãã§ã©ã®ããã«äœ¿çšã§ããŸããïŒ ãã±ããã«ã¯å€ãã®å±æ§ãå«ãŸããŠããããããæ³åã®ãšãããããã¯æååã§ã¯ãªããæ§é ã®ã»ããã§ãïŒããšãã°ãTCP / IPãã±ããã«ã¯ã€ãŒãµãããããããŒãIPããããŒãTCPããããŒãæåŸã«ããŒã¿ãå«ãŸããŸãïŒã ãã®u_char
ãã€ã³ã¿ãŒã¯ããããã®æ§é ã®ã·ãªã¢ã«åãããããŒãžã§ã³ãæããŸãã ãããã®ããããã®äœ¿çšãéå§ããã«ã¯ãããã€ãã®è峿·±ãå倿ãè¡ãå¿
èŠããããŸãã
ãŸããããŒã¿ãæ§é ã«åã蟌ãåã«ãæ§é èªäœã決å®ããå¿
èŠããããŸãã TCP/IP Ethernet.
Ethernet, IP, TCP #define ETHER_ADDR_LEN 6 struct sniff_ethernet { u_char ether_dhost[ETHER_ADDR_LEN]; u_char ether_shost[ETHER_ADDR_LEN]; u_short ether_type; }; struct sniff_ip { u_char ip_vhl; u_char ip_tos; u_short ip_len; u_short ip_id; u_short ip_off; #define IP_RF 0x8000 #define IP_DF 0x4000 #define IP_MF 0x2000 #define IP_OFFMASK 0x1fff u_char ip_ttl; u_char ip_p; u_short ip_sum; struct in_addr ip_src,ip_dst; }; #define IP_HL(ip) (((ip)->ip_vhl) & 0x0f) #define IP_V(ip) (((ip)->ip_vhl) >> 4) typedef u_int tcp_seq; struct sniff_tcp { u_short th_sport; u_short th_dport; tcp_seq th_seq; tcp_seq th_ack; u_char th_offx2; #define TH_OFF(th) (((th)->th_offx2 & 0xf0) >> 4) u_char 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 #define TH_ECE 0x40 #define TH_CWR 0x80 #define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR) u_short th_win; u_short th_sum; u_short th_urp; };
PCAP u_char
? , . ? ( : ).
, , TCP/IP Ethernet. . â , . , . .
#define SIZE_ETHERNET 14 const struct sniff_ethernet *ethernet; const struct sniff_ip *ip; const struct sniff_tcp *tcp; const char *payload; u_int size_ip; u_int size_tcp;
:
ethernet = (struct sniff_ethernet*)(packet); ip = (struct sniff_ip*)(packet + SIZE_ETHERNET); size_ip = IP_HL(ip)*4; if (size_ip < 20) { printf(" * Invalid IP header length: %u bytes\n", size_ip); return; } tcp = (struct sniff_tcp*)(packet + SIZE_ETHERNET + size_ip); size_tcp = TH_OFF(tcp)*4; if (size_tcp < 20) { printf(" * Invalid TCP header length: %u bytes\n", size_tcp); return; } payload = (u_char *)(packet + SIZE_ETHERNET + size_ip + size_tcp);
ã©ã®ããã«æ©èœããŸããïŒ . u_char
â .
, ,
. , , â sniff_ethernet
,
, . â
Ethernet , 14, SIZE_ETHERNET
.
, , â . IP, Ethernet, . 4- IP. 4- , 4, . 20 .
TCP , 4- , " " TCP, 20 .
, :
VARIABLE | LOCATION(in bytes) |
---|
sniff_ethernet | X |
sniff_ip | X + SIZE_ETHERNET |
sniff_tcp | X + SIZE_ETHERNET + {IP header length} |
payload | X + SIZE_ETHERNET + {IP header length} + {TCP header length} |
sniff_ethernet
, ,
. sniff_ip
, sniff_ethernet
,
, sniff_ethernet
(14 SIZE_ETHERNET
). sniff_tcp
, â X
Ethernet, IP . (14 , 4 IP). , ( ) .
, , , . . sniffer.c .
å®äº
PCAP. PCAP , , , . .
2002. . , :
:
, , .
This document is Copyright 2002 Tim Carstens. All rights reserved. Redistribution and use, with or without modification, are permitted provided that the following conditions are met:
Redistribution must retain the above copyright notice and this list of conditions.
The name of Tim Carstens may not be used to endorse or promote products derived from this document without specific prior written permission.
/ Insert 'wh00t' for the BSD license here /