Transcript libpcap

張詠承
[email protected]
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 的 IP packet
 ARP (Address Resolution Protocol)
 RARP (Reverse ARP)
Why Raw Socket
 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
only the data is shipped to the application layer
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
ETH_P_IP
ETH_P_ARP
ETH_P_IPV6
// return frames for all protocols that the data link receives
// return IPv4 frames
// return ARP Protocol frames
// 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的格式 parse rcvbuffer
先判斷 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
#include <sys/ioctl.h>
eth0 promisc)
#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-anddots 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.
Internet Address Manipulation
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_ICMP 1
 IPPROTO_IGMP 2
 IPPROTO_TCP 6
 IPPROTO_UDP 17
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
Debugging
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
 VMWare Server 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/LinuxTutorialPosixThr
eads.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_b
asic.php
Demo