0%

PACKET SPOFFING AND SNIFFING PROJECT

一.实验目标

本实验的目标有两个方面:学习使用这些工具(Wireshark,Tcpdump,Netwox,Scapy)和了解这些工具背后的技术。对于第二个任务,将编写简单的嗅探器和欺骗程序,并获得深入了解这些程序的技术方面。

本实验涵盖以下主题:

• 嗅探和欺骗的工作原理

• 使用pcap库和Scapy进行数据包嗅探

• 使用原始套接字和Scapy进行数据包欺骗

• 使用Scapy操作数据包

二.实验原理

Sniffing就是一种能将本地网卡状态设成‘混杂’状态的模式,当网卡处于这种“混杂”方式时,该网卡具备“广播地址”,它对遇到的每一个帧都产生一个硬件中断以便提醒操作系统处理流经该物理媒体上的每一个报文包。(绝大多数的网卡具备置成混杂模式的能力)

一般来说,sniffing和poofing会联合起来使用。当攻击者嗅探到关键信息时,通常会使用poofing技术来构造数据包来劫持会话或者去获取更多信息,通常会造成很大的危害。Poofing技术就是攻击者自己构造数据包的ip/tcp数据包帧头部数据来达到自己的目的。

本次实验就是基于以上原理,在linux下模拟整个过程。

三.实验器材

1.Ubuntu12.04。

2.Wireshark等常用捕包工具。

四.实验步骤及运行结果

4.1 Lab Task Set 1: Using Tools to Sniff and Spoof Packets

4.1.1 Task 1.1: Sniffing Packets

Task 1.1A 上述程序嗅探数据包。对于每个捕获的数据包,回调函数打印 pkt()将被调用;此函数将打印出有关数据包的一些信息。运行程序根权限,并证明您确实可以捕获数据包。之后,再次运行该程序,但不使用根权限;描述并解释您的观察结果。

运行结果:

运行sniff时,在主机A中ping主机B可以截取到如上数据包

如果关掉root在用户状态下运行,会得到如下报错:

解释:普通用户没用权限执行sniff程序。

Task 1.1B. 通常,当我们嗅探数据包时,我们只对某些类型的数据包感兴趣。我们可以做到通过在嗅探中设置过滤器。斯卡皮的过滤器使用BPF(伯克利数据包过滤器)语法;您可以找到来自互联网的 BPF 手册。请设置以下过滤器并再次演示您的嗅探器程序(每个过滤器应单独设置):

仅仅捕获ICMP数据包(Task 1.1A中已经实现)

捕获来自于特定IP地址的TCP数据包并且目的端口号为23

首先在过滤器中对过滤规则进行更改如下:

然后了解到23端口作用如下:

可以在主机A中执行telnet 10.9.0.6 命令,并且执行sniff程序得到如下结果:

捕获来自于指定子网的数据包

设置过滤器规则如下:

捕获到数据包如下:

4.1.2 Task 1.2: Spoofing ICMP Packets

在attacker主机中利用虚拟机本地网卡enps03发送伪造数据包,并且利用wireshark进行数据包的截获得到如下结果,可以看到伪造成功。

4.1.3 Task 1.3: Traceroute

攻击者主机中对ping baidu.com 进行定位计算机和目标计算机之间的所有路由器。分别修改程序中的ttl为3,4,5可以得到如下运行结果:

4.1.4 Sniffing and-then Spoofing

单独在主机B中ping 8.8.8.8 可以观察到如下结果:

利用Scapy编写好伪造程序后在攻击者主机中进行运行,同时再次利用主机B进行ping 8.8.8.8 的命令,可以得到如下运行结果:

可以发现在主机B中,只发送了3个ping请求报文,但是却收到了6个响应报文,并且在攻击者主机中嗅探中,可以发现每次嗅探到一个请求报文,就会伪造一份响应报文,证明伪造成功。

4.2 Lab Task Set 2: Writing Programs to Sniff and Spoof Packets

4.2.1 Writing Packet Sniffing Program

Task 2.1A: Understanding How a Sniffer Works

运行结果如下:

问题回答:

A1:首先调用pcap对指定的enps03网卡进行监听,然后在过滤器中设置过滤规则,最后进行数据包的捕获。

A2:嗅探数据报涉及到隐私安全的问题,如果任何用户都可以执行这一操作,便可以通过嗅探到的数据进行分析,从而获取他人隐私,显然是不安全的。

A3: 打开混在模式可以监听网段下其他网卡发送的数据包,如果关闭就只能够监听到本机的数据包。

Task 2.1B: Writing Filters

捕获两个特定主机间的icmp数据包

捕获目的端口为10-100的tcp数据包

Task 2.1C: Sniffing Passwords

在攻击者主机中执行嗅探程序,同时在主机A中执行telnet 10.9.0.6 的命令,在此过程中需要输入用户名和密码,通过嗅探程序可以截获并且打印数据包,从而得到并破解用户的密码。

在截获过程中,观察到login后面得到的数据为sseeeedd,password后面得到的数据为dees,而主机本身的用户名为seed,密码为dees,证明截获到了正确的数据包,对用户名和密码捕获成功。

4.2.2 Spoofing

执行伪造程序,并且利用wireshark进行抓包,可以成功捕获到数据包,证明伪造数据包发送成功。

问题回答:

A4:可以随机设置报文头中的报文长度,但需要保证向socket发送的原始报文是正确的长度,否则可能会导致发送出的报文检验和不匹配从而无法收到回显报文。

A5:必须计算检验和,如按照默认的0x00,会导致报文在终点服务器检验不通过,从而被丢弃导致伪造失败。

A6:没有权限的用户不可以执行数据包的截获,发送等行为。

4.2.3 Sniff and then Spoof

首先在主机A上进行ping google,com ,发现无法连通,并且没有响应数据包

然后在攻击者主机中执行嗅探和伪造程序,再一次在主机A中执行ping google.com命令,可以得到如下运行结果:

可以观察到在主机A中可以成功收到icmp响应数据包,说明嗅探和伪造成功。

五.附件

Task1.1

1
2
3
4
5
6
7
8
9
10
#!/usr/bin/env python3
from scapy.all import *
num = 0
def print_pkt(pkt):
global num
num += 1
print("\n==================packet:{}===================\n".for
mat(num))
pkt.show()
pkt = sniff(iface = 'br-4ceb30c2d898',filter='src net 10.0.0.0/16',prn=print_pkt)

Task1.2

1
2
3
4
5
6
7
8
#!/usr/bin/env python3
from scapy.all import *
a =IP()
a.dst = '1.2.3.4'
b = ICMP()
p = a/b
ls(a)
send(p,iface = 'enp0s3')

Task1.3

1
2
3
4
5
6
7
8
9
#!/usr/bin/env python3
from scapy.all import *
a= IP()
a.dst='baidu.com'
a.ttl =15
b= ICMP()
# send(a/b)
a = sr1(a/b)
print("Source:",a.src)

Task1.4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/usr/bin/env python3
from scapy.all import *
def spoof_pkt(pkt):
# sniff and print out icmp echo request packet
if ICMP in pkt and pkt[ICMP].type == 8:
print("Original Packet.........")
print("Source IP : ", pkt[IP].src)
print("Destination IP :", pkt[IP].dst)
# spoof an icmp echo reply packet
# swap srcip and dstip
ip = IP(src=pkt[IP].dst, dst=pkt[IP].src, ihl=pkt[IP].ihl)
icmp = ICMP(type=0, id=pkt[ICMP].id, seq=pkt[ICMP].seq)
data = pkt[Raw].load
newpkt = ip/icmp/data
print("Spoofed Packet.........")
print("Source IP : ", newpkt[IP].src)
print("Destination IP :", newpkt[IP].dst)
send(newpkt, verbose=0)
pkt = sniff(iface = 'vetha6b71be',filter=filter, prn=spoof_pkt)

Task2.1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdlib.h>
#include <stdio.h>
#include <pcap.h>
void got_packet(u_char *args, const struct pcap_pkthdr *header,const u_char *packet)
{
printf("Got a packet\n");
}
int main()
{
pcap_t *handle;
char errbuf[PCAP_ERRBUF_SIZE];
struct bpf_program fp;
char filter_exp[] = "icmp";
bpf_u_int32 net;
// Step 1: Open live pcap session on NIC with name enp0s3
handle = pcap_open_live("enp0s3", BUFSIZ, 1, 1000, errbuf);
// Step 2: Compile filter_exp into BPF psuedo-code
pcap_compile(handle, &fp, filter_exp, 0, net);
if (pcap_setfilter(handle, &fp) !=0) {
pcap_perror(handle, "Error:");
exit(EXIT_FAILURE);
}
// Step 3: Capture packets
pcap_loop(handle, -1, got_packet, NULL);
pcap_close(handle); //Close the handle
return 0;
}

Task2.2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
/* Ethernet header */
struct ethheader {
u_char ether_dhost[6]; /* destination host address */
u_char ether_shost[6]; /* source host address */
u_short ether_type; /* IP? ARP? RARP? etc */
};
/* IP Header */
struct ipheader {
unsigned char iph_ihl:4, //IP header length
iph_ver:4; //IP version
unsigned char iph_tos; //Type of service
unsigned short int iph_len; //IP Packet length (data + header)
unsigned short int iph_ident; //Identification
unsigned short int iph_flag:3, //Fragmentation flags
iph_offset:13; //Flags offset
unsigned char iph_ttl; //Time to Live
unsigned char iph_protocol; //Protocol type
unsigned short int iph_chksum; //IP datagram checksum
struct in_addr iph_sourceip; //Source IP address
struct in_addr iph_destip; //Destination IP address
};
/* ICMP Header */
struct icmpheader {
unsigned char icmp_type; // ICMP message type
unsigned char icmp_code; // Error code
unsigned short int icmp_chksum; //Checksum for ICMP Header and data
unsigned short int icmp_id; //Used for identifying request
unsigned short int icmp_seq; //Sequence number
};
struct udpheader
{
u_int16_t udp_sport; /* source port */
u_int16_t udp_dport; /* destination port */
u_int16_t udp_ulen; /* udp length */
u_int16_t udp_sum; /* udp checksum */
}
/* TCP Header */
struct tcpheader {
u_short tcp_sport; /* source port */
u_short tcp_dport; /* destination port */
u_int tcp_seq; /* sequence number */
u_int tcp_ack; /* acknowledgement number */
u_char tcp_offx2; /* data offset, rsvd */
#define TH_OFF(th) (((th)->tcp_offx2 & 0xf0) >> 4)
u_char tcp_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 tcp_win; /* window */
u_short tcp_sum; /* checksum */
u_short tcp_urp; /* urgent pointer */
};
/* Psuedo TCP header */
struct pseudo_tcp
{
unsigned saddr, daddr;
unsigned char mbz;
unsigned char ptcl;
unsigned short tcpl;
struct tcpheader tcp;
char payload[1500];
};
unsigned short in_cksum (unsigned short *buf, int length);
void send_raw_ip_packet(struct ipheader* ip);
unsigned short in_cksum (unsigned short *buf, int length)
{
unsigned short *w = buf;
int nleft = length;
int sum = 0;
unsigned short temp=0;
/*
* The algorithm uses a 32 bit accumulator (sum), adds
* sequential 16 bit words to it, and at the end, folds back all
* the carry bits from the top 16 bits into the lower 16 bits.
*/
while (nleft > 1) {
sum += *w++;
nleft -= 2;
}
/* treat the odd byte at the end, if any */
if (nleft == 1) {
*(u_char *)(&temp) = *(u_char *)w ;
sum += temp;
}
/* add back carry outs from top 16 bits to low 16 bits */
sum = (sum >> 16) + (sum & 0xffff); // add hi 16 to low 16
sum += (sum >> 16); // add carry
return (unsigned short)(~sum);
}
void send_raw_ip_packet(struct ipheader* ip)
{
struct sockaddr_in dest_info;
int enable = 1;
// Step 1: Create a raw network socket.
int sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
// Step 2: Set socket option.
setsockopt(sock, IPPROTO_IP, IP_HDRINCL,
&enable, sizeof(enable));
// Step 3: Provide needed information about destination.
dest_info.sin_family = AF_INET;
dest_info.sin_addr = ip->iph_destip;
// Step 4: Send the packet out.
sendto(sock, ip, ntohs(ip->iph_len), 0,
(struct sockaddr *)&dest_info, sizeof(dest_info));
close(sock);
}
/******************************************************************
Spoof an ICMP echo request using an arbitrary source IP Address
*******************************************************************/
int main() {
char buffer[1500];
memset(buffer, 0, 1500);
/*********************************************************
Step 1: Fill in the ICMP header.
********************************************************/
struct icmpheader *icmp = (struct icmpheader *)
(buffer + sizeof(struct ipheader));
icmp->icmp_type = 8; //ICMP Type: 8 is request, 0 is reply.
// Calculate the checksum for integrity
icmp->icmp_chksum = 0;
icmp->icmp_chksum = in_cksum((unsigned short *)icmp,
sizeof(struct icmpheader));
/*********************************************************
Step 2: Fill in the IP header.
********************************************************/
struct ipheader *ip = (struct ipheader *) buffer;
ip->iph_ver = 4;
ip->iph_ihl = 5;
ip->iph_ttl = 20;
ip->iph_sourceip.s_addr = inet_addr("10.9.0.5");
ip->iph_destip.s_addr = inet_addr("8.8.8.8");
ip->iph_protocol = IPPROTO_ICMP;
ip->iph_len = htons(sizeof(struct ipheader) +sizeof(struct icmpheader));
/*********************************************************
Step 3: Finally, send the spoofed packet
********************************************************/
send_raw_ip_packet (ip);
return 0;
}

Task2.3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
#define APP_NAME "sniffex"
#define APP_DESC "sniffer example using libcap"
#define APP_COPYRIGHT "COPY"
#define APP_DISCLAIMER "NO WARNNING"
#include <pcap.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <arpa/inet.h>
#define SNAP_LEN 1518
#define SIZE_ETHERNET 14
#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 0x1ffff
u_char ip_ttl;
u_char ip_p;
u_char 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;
};
struct sniff_icmp {
u_char icmp_type;
u_char icmp_code;
u_short icmp_chksum;
u_short icmp_n;
};
void got_packet(u_char *args,const struct pcap_pkthdr *header,const u_char *packet);
void print_payload(const u_char *payload ,int len);
void print_hex_ascill_line(const u_char *payload,int len,int offset);
void print_app_banner(void);
void print_app_usage(void);
void print_app_banner(void)
{
printf("%s - %s\n",APP_NAME,APP_DESC);
printf("%s\n",APP_COPYRIGHT);
printf("%s\n",APP_DISCLAIMER);
printf("\n");
return;
}
void print_app_usage(void)
{
printf("Usage: %s [interface]\n",APP_NAME);
printf("/n");
printf("Options:\n");
printf(" interface listen on <interface> for packets. \n");
printf("\n");
return;
}
void print_hex_ascill_line(const u_char *payload,int len,int offset)
{
int i;
int gap;
const u_char *ch;
printf("%05d ",offset);
ch = payload;
for (i=0;i<len;i++){
printf("%02x ",*ch);
ch++;
if(i==7){
printf(" ");
}
}
if (len<8){
printf(" ");
}
if (len<16){
gap = 16-len;
for (i=0;i<gap;i++){
printf(" ");
}
}
printf(" ");
ch =payload;
for (i=0;i<len;i++){
if(isprint(*ch))
printf("%c",*ch);
else
printf(".");
ch++;
}
printf("\n");
return;
}
void print_payload(const u_char *payload ,int len)
{
int len_rem = len;
int line_width = 16;
int line_len;
int offset=0;
const u_char *ch = payload;
if (len<=0)
return;
if(len <=line_width)
{
print_hex_ascill_line(ch,len,offset);
return;
}
for ( ; ; ){
line_len = line_width % len_rem;
print_hex_ascill_line(ch,line_len,offset);
len_rem = len_rem - line_len;
ch = ch+ line_len;
offset = offset + line_width;
if(len_rem <= line_width){
print_hex_ascill_line(ch,len_rem,offset);
break;
}
}
return;
}
void send_icmpreply(u_char *packet)
{
const struct sniff_ip *old_ip_header;
old_ip_header = (struct sniff_ip *)(packet + SIZE_ETHERNET);
int ip_len = ntohs(old_ip_header->ip_len);
char buf[ip_len];
bzero(buf,sizeof(buf));
memcpy(buf,(packet + SIZE_ETHERNET),sizeof(buf));
char *ptr = buf;
struct sniff_ip *ip_header = (struct sniff_ip*)(ptr);
int size_ip_header = IP_HL(ip_header)*4;
struct sniff_icmp *icmp_header;
icmp_header = (struct sniff_icmp*)(packet +size_ip_header);
icmp_header->icmp_type = 8;
icmp_header->icmp_chksum = 0;
icmp_header->icmp_n =0 ;
struct in_addr tempAddress = ip_header->ip_dst;
ip_header->ip_dst = ip_header->ip_src;
ip_header->ip_src = tempAddress;
struct sockaddr_in dst;
dst.sin_family = AF_INET;
inet_pton(AF_INET,inet_ntoa(ip_header->ip_dst),&dst.sin_addr.s_addr);
dst.sin_port = htons(0);
icmp_header->icmp_n ++ ;
int one = 1;
int s;
s = socket(AF_INET,SOCK_RAW,IPPROTO_RAW);
setsockopt(s,IPPROTO_IP,IP_HDRINCL,&one,sizeof(one));
sendto(s,buf,sizeof(buf),0,(struct sockaddr *)&dst ,sizeof(dst));
close(s);
}
void got_packet(u_char *args,const struct pcap_pkthdr *header,const u_char *packet)
{
static int count = 1;
const struct sniff_ethernet *ethernet;
const struct sniff_ip *ip;
const struct sniff_tcp *tcp;
const char *payload;
int size_ip;
int size_tcp;
int size_payload;
printf("\n Packet number %d: \n",count);
count++;
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;
}
printf(" From: %s\n", inet_ntoa(ip->ip_src));
printf(" To: %s\n", inet_ntoa(ip->ip_dst));
switch(ip->ip_p)
{
case IPPROTO_TCP:
printf(" Protocol: TCP\n")
break;
case IPPROTO_UDP:
printf(" Protocol: UDP\n");
return;
case IPPROTO_ICMP:
printf(" Protocol: ICMP\n");
send_icmpreply(packet);
return;
default:
printf(" Protocol: others\n");
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;
}
printf(" Src port: %d\n",ntohs(tcp->th_sport));
printf(" Dst port: %d\n",ntohs(tcp->th_dport));
payload = (u_char*)(packet + SIZE_ETHERNET +size_ip + size_tcp);
size_payload = ntohs(ip->ip_len) - size_ip - size_tcp;
if ( size_payload >0 )
{
printf(" Payload (%d bytes):\n",size_payload);
print_payload(payload,size_payload);
}
return;
}
int main(int argc, char **argv)
{
char *dev = NULL;
char errbuf[PCAP_ERRBUF_SIZE];
pcap_t *handle;
char filter_exp[] = "icmp";
struct bpf_program fp;
bpf_u_int32 mask;
bpf_u_int32 net;
int num_packets = 100;
print_app_banner();
if(argc == 2 ){
dev = argv[1];
}
else if (argc > 2){
fprintf(stderr, "error:unrecongnized command_line options\n\n" );
print_app_usage();
exit(EXIT_FAILURE);
}
else{
dev = pcap_lookupdev(errbuf);
if(dev = NULL){
fprintf(stderr,"Couldn't find default device: %s\n",errbuf);
exit(EXIT_FAILURE);
}
}
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;
}
printf("Device: %s\n",dev);
printf("Number of packets: %d\n",num_packets);
printf("Filter expression: %s\n",filter_exp);
handle = pcap_open_live(dev,SNAP_LEN,1,1000,errbuf);
if(handle == NULL){
fprintf(stderr,"Couldn't open device %s : %s\n",dev,errbuf);
exit(EXIT_FAILURE);
}
if(pcap_datalink(handle) != DLT_EN10MB){
fprintf(stderr,"%s is not an Ethernet\n",dev);
exit(EXIT_FAILURE);
}
if(pcap_compile(handle,&fp,filter_exp,0,net) == -1){
fprintf(stderr,"Couldn't parse filter %s : %s\n",filter_exp,pcap_geterr(handle));
exit(EXIT_FAILURE);
}
if (pcap_setfilter(handle,&fp) == -1)
{
fprintf(stderr,"Couldn't install filter %s : %s\n",filter_exp,pcap_geterr(handle));
exit(EXIT_FAILURE);
}
pcap_loop(handle,num_packets,got_packet,NULL);
pcap_freecode(&fp);
pcap_close(handle);
printf("\n Capture complete. \n");
return 0;}