390 likes | 605 Views
CS4231 Local Area Networks HW1 – IP Packet Sniffer. 張詠承 passtaiker@gmail.com. Summary. 目的 啟用網路卡之 promiscuous mode ( 混雜模式 ) 從網路卡抓取封包 分析封包 顯示分析結果 Hint Raw socket/libpcap/winpcap Data link layer socket programming/Packet capture library Network packet capture. Example of screen shot.
E N D
CS4231Local Area NetworksHW1 – IP Packet Sniffer 張詠承 passtaiker@gmail.com
Summary • 目的 • 啟用網路卡之 promiscuous mode (混雜模式) • 從網路卡抓取封包 • 分析封包 • 顯示分析結果 • Hint • Raw socket/libpcap/winpcap • Data link layer socket programming/Packet capture library • Network packet capture
Example of screen shot (after # sudo ./a.out)
What’s Raw Socket • Simply put raw sockets provide a way to bypass the whole network stack traversal of a packet and deliver it directly to an application. • Raw socket r/w packets from Data Link Layer • 利用 Raw socket 可以讀寫 IPv4 packet 的 header • Read/write 那些 kernel 不處理的 protocol 的 IPpacket • ARP(Address Resolution Protocol) • RARP (Reverse ARP)
Why Raw Socket only the data is shipped to the application layer • TCP/UDP packets received from a socket • contains only payload part of a IP packet • ETH/IP/ARP hdrs are removed by kernel • Use raw socket to r/w the header of a IPv4 packet
How to Use Raw Socket // 宣告一個socket,第二個參數指出這是raw socket,第三個參數指出這是ARP封包 sd = socket(PF_PACKET , SOCK_RAW , htons(ETH_P_ALL)); // 第一個參數 PF_PACKET // It is a software interface to send/receive packets at layer 2 of the OSI //All packets received will be complete with all headers and data. //Supports filtering using Berkley Packet Filters. // 第二個參數 PF_PACKET 支援兩個 socket type: SOCK_DGRAM // return packets with the link-layer header removed SOCK_RAW // return complete link-layer packet // 最後一個參數 ETH_P_ALL // return frames for all protocols that the datalink receives ETH_P_IP // return IPv4 frames ETH_P_ARP // return ARP Protocol frames ETH_P_IPV6 // return IPv6 frames
How to Use Raw Socket addr.sll_family = PF_PACKET; addr.sll_protocol = htons(ETH_P_ARP); recvfrom(sd, rcvbuffer, sizeof(rcvbuffer), 0, (struct sockaddr*)&addr, &len) /* 第一個參數為 socket descriptor 第二個參數為接收內容的 buffer, 第三個參數為此內容的長度, 第四個參數不會用到設為 0, 第五個參數設定 address 的封包種類、接收的 protocol 等等 第六個參數為 addr 的長度 */
Example int main(int argc, char *argv[]) { // 省略變數宣告 // create raw socket for sniffing sd = socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ALL)); if(sd == -1){ perror("socket error\n"); return; } // set address addr.sll_family = PF_PACKET; addr.sll_protocol = htons(ETH_P_ALL);
Example for(;;) { len=sizeof(addr); // receive packets ret=recvfrom(sd, rcvbuffer, sizeof(rcvbuffer), 0, (struct sockaddr*)&addr, &len); if (ret == -1) continue; /* 於此處按照 IP protocol的格式 parsercvbuffer 先判斷 Ethernet 是否是 IP 的封包,若是的話就parse 並印出封包的內容 */ } } // end of main
Network API - libpcap • libpcap (Packet CAPture) provides a portable framework for low-level network monitoring. • Applications include network statistics collection, security monitoring, network debugging, etc. • libpcap is the library we are going to use to grab packets right as they come off of the network card • Tutorial • http://yuba.stanford.edu/~casado/pcap/section1.html
Libpcap - Functions • pcap_t * pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) • int pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
libpcap -Open up NIC for PCAP dev = pcap_lookupdev(errbuf); // 亦可寫成 dev = “eth0” If(dev == NULL) { fprintf(stderr,“%s\n”,errbuf); return -1; } descr = pcap_open_live(dev, BUFSIZ, promisc, pcap_time_out, errbuf); If(descr == NULL) { printf(“pcap_open_live(): %s\n”,errbuf); return -1; }
libpcap - Capture a Packet int ret; ret = pcap_dispatch( pt_a, 0, dev_a_handle, NULL); if ( ret == -1 ) { pcap_perror( pt_a, "pcap_dispatch err:"); } void dev_a_handle( u_char *devId, const struct pcap_pkthdr *hdr, const u_char *packet )
Network API - libnet • Designed by Mike Schiffman, libnet is a portable, open source, C-language library for creating and injecting network packets. • libnet supports packet creation at all network levels with the TCP/IP network model.
libnet - Functions • libnet_t *libnet_init(int injection_type, char *device, char *err_buf); • int libnet_write_link(struct libnet_link_int *l,const u_char *device, u_char *packet,int packet_size);
libnet - Initialization net_b = libnet_init( LIBNET_LINK, "eth0", errbuf ); if( net_a == NULL ) { fprintf(stderr, "libnet_init fail:%s ", errbuf ); return; }
libnet - Send a Packet c = libnet_write_link( net_b, (u_char*)packet, hdr->caplen );
pthread • int pthread_create(pthread_t * thread, const pthread_attr_t * attr, void * (*start_routine)(void *), void *arg); • thread - returns the thread id. (unsigned long int defined in bits/pthreadtypes.h) • attr - Set to NULL if default thread attributes are used. • void * (*start_routine) - pointer to the function to be threaded. Function has a single argument: pointer to void. • *arg - pointer to argument of function. To pass multiple arguments, send a pointer to a structure.
pthread • int pthread_join(pthread_t * thread, void **value_ptr); • The pthread_join() function suspends execution of the calling thread until the target thread terminates
libpcap, libnet Installation • libpcap • sudo apt-get install libpcap0.8-dev • libnet • sudo apt-get install libnet1-dev • Remember to Install these two library first
Programming Environment • You have to write your program on Linux platform. • You can install VMware to run Linux on it.
Promiscuous Mode • We can only receive frames destined to us (Unicast) , to everyone (Broadcast) and to some selected addresses we subscribe to (Multicast). • If we could receive the frames for all computers connected to our broadcast domain – Promiscuous mode
Promiscuous Mode • It is the “See All, Hear All” Wizard mode • Tells the network driver to accept all packets irrespective of whom the packets are addressed to. • Used for Network Monitoring – both legal and illegal monitoring • We can do this by programmatically setting the IFF_PROMISC flag or by using the ifconfig utility (ifconfig eth0 promisc) #include <sys/ioctl.h>#include <net/if.h>struct ifreq ifrq;strncpy(ethreq.ifr_name,"eth0",IFNAMSIZ);ioctl(sock,SIOCGIFFLAGS,&ifrq);ifrq.ifr_flags|=IFF_PROMISC;ioctl(sock,SIOCSIFFLAGS,&ifrq);
The making of a Sniffer • Create Raw socket – socket() • Set interface you want to sniff on in promiscuous mode. • Bind Raw socket to this interface – bind() • optional • Receive packets on the socket – recvfrom() • Process received packets • Close the raw socket().
Internet Address Manipulation • in_addr_t inet_addr(const char *cp) • convert the Internet host address cp from numbers-and-dots notation into binary data in network byte order • char *inet_ntoa(struct in_addr in) • convert the Internet host address in given in network byte order to a string in standard numbers-and-dots notation (a.b.c.d) • The string is returned in a statically allocated buffer, which subsequent calls will overwrite.
Network Byte Ordering • Network is big-endian, host may be big- or little-endian • Functions work on 16-bit (short) and 32-bit (long) values • htons() / htonl() • convert host byte order to network byte order • ntohs() / ntohl() • convert network byte order to host byte order • Use these to convert network addresses, ports, …
Ethernet Header Format • Destination • 目的地的 MAC address • Source • 傳送方的 MAC address • Message Type(#define ETH_P_ARP 0x0806) • 封包種類,如果該值是0x0806,則表示為ARP封包 • Data • 封包內容
IP Header Format • Protocol • IPPROTO_ICMP1 • IPPROTO_IGMP2 • IPPROTO_TCP6 • IPPROTO_UDP17
Requirements • packet number • time elapsed since capture was initiated (with microsecond resolution) • packet size • packet type (protocol) • ETHERNET packet: ARP • IP packet: TCP/UDP/ICMP/IGMP • source and destination IP addresses • summary information about the IP packet
Bonus • GUI • Filter • IP address • Protocol • Additional IP protocols • etc
Grading • Correctness (60%) • Report (30%) • How to run your program. • What you’ve learned? • What are you suffer from this HW? • Any feedback? • Coding Style (10%)
Hand in your program • Deadline: 2009/5/20 PM 23:59:59 • Write a simple report in text file. • Please tar/zip/rar your files (including code and report) named as 學號.tar (ex: 9762560.tar) and login to • ftp:// 140.114.71.48:4231, cs4231/cs4231s10 Change directory to Project1_upload and create a directory named your 學號, then upload your file in this directory.
Appendix • Raw socket 收封包: • http://blog.roodo.com/thinkingmore/archives/554037.html • WinPcap函式庫使用入門: • http://blog.roodo.com/thinkingmore/archives/554037.html • WinPcap函式庫下載與文件: • http://www.winpcap.org/devel.htm • LibPcap函式庫使用入門: • http://yuba.stanford.edu/~casado/pcap/section1.html • http://www.tcpdump.org/pcap.htm • VMWareServer 2.0安裝入門: • http://full827.pixnet.net/blog/post/24011324
Appendix • libpcap / libnet • http://web.zyline.com.cn/prolist.asp?id=4916 • http://dev.csdn.net/article/21/21009.shtm • pthread • http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html
Appendix • WireShark-the open source • http://www.wireshark.org/ • Ethernet 封包格式: • http://en.wikipedia.org/wiki/EtherType • IP 封包格式: • http://www.networksorcery.com/enp/protocol/ip.htm • Study-Area • http://www.study-rea.org/network/network_ip_arp.htm • 鳥哥的Linux • http://linux.vbird.org/linux_server/0110network_basic/0110network_basic.php