######################################################### ¸®´ª½º¿¡¼­ pcap library¸¦ »ç¿ëÇÏ¿© ÆÐŶÀ» Àâ¾Æº¸±â v0.3 ±Û¾´ÀÌ : ³ë±¤¹Î e-mail : djstop@orgio.net homepage : http://myhome.shinbiro.com/~nkm24 tcpdump, libpcap ¼Ò½º ±¸ÇÒ ¼ö ÀÖ´Â °÷ : ftp://ftp.ee.lbl.gov ######################################################### Àú´Â ½Ã½ºÅÛ, ³×Æ®¿÷ ÇÁ·Î±×·¥¿¡ Èï¹Ì°¡ ¸¹¾Ò°í À©µµ¿ìÁî´Â À̰͵éÀ» Çϱâ À§ÇÑ ¼Ò½º¸¦ ÃæºÐÈ÷ Á¦°øÇÏÁö ¸øÇÏ´Â OSÀÔ´Ï´Ù. ÇÏÁö¸¸ ¸®´ª½º´Â ½ÇÇèÁ¤½Å°ú µµÀüÁ¤½Å¸¸ ÀÖ´Ù¸é ÀÌ·± ÇÁ·Î±×·¥µµ ÃæºÐÈ÷ ÇÒ ¼ö ÀÖÁÒ. Àú¿Í °°ÀÌ ½Ã½ºÅÛ, ³×Æ®¿÷ ÇÁ·Î±×·¥Àº ÇÏ°í ½ÍÀºµ¥ ´çÀå ¶Ù¾îµé±â°¡ ¸·¸·ÇϽŠºÐµéÀ» À§ÇØ ÀÌ·¸°Ô ªÀº Áö½ÄÀ̳ª¸¶ ¸ÕÀú ÇØ º¸¾Ò´ø °æÇèÀ» Åä´ë·Î ÇÑ ¹ø ±ÛÀ» ¿Ã·Á º¾´Ï´Ù. ¿©±â¿¡¼­ ¼³¸íÇÏ´Â ³»¿ëµéÀº ½ÇÁ¦ socketÀ» ÀÌ¿ëÇÑ ³×Æ®¿÷ ÇÁ·Î±×·¥°ú´Â Á¶±Ý ´Ù¸¥ °ÍÀÔ´Ï´Ù. ¸®´ª½º¿¡´Â ³×Æ®¿÷ ÇÁ·Î±×·¥À» Çϱâ À§ÇØ Âü°íÇÒ ¸¸ÇÑ ¸¹Àº ¼Ò½ºµéÀÌ ¸¹ÀÌ ÀÖ½À´Ï´Ù. Á¦°¡ ÇÁ·ÎÁ§Æ®¸¦ ÇÒ ¶§ Âü°í·Î Çß´ø °ÍÀº tcpdumpÀÔ´Ï´Ù. ÀÌ ³ðÀº ³×Æ®¿÷»óÀÇ °¢Á¾ ÆÐŶÀ» Àâ¾Æ¼­ ÅؽºÆ® Á¤º¸·Î ¿ä¾àÇؼ­ º¸¿©ÁÖ´Â ÇÁ·Î±×·¥ÀÌÁö¿ä.. ±×·³ ÀÌ ³ðÀ» º¸¸é ³ªµÎ ³×Æ®¿÷»óÀÇ ÆÐŶÀ» Àâ¾Æ¼­ º¼ ¼ö ÀÖ°Ú±¸³ªÇÏ°í »ý°¢À» ÇßÁÒ. ±×·³ ÆÐŶÀ» Àâ´Â °ÍÀÌ ¾ó¸¶³ª ½¬¿îÁö ÇÑ ¹ø º¸°Ú½À´Ï´Ù. int main(int argc, char *argv[]) { . . . . . opterr = 0; if (device == NULL ) { if ( (device = pcap_lookupdev(ebuf) ) == NULL) { perror(ebuf); exit(-1); } } pd = pcap_open_live(device, snaplen, PROMISCUOUS, 1000, ebuf); if(pd == NULL) { perror(ebuf); exit(-1); } if(pcap_lookupnet(device, &localnet, &netmask, ebuf) < 0) { perror(ebuf); exit(-1); } setuid(getuid()); if(pcap_compile(pd, &fcode, filter_rule, 0, netmask) < 0) { perror(ebuf); exit(-1); } if(pcap_setfilter(pd, &fcode) < 0) { perror(ebuf); exit(-1); } fflush(stderr); printer = lookup_printer(pcap_datalink(pd)); pcap_userdata = 0; if(pcap_loop(pd, packetcnt, printer, pcap_userdata) < 0) { perror("pcap_loop error"); exit(-1); } pcap_close(pd); exit(0); } ³×Æ®¿÷ »óÀÇ ÆÐŶÀ» Àâ±â À§ÇØ pcap libraryÀÇ À§¿Í °°Àº ÇÔ¼öµéÀ» ³ª¿­Çϱ⸸ ÇÏ¸é µË´Ï´Ù. Â÷·Ê´ë·Î º¼±î¿ä? device = pcap_lookupdev(ebuf); ¿ä³ðÀº ¸®´ª½º ¸Ó½ÅÀÇ ³×Æ®¿÷ µð¹ÙÀ̽º¸¦ °¡Á®¿À´Â ÇÔ¼öÀÔ´Ï´Ù. ÆÐŶÀ» ÀâÀ¸·Á¸é ³×Æ®¿÷ µð¹ÙÀ̽º¸¦ ÁöÁ¤ÇØ¾ß °ÚÁÒ? À̳ðÀº °¡´ÉÇÑ ´ÙºñÀ̽ºÁß °¡Àå ¹øÈ£°¡ ³·Àº µð¹ÙÀ̽º¸¦ °¡Á®¿À°Ô µË´Ï´Ù. ¸®´ª½º¶ó¸é eth0ÀÌ°ÚÁÒ... i ¿É¼ÇÀ¸·Î µð¹ÙÀ̽º¸¦ ¼öµ¿À¸·Î ÁöÁ¤ÇÒ ¼ö ÀÖ½À´Ï´Ù. pd = pcap_open_live(device, snaplen, PROMISCUOUS, 1000, ebuf) À§ ÇÔ¼ö´Â ½ÇÁ¦ ±â±â¸¦ ¿­¾îÁÖ´Â ±â´ÉÀ» ÇÏ´Â °ÍÀ¸·Î snaplen´Â ÆÐŶ´ç ÀúÀåÇÒ ¹ÙÀ̽º ¼ö, ½ÇÁ¦ datalink°èÃþºÎÅÍ ÆÐŶÀÇ Å©±â¸¦ °è»êÇÏ¿© ¿øÇÏ´Â ºÎºÐ¸¸À» ¾ò¾î¿À¸é µÇ´Â °ÍÀÔ´Ï´Ù. Çì´õÁ¤º¸¸¸À» º¸°í½ÍÀºµ¥ ¾µµ¥¾øÀÌ µ¥ÀÌŸ±îÁö ¹ÞÀ» ÇÊ¿ä´Â ¾ø°ÚÁÒ. µ¥ÀÌÅͱîÁö º¸°í½ÍÀ¸¸é À̸¦ ´Ã¸®¸é µË´Ï´Ù. PROMISCUOUS´Â 1ÀÌ¸ç ³×Æ®¿÷ µð¹ÙÀ̽º¿¡ ¿À´Â ¸ðµç ÆÐŶÀ» ¹Þ°Ú´Ù´Â ÀǹÌÀÔ´Ï´Ù. ÀÌ ¸ðµå¸¦ ÀÚ¼¼ÇÏ°Ô ¼³¸íÇϸé lanÀº ¸ðµç ÆÐŶÀÌ broadcastingµÇ¸ç ÀÏ´Ü ¸ðµç ³×Æ®¿÷ µð¹ÙÀ̽º´Â µ¿ÀÏ ³×Æ®¿÷³»ÀÇ ´Ù¸¥ È£½ºÆ®ÀÇ ÆÐŶµµ ÀÏ´Ü Á¢ÇÏ°Ô µË´Ï´Ù. ±×·¯³ª, ³×Æ®¿÷ µð¹ÙÀ̽º´Â ±âº»ÀûÀ¸·Î ÀÚ½ÅÀÇ ÆÐŶ¸¸À» ¹Þ°Ô²û µÇ¾îÀÖ½À´Ï´Ù. ±×·¯¹Ç·Î ´Ù¸¥ È£½ºÆ®ÀÇ ÆÐŶÀº ¹ö¸®°Ô µÇ´Â °ÍÀÔ´Ï´Ù. ±×·¯³ª promiscuous¸ðµå·Î µð¹ÙÀ̽º ¸ðµå¸¦ ¹Ù²Ù°Ô µÇ¸é ¸ðµç ÆÐŶÀ» ¹Þ¾ÆµéÀÌ°Ô µÇ´Â °ÍÀÔ´Ï´Ù. ½º´ÏÆÛ¸µ ÇÁ·Î±×·¥Àº ¸ðµÎ ÀÌ ¸ðµå¸¦ »ç¿ëÇÏ°Ô µË´Ï´Ù. ¼¼ ¹ø° ÀÎÀÚ´Â ÆÐŶÀÌ ¹öÆÛ·Î Àü´ÞµÉ ¶§ ¹Ù·Î Àü´ÞµÇ´Â °ÍÀÌ ¾Æ´Ï¶ó À§¿¡¼­ ¸í½ÃÇÑ ½Ã°£À» ³Ñ°åÀ» ¶§³ª ¹öÆÛ°¡ ´Ù ä¿öÁ³À» ¶§ ÀÀ¿ëÇÁ·Î±×·¥À¸·Î Àü´ÞµÇ´Â °ÍÀÔ´Ï´Ù. pcap_lookupnet(device, &localnet, &netmask, ebuf) ¿­·ÁÁø ÆÐŶ ĸÃÄ µð¹ÙÀ̽º¿¡ ³×Æ®¿÷ ÁÖ¼Ò¿Í ¼­ºê³Ý ¸¶½ºÅ©¸¦ ³Ñ°ÜÁÝ´Ï´Ù. pcap_compile(pd, &fcode, filter_rule, 0, netmask) Á¤ÇØÁø ÇÊÅÍ·ê¿¡ ÀÇÇØ ÇÊÅÍ ÇÁ·Î±×·¥À» ÄÄÆÄÀÏÇÏ°Ô µÇ´Âµ¥ ¿ì¸®°¡ ¿øÇÏ´Â ÆÐŶÀº ÇÊÅÍ·êÀ» ÁÖ¾î¾ß¸¸ ¿øÇÏ´Â ÆÐŶ¸¸À» ¾òÀ» ¼ö ÀÖ½À´Ï´Ù. ½ÇÁ¦ tcpdump¿¡¼­ »ç¿ëÇÏ´Â ÇÊÅÍ·êÀÌ ¿©±â¿¡¼­ ¾²ÀÔ´Ï´Ù. ¿¹¸¦ µé¸é "tcp port 80" ... ÀÚ¼¼ÇÑ ÇÊÅÍ·ê¿¡ ´ëÇÑ ¼³¸íÀº tcpdumpÀÇ ¸Þ´º¾óÀ» º¸¸é ¾Ë ¼ö ÀÖ½À´Ï´Ù. pcap_setfilter(pd, &fcode) À§´Â ¾Õ¼­ ÄÄÆÄÀÏÇÑ ÇÊÅÍ ÇÁ·Î±×·¥À» ÆÐŶ ĸÃÄ µð¹ÙÀ̽º·Î ÀоîµéÀÌ°Ô µË´Ï´Ù. ÀÌ·¸°Ô ÇÏ¿© ¿øÇÏ´Â ÆÐŶÀ» ¾òÀ» Áغñ¸¦ ÇÏ°Ô µË´Ï´Ù. printer = lookup_printer(pcap_datalink(pd)); À§´Â ÆÐŶ ĸÃÄ µð¹ÙÀ̽ºÀÇ datalink°èÃþÀÇ Á¾·ù¸¦ ³Ñ°Ü ¹Þ¾Æ ÀÌ¿¡ µû¸¥ ÀûÀýÇÑ ÇÔ¼öÆ÷ÀÎÅ͸¦ ÇÒ´çÇÏ°Ô µË´Ï´Ù. pcap_loop(pd, packetcnt, printer, pcap_userdata) ÀÌ ³ðÀÌ ½ÇÁ¦ ÆÐŶÀ» Àâ¾Æ¼­ ½ÇÇàÇÒ ÇÔ¼ö¸¦ ÁöÁ¤ÇØ ÁÖ´Â ÇÔ¼öÀÔ´Ï´Ù. packetcntÀÇ ¼ö¸¸Å­ ÆÐŶÀ» Àâ¾Æ¼­ ÀâÀ» ¶§ ¸¶´Ù printer°¡ °¡¸£Ä¡´Â ÇÔ¼ö¸¦ ¼öÇàÇÏ°Ô µË´Ï´Ù. packetcnt¸¦ 0À¸·Î ÁöÁ¤ÇÏ¸é ¹«ÇÑ´ë·Î ÇÔ¼ö¸¦ ½ÇÇàÇÕ´Ï´Ù. ´õ ÀÚ¼¼ÇÑ ¼³¸íÀ» ¿øÇÑ´Ù¸é ½ºÆ¼ºì½º ¾ÆÀú¾¾°¡ ¾´ unp(unix network programming) À» º¸¸é 26Àå¿¡ pcap library¿¡ ´ëÇÑ ¼³¸íÀÌ ³ª¿Í ÀÖ½À´Ï´Ù. ±×·³ ÀÌ pcap library¸¦ ÀÌ¿ëÇØ ½ÇÁ¦ ³×Æ®¿÷»óÀÇ ip±â¹ÝÀÇ tcp, udp, icmpÀÇ ÆÐŶÀ» Àâ¾Æ¼­ ÅؽºÆ®·Î Çʵ庰·Î »Ñ·ÁÁÖ´Â ¼Ò½º¸¦ º¸±â·Î ÇսôÙ. ÀÌ ¼Ò½º´Â Á¦°¡ tcpdumpÀÇ ¼Ò½º¸¦ º¸°í ³ë°¡´Ù ÇÁ·Î±×·¥À» ÇÑ °ÍÀÌ¸ç ¼Ò½º¿¡ ´ëÇÑ ¼³¸íÀº ÁÖ¼®À¸·Î ´ë½ÅÇÏ°Ú½À´Ï´Ù. ################################################################################## #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define PROMISCUOUS 1 struct iphdr *iph; struct tcphdr *tcph; struct udphdr *udph; struct icmp *icmph; static pcap_t *pd; int sockfd; int pflag; // DATA¸¦ ¹®ÀÚ·Î ÂïÀ» °ÍÀÎÁö. int rflag; // DATA¸¦ »ýÀ¸·Î ÂïÀ» °ÍÀÎÁö. int eflag; // DATALINK layer print option int cflag; // ÆÐŶÀ» ÀÌ ¼øÀÚ¸¸Å­ Âï¾îÁÖ°í Á¾·áÇÑ´Ù. int chcnt; // ¹®ÀÚ¸¦ ÂïÀ» ¶§ ¹®ÀÚÄ«¿îÅÍ ´ÙÀ½ÁÙ¿¡ Âï±âÀ§ÇØ char *device, *filter_rule; void packet_analysis(unsigned char *, const struct pcap_pkthdr *, const unsigned char *); struct printer { pcap_handler f; int type; }; /* datalink type¿¡ µû¸¥ ºÒ¸®¾îÁú ÇÔ¼öµéÀÇ ¸ñ·ÏµéÀ» °®´Â ±¸Á¶Ã¼ Data-link level type codes. #define DLT_NULL 0 no link-layer encapsulation #define DLT_EN10MB 1 Ethernet (10Mb) #define DLT_EN3MB 2 Experimental Ethernet (3Mb) #define DLT_AX25 3 Amateur Radio AX.25 #define DLT_PRONET 4 Proteon ProNET Token Ring #define DLT_CHAOS 5 Chaos #define DLT_IEEE802 6 IEEE 802 Networks #define DLT_ARCNET 7 ARCNET #define DLT_SLIP 8 Serial Line IP #define DLT_PPP 9 Point-to-point Protocol #define DLT_FDDI 10 FDDI #define DLT_ATM_RFC1483 11 LLC/SNAP encapsulated atm #define DLT_RAW 12 raw IP #define DLT_SLIP_BSDOS 13 BSD/OS Serial Line IP #define DLT_PPP_BSDOS 14 BSD/OS Point-to-point Protocol bpf.h ¶ó´Â Çì´õÈ­ÀÏ¿¡ À§¿Í °°Àº ³»¿ëÀ¸·Î Á¤ÀǵǾî ÀÖ´Ù. */ static struct printer printers[] = { { packet_analysis, DLT_IEEE802 }, { packet_analysis, DLT_EN10MB }, { NULL, 0 }, }; /* datalink type¿¡ µû¶ó ¼öÇàµÉ ÇÔ¼ö¸¦ °áÁ¤ÇÏ°Ô µÈ´Ù. ÀÌ´Â pcap_handler¶ó´Â ÇÔ¼öÇü Æ÷ÀÎÅÍÀÇ °ªÀ¸·Î ´ëÀԵȴÙ. */ static pcap_handler lookup_printer(int type) { struct printer *p; for(p=printers; p->f; ++p) if(type == p->type) return p->f; perror("unknown data link type"); } /* pcap_loop()¿¡ ÀÇÇØ ÆÐŶÀ» ÀâÀ» ¶§¸¶´Ù ºÒ·ÁÁö´Â ÇÔ¼ö pcap_handler°¡ ÀÌ ÇÔ¼ö¸¦ Æ÷ÀÎÅÍÇÏ°í Àֱ⠶§¹®ÀÌ´Ù */ void packet_analysis(unsigned char *user, const struct pcap_pkthdr *h, const unsigned char *p) { int j, temp; unsigned int length = h->len; struct ether_header *ep; unsigned short ether_type; unsigned char *tcpdata, *udpdata,*icmpdata; register unsigned int i; chcnt = 0; // ÀâÀº ÆÐŶÀ» ±×´ë·Î »ýÀ¸·Î Âï±â if(rflag) { while(length--) { printf("%02x ", *(p++)); if( (++chcnt % 16) == 0 ) printf("\n\t"); } fprintf(stdout, "\n"); return; } length -= sizeof(struct ether_header); // ethernet header mapping ep = (struct ether_header *)p; // ethernet header 14 bytes¸¦ °Ç³Ê ¶Ú Æ÷ÀÎÅÍ p += sizeof(struct ether_header); // datalink type ether_type = ntohs(ep->ether_type); printf("\n"); // lan frameÀÌ IEEE802Àΰæ¿ì ether_typeÇʵ尡 ±æÀÌÇʵ尡 µÈ´Ù. if(ether_type <= 1500) { ; /*while(length--) { if(++is_llchdr <= 3) { fprintf(stdout,"%02x",*p++); continue; } if(++next_line == 16) { next_line = 0; printf("\n\t"); } printf("%02x",*p++); }*/ } else { if(eflag) { printf("\n\n =================== Datalink layer ===================\n\t"); for(j=0; jether_dhost[j]); if(j != 5) printf(":"); } printf(" ------> "); for(j=0; jether_shost[j]); if(j != 5) printf(":"); } printf("\n\tether_type -> %x\n", ntohs(ep->ether_type)); } iph = (struct iphdr *) p; i = 0; if (ntohs(ep->ether_type) == ETHERTYPE_IP) { // ip ÆÐŶÀΰ¡? // packet capturingÇÑ °ÍÀ» È­¸é¿¡ Ãâ·ÂÇÏ´Â ºÎºÐ printf("\n\n =================== IP HEADER ===================\n"); printf("\t%s -----> ", inet_ntoa(iph->saddr)); printf("%s\n", inet_ntoa(iph->daddr)); printf("\tVersion: %d\n", iph->version); printf("\tHerder Length: %d\n", iph->ihl); printf("\tService: %#x\n",iph->tos); printf("\tTotal Length: %d\n", ntohs(iph->tot_len)); printf("\tIdentification : %d\n", ntohs(iph->id)); printf("\tFragment Offset: %d\n", ntohs(iph->frag_off)); printf("\tTime to Live: %d\n", iph->ttl); printf("\tChecksum: %d\n", ntohs(iph->check)); /* packetÀÇ ipºÎºÐÀ» °Ç³Ê¶Ú °÷¿¡¼­ºÎÅÍ tcp headerÀÇ ½ÃÀÛÀÌ µÈ´Ù. */ if(iph->protocol == IPPROTO_TCP) { tcph = (struct tcphdr *) (p + iph->ihl * 4); // tcp data´Â tcpdata = (unsigned char *) (p + (iph->ihl*4) + (tcph->doff * 4)); printf("\n\n =================== TCP HEADER ===================\n"); printf("\tSource Port: %d\n", ntohs(tcph->source)); printf("\tDestination Port: %d\n", ntohs(tcph->dest)); printf("\tSequence Number: %d\n", ntohl(tcph->seq)); printf("\tAcknowledgement Number: %d\n", ntohl(tcph->ack_seq)); printf("\tData Offset: %d\n", tcph->doff); printf("\tWindow: %d\n", ntohs(tcph->window)); printf("\tURG:%d ACK:%d PSH:%d RST:%d SYN:%d FIN:%d\n", tcph->urg, tcph->ack, tcph->psh, tcph->rst, tcph->syn, tcph->fin, ntohs(tcph->check), ntohs(tcph->urg_ptr)); printf("\n =================== TCP DATA(HEXA) =================\n\t"); chcnt = 0; for(temp = (iph->ihl * 4) + (tcph->doff * 4); temp <= ntohs(iph->tot_len) - 1; temp++) { printf("%02x ", *(tcpdata++)); if( (++chcnt % 16) == 0 ) printf("\n\t"); } if (pflag) { printf("\n =================== TCP DATA(CHAR) =================\n"); tcpdata = (unsigned char *) ((p + iph->ihl*4) + (tcph->doff*4)); for(temp = (iph->ihl * 4) + (tcph->doff * 4); temp <= ntohs(iph->tot_len) - 1; temp++) printf("%c", *(tcpdata++)); } printf("\n\t\t<<<<< End of Data >>>>>\n"); } else if(iph->protocol == IPPROTO_UDP) { udph = (struct udphdr *) (p + iph->ihl * 4); udpdata = (unsigned char *) (p + iph->ihl*4) + 8; printf("\n ==================== UDP HEADER =====================\n"); printf("\tSource Port : %d\n",ntohs(udph->source)); printf("\tDestination Port : %d\n", ntohs(udph->dest)); printf("\tLength : %d\n", ntohs(udph->len)); printf("\tChecksum : %x\n", ntohs(udph->check)); printf("\n =================== UDP DATA(HEXA) ================\n\t"); chcnt = 0; for(temp = (iph->ihl*4)+8; temp<=ntohs(iph->tot_len) -1; temp++) { printf("%02x ", *(udpdata++)); if( (++chcnt % 16) == 0) printf("\n\t"); } udpdata = (unsigned char *) (p + iph->ihl*4) + 8; if(pflag) { printf("\n=================== UDP DATA(CHAR) ================\n"); for(temp = (iph->ihl*4)+8; temp<=ntohs(iph->tot_len) -1; temp++) printf("%c", *(udpdata++)); } printf("\n\t\t<<<<< End of Data >>>>>\n"); } else if(iph->protocol == IPPROTO_ICMP) { icmph = (struct icmp *) (p + iph->ihl * 4); icmpdata = (unsigned char *) (p + iph->ihl*4) + 8; printf("\n\n =================== ICMP HEADER ===================\n"); printf("\tType : %d\n", icmph->icmp_type); printf("\tCode : %d\n", icmph->icmp_code); printf("\tChecksum : %02x\n", icmph->icmp_cksum); printf("\tID : %d\n", icmph->icmp_id); printf("\tSeq : %d\n", icmph->icmp_seq); printf("\n =================== ICMP DATA(HEXA) =================\n\t"); chcnt = 0; for(temp = (iph->ihl * 4) + 8; temp <= ntohs(iph->tot_len) - 1; temp++) { printf("%02x ", *(icmpdata++)); if( (++chcnt % 16) == 0 ) printf("\n\t"); } printf("\n\t\t<<<<< End of Data >>>>>\n"); } } } } void sig_int(int sig) { printf("Bye!!\n"); pcap_close(pd); close(sockfd); exit(0); } void usage(void) { fprintf(stdout," Usage : pa filter_rule [-pch]\n"); fprintf(stdout," -p : µ¥ÀÌŸ¸¦ ¹®ÀÚ·Î Ãâ·ÂÇÑ´Ù.\n"); fprintf(stdout," -c : ÁÖ¾îÁø ¼ýÀÚ¸¸Å­ÀÇ ÆÐŶ¸¸ ´ýÇÁÇÑ´Ù\n"); fprintf(stdout," -e : datalink layer¸¦ Ãâ·ÂÇÑ´Ù.\n"); fprintf(stdout," -e : ÀâÀº ÆÐŶÀ» »ýÀ¸·Î Âï´Â´Ù.\n"); fprintf(stdout," -h : »ç¿ë¹ý\n"); } int main(int argc, char *argv[]) { struct bpf_program fcode; pcap_handler printer; char ebuf[PCAP_ERRBUF_SIZE]; int c, i, snaplen = 512, size, packetcnt; bpf_u_int32 myself, localnet, netmask; unsigned char *pcap_userdata; filter_rule = argv[1]; // ex) src host xxx.xxx.xxx.xxx and tcp port 80 signal(SIGINT,sig_int); // signal hanlder µî·Ï opterr = 0; if(argc-1 < 1) { // option check usage(); exit(1); } while( (c = getopt(argc, argv,"i:c:pher")) != -1) { switch(c) { case 'i' : // ÆÐŶ ĸÃÄ ±â±â ÁöÁ¤ device = optarg break; case 'p' : // µ¥ÀÌÅ͸¦ ¹®ÀÚ·Î Ãâ·ÂÇÏ´Â ¿É¼Ç pflag = 1; break; case 'c' : // ´ýÇÁÇÏ·Á´Â ÆÐŶÀÇ ¼ö cflag = 1; packetcnt = atoi(optarg); if(packetcnt <= 0) { fprintf(stderr,"invalid pacet number %s",optarg); exit(1); } break; case 'e' : // µ¥ÀÌÅ͸µÅ© °èÃþ Ãâ·Â eflag = 1; break; case 'r' : // ÀâÀº ÆÐŶÀ» ¸ÊÇξøÀÌ 16Áø¼ö·Î ¸ðµÎ Âï´Â´Ù. rflag = 1; break; case 'h' : // »ç¿ë¹ý usage(); exit(1); } } if (device == NULL ) { if ( (device = pcap_lookupdev(ebuf) ) == NULL) { perror(ebuf); exit(-1); } } fprintf(stdout, "device = %s\n", device); pd = pcap_open_live(device, snaplen, PROMISCUOUS, 1000, ebuf); if(pd == NULL) { perror(ebuf); exit(-1); } i = pcap_snapshot(pd); if(snaplen < i) { perror(ebuf); exit(-1); } if(pcap_lookupnet(device, &localnet, &netmask, ebuf) < 0) { perror(ebuf); exit(-1); } setuid(getuid()); if(pcap_compile(pd, &fcode, filter_rule, 0, netmask) < 0) { perror(ebuf); exit(-1); } if(pcap_setfilter(pd, &fcode) < 0) { perror(ebuf); exit(-1); } fflush(stderr); printer = lookup_printer(pcap_datalink(pd)); pcap_userdata = 0; if(pcap_loop(pd, packetcnt, printer, pcap_userdata) < 0) { perror("pcap_loop error"); exit(-1); } pcap_close(pd); exit(0); } ################################################################################## ½ÇÁ¦ ½ÇÇà°á°ú¿Í »ç¿ë¹æ¹ýÀÌ È¨ÆäÀÌÁö¿¡ ¿Ã·ÁÁ® ÀÖ½À´Ï´Ù. ¼öÁ¤ÇÒ ºÎºÐÀ̳ª °è¼±ÇÒ Á¡ÀÌ ¸¹À¸´Ï ¼Ò½º¸¦ °íÃļ­ ´õ¿í °­·ÂÇÑ À¯Æ¿¸®Æ¼·Î ¸¸µé¾î º¸´Â °ÍÀÌ ÁÁÀ» °Í °°±º¿ä. ±×·¡µµ ¿ì¸®³ª¶ó¿¡ ¸¹Àº µµÀüÁ¤½Å°ú ½ÇÇèÁ¤½ÅÀ» °¡Áö°í ÀÖ´Â ¸®´ª¼­µéÀÌ ¸¸µç ÇÁ·Î±×·¥À» »ç¿ëÇÏ´Â ÆíÀÌ ÁÁ°ÚÁÒ...^^ À§ÀÇ ¼Ò½º¸¦ ÄÄÆÄÀÏÇؼ­ »ç¿ëÇϱâ À§Çؼ­´Â pcap library°¡ ÀÖ¾î¾ß ÇÏ¸ç ¾Æ¸¶ ¹èÆ÷ÆÇ ¸®´ª½º¶ó¸é /usr/lib/libpcap.a¶ó´Â È­ÀÏ·Î ÀÖÀ» °ÍÀÔ´Ï´Ù. ¾Æ·¡¿Í °°ÀÌ ¸µÅ©½ÃÄÑ ÄÄÆÄÀÏÇÏ½Ã¸é µË´Ï´Ù. ÄÄÆÄÀϽà bpf.h°¡ ¾ø´Ù´Â ¸Þ¼¼Áö°¡ ³ª¿Ã °æ¿ì /usr/include/pcap/net/bpf.h ¸¦ /usr/include/net/bpf.h·Î º¹»ç¸¦ ÇØÁÖ½Ã¸é µË´Ï´Ù. #cp /usr/include/pcap/net/bpf.h /usr/include/net #gcc -g -o noh_pa noh_pa.c -lpcap #./noh_pa "src host xxx.xxx.xxx.xxx and tcp port 80" -i eth0 -e -p ±×¸®°í tcp/ip¿¡ °ü·ÃµÈ Áö½ÄÀÌ ¿ä±¸µÇ´Â ¼Ò½ºÀ̹ǷΠ°ü·ÃÃ¥À» °°ÀÌ º¸½Ã¸é¼­ ÇÁ·Î±×·¥À» ÇϽô °ÍÀÌ ¼ö¿ùÇÏ½Ç °ÍÀÔ´Ï´Ù. ¿©±â¼­´Â ´Ü¼øÈ÷ ÆÐŶ¸¸À» Àâ¾Æ¼­ º¸¿©ÁÖ´Â µ¥ ±×Ä¡Áö¸¸ Á¶±Ý ´õ °ü½ÉÀ» °¡Áö½Ã¸é ÆÐŶÀ» Á÷Á¢ ¸¸µé¾î ´Ù¸¥ È£½ºÆ®·Î º¸³¾ ¼öµµ ÀÖ½À´Ï´Ù. pcap_libraryÀÇ ¼Ò½º¸¦ °íÃļ­ ±â´ÉÀ» ±¸ÇöÇÒ ¼öµµ ÀÖ°í raw socketÀ» ÀÌ¿ëÇÒ ¼öµµ ÀÖ½À´Ï´Ù. raw socketÀ» ÀÌ¿ëÇÏ´Â ´ëÇ¥ÀûÀÎ ¿¹·Î´Â ping ÇÁ·Î±×·¥À» µé ¼ö ÀÖ½À´Ï´Ù. unp¿¡ º¸½Ã¸é ¼Ò½º°¡ ³ª¿Í Àִµ¥ À̸¦ Àß ºÐ¼®ÇϽøé icmp»Ó ¾Æ´Ï¶ó ip,tcp,udpµîÀÇ ÆÐŶµµ Á÷Á¢ ¸¸µé¾î º¸³¾ ¼ö ÀÖ½À´Ï´Ù. ¸®´ª½ºÀÇ Çì´õÈ­ÀϵîÀ» »ìÆ캸¸é °¢ ÇÁ·ÎÅäÄݺ°·Î Çì´õÇü½ÄÀÇ ±¸Á¶Ã¼°¡ Àִµ¥ À̸¦ Âü°íÇÏ¸é µË´Ï´Ù. À§ ¼Ò½ºÀÇ include ºÎºÐÀÇ È­ÀϵéÀÔ´Ï´Ù. ¹°·Ð ´Ù¸¥ ÇÁ·ÎÅäÄݵµ Çì´õÇü½Ä¿¡ ¸Â°Ô ±¸¼º¸¸ ÇØ ÁØ´Ù¸é °¡´ÉÇÏÁö¿ä... ÀúÀÇ È¨ÆäÀÌÁö¿¡ º¸½Ã¸é icmpÀÇ ¸ñÀûÁö¹Ìµµ´Þ ÆÐŶÀ» Á÷Á¢ ±¸¼ºÇÏ¿© ÇØ´ç È£½ºÆ®ÀÇ Á¢¼ÓÀ» ²÷´Â ¼Ò½º°¡ ÀÖ½À´Ï´Ù. Âü°í¹Ù¶ø´Ï´Ù. ¼Ò°³ÇÑ ³»¿ë°ú ¼Ò½º°¡ °ü·Ã ÇÁ·Î±×·¥À» ¸· ½ÃÀÛÇÏ·Á´Â ºÐµé¿¡°Ô Á¶±ÝÀ̳ª¸¶ µµ¿òÀÌ µÇ¾úÀ¸¸é ÇÏ´Â ¹Ù·¥ÀÔ´Ï´Ù.