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