由 pcap_findalldevs_ex() 返回的每一个 pcap_if 结构体,都包含一个 pcap_addr 结构体,这个结构体由如下元素组成:
- 一个地址列表
- 一个掩码列表 (each of which corresponds to an entry in the addresses list).
- 一个广播地址列表 (each of which corresponds to an entry in the addresses list).
- 一个目的地址列表 (each of which corresponds to an entry in the addresses list).
另外, 函数 pcap_findalldevs_ex() 还能 返回远程适配器信息 和 一个位于所给的本地文件夹的pcap文件列表 。
下面的范例使用了ifprint()函数来打印出 pcap_if 结构体中所有的内容。程序对每一个由 pcap_findalldevs_ex() 函数返回的pcap_if,都调用ifprint()函数来实现打印。
1
#include
"
pcap.h
"
2
#pragma
comment(lib, "wpcap.lib")
3
#pragma
comment(lib, "Packet.lib")
4
#pragma
comment(lib, "wsock32.lib")
5
6
7
8
#ifndef WIN32
9
#include <sys/socket.h>
10
#include <netinet/
in
.h>
11
#else
12
#include <winsock.h>
13
#endif
14
15
16
//
函数原型
17
void
ifprint(pcap_if_t *
d);
18
char
*iptos(u_long
in
);
19
char
* ip6tos(
struct
sockaddr *sockaddr,
char
*address,
int
addrlen);
20
21
22
int
main()
23
{
24
pcap_if_t *
alldevs;
25
pcap_if_t *
d;
26
char
errbuf[PCAP_ERRBUF_SIZE+
1
];
27
char
source[PCAP_ERRBUF_SIZE+
1
];
28
29
printf(
"
Enter the device you want to list:\n
"
30
"
rpcap:// ==> lists interfaces in the local machine\n
"
31
"
rpcap://hostname:port ==> lists interfaces in a remote machine\n
"
32
"
(rpcapd daemon must be up and running\n
"
33
"
and it must accept 'null' authentication)\n
"
34
"
file://foldername ==> lists all pcap files in the give folder\n\n
"
35
"
Enter your choice:
"
);
36
37
fgets(source, PCAP_ERRBUF_SIZE, stdin);
38
source[PCAP_ERRBUF_SIZE] =
'
\0
'
;
39
40
/*
获得接口列表
*/
41
if
(pcap_findalldevs_ex(source, NULL, &alldevs, errbuf) == -
1
)
42
{
43
fprintf(stderr,
"
Error in pcap_findalldevs: %s\n
"
,errbuf);
44
exit(
1
);
45
}
46
47
/*
扫描列表并打印每一项
*/
48
for
(d=alldevs;d;d=d->
next)
49
{
50
ifprint(d);
51
}
52
53
pcap_freealldevs(alldevs);
54
55
return
1
;
56
}
57
58
59
60
/*
打印所有可用信息
*/
61
void
ifprint(pcap_if_t *
d)
62
{
63
pcap_addr_t *
a;
64
char
ip6str[
128
];
65
66
/*
设备名(Name)
*/
67
printf(
"
%s\n
"
,d->
name);
68
69
/*
设备描述(Description)
*/
70
if
(d->
description)
71
printf(
"
\tDescription: %s\n
"
,d->
description);
72
73
/*
Loopback Address
*/
74
printf(
"
\tLoopback: %s\n
"
,(d->flags & PCAP_IF_LOOPBACK)?
"
yes
"
:
"
no
"
);
75
76
/*
IP addresses
*/
77
for
(a=d->addresses;a;a=a->
next) {
78
printf(
"
\tAddress Family: #%d\n
"
,a->addr->
sa_family);
79
80
switch
(a->addr->
sa_family)
81
{
82
case
AF_INET:
83
printf(
"
\tAddress Family Name: AF_INET\n
"
);
84
if
(a->
addr)
85
printf(
"
\tAddress: %s\n
"
,iptos(((
struct
sockaddr_in *)a->addr)->
sin_addr.s_addr));
86
if
(a->
netmask)
87
printf(
"
\tNetmask: %s\n
"
,iptos(((
struct
sockaddr_in *)a->netmask)->
sin_addr.s_addr));
88
if
(a->
broadaddr)
89
printf(
"
\tBroadcast Address: %s\n
"
,iptos(((
struct
sockaddr_in *)a->broadaddr)->
sin_addr.s_addr));
90
if
(a->
dstaddr)
91
printf(
"
\tDestination Address: %s\n
"
,iptos(((
struct
sockaddr_in *)a->dstaddr)->
sin_addr.s_addr));
92
break
;
93
/*
94
case AF_INET6:
95
printf("\tAddress Family Name: AF_INET6\n");
96
if (a->addr)
97
printf("\tAddress: %s\n", ip6tos(a->addr, ip6str, sizeof(ip6str)));
98
break;
99
*/
100
default
:
101
printf(
"
\tAddress Family Name: Unknown\n
"
);
102
break
;
103
}
104
}
105
printf(
"
\n
"
);
106
}
107
108
109
110
/*
将数字类型的IP地址转换成字符串类型的
*/
111
#define
IPTOSBUFFERS 12
112
char
*iptos(u_long
in
)
113
{
114
static
char
output[IPTOSBUFFERS][
3
*
4
+
3
+
1
];
115
static
short
which;
116
u_char *
p;
117
118
p = (u_char *)&
in
;
119
which = (which +
1
== IPTOSBUFFERS ?
0
: which +
1
);
120
sprintf(output[which],
"
%d.%d.%d.%d
"
, p[
0
], p[
1
], p[
2
], p[
3
]);
121
return
output[which];
122
}
123
124
125
/*
126
char* ip6tos(struct sockaddr *sockaddr, char *address, int addrlen)
127
{
128
socklen_t sockaddrlen;
129
130
#ifdef WIN32
131
sockaddrlen = sizeof(struct sockaddr_in6);
132
#else
133
sockaddrlen = sizeof(struct sockaddr_storage);
134
#endif
135
136
137
if(getnameinfo(sockaddr,
138
sockaddrlen,
139
address,
140
addrlen,
141
NULL,
142
0,
143
NI_NUMERICHOST) != 0) address = NULL;
144
145
return address;
146
}
147
*/
结果:
此处只能显示电脑的ipv4的网卡信息,不知道为什么不能有ipv6的代码时,不能编译通过,不知道是包不支持,还是系统不支持;
int
pcap_findalldevs_ex (
char
*
source,
struct
pcap_rmtauth *
auth,
pcap_if_t
**
alldevs,
char
*
errbuf
)
·该函数请查看前一篇;
struct
pcap_rmtauth{
int
type
//
Type of the authentication required.
char
*
username
//
Zero-terminated string containing the username that has to be used on the remote machine for authentication.
char
*
password
//
Zero-terminated string containing the password that has to be used on the remote machine for authentication.
};
typedef struct pcap_if pcap_if_t ;
struct
pcap_if {
pcap_if
*
next
//
if not NULL, a pointer to the next element in the list; NULL for the last element of the list
char
*
name
//
a pointer to a string giving a name for the device to pass to pcap_open_live()
char
*
description
//
if not NULL, a pointer to a string giving a human-readable description of the device
pcap_addr *
addresses
//
a pointer to the first element of a list of addresses for the interface
u_int flags
//
PCAP_IF_ interface flags. Currently the only possible flag is PCAP_IF_LOOPBACK, that is set if the interface is a loopback interface.
};
typedef struct pcap_addr pcap_addr_t ;
struct
pcap_addr
{
pcap_addr
*
next
//
if not NULL, a pointer to the next element in the list; NULL for the last element of the list
sockaddr *
addr
//
a pointer to a struct sockaddr containing an address
sockaddr *
netmask
//
if not NULL, a pointer to a struct sockaddr that contains the netmask corresponding to the address pointed to by addr.
sockaddr *
broadaddr
//
if not NULL, a pointer to a struct sockaddr that contains the broadcast address corre sponding to the address pointed to by addr; may be null if the interface doesn't support broadcasts
sockaddr *
dstaddr
//
if not NULL, a pointer to a struct sockaddr that contains the destination address corre sponding to the address pointed to by addr; may be null if the interface isn't a point- to-point interface
};
struct
sockaddr {
unsigned
short
sa_family;
char
sa_data[
14
];
};
·详细的请看前面的socket编程;
struct
sockaddr_in{
short
sin_family;
unsigned
short
sin_port;
struct
in_addr sin_addr;
char
sin_zero[
8
];
};
in_addr
The in_addr structure represents a host by its Internet address.
struct
in_addr {
union {
struct
{ u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;
struct
{ u_short s_w1,s_w2; } S_un_w;
u_long S_addr;
} S_un;
};
Members
- S_un_b
- Address of the host formatted as four u_chars.
- S_un_w
- Address of the host formatted as two u_shorts.
- S_addr
- Address of the host formatted as a u_long.
fgets, fgetws
Get a string from a stream.
char
*fgets(
char
*
string
,
int
n, FILE *
stream );
wchar_t
*fgetws( wchar_t *
string
,
int
n, FILE *stream );

