Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
emulab
emulab-devel
Commits
09ad13ee
Commit
09ad13ee
authored
Jan 08, 2003
by
Mike Hibler
Browse files
Have device threads stop snooping packets if there are no clients.
parent
472d7fee
Changes
1
Hide whitespace changes
Inline
Side-by-side
tools/pcapper/pcapper.c
View file @
09ad13ee
/*
* EMULAB-COPYRIGHT
* Copyright (c) 2000-200
2
University of Utah and the Flux Group.
* Copyright (c) 2000-200
3
University of Utah and the Flux Group.
* All rights reserved.
*/
...
...
@@ -224,11 +224,16 @@ extern int opterr;
extern
int
optreset
;
/*
* Lock used to make sure that the threads don't clobber the pa
k
cet counts.
* Lock used to make sure that the threads don't clobber the pac
k
et counts.
* We just use one big fat lock for all of them.
*/
pthread_mutex_t
lock
;
/*
* Condition variable for device threads to wait on for activity.
*/
pthread_cond_t
cond
;
/*
* Pakcet counts for the three types of packets that we care about.
*/
...
...
@@ -245,6 +250,11 @@ pcap_t *pcap_devs[MAX_INTERFACES];
*/
int
client_connected
[
MAX_CLIENTS
];
/*
* Number of active clients. When count is zero, the device is closed.
*/
volatile
int
active
;
int
MAX
(
int
a
,
int
b
)
{
if
((
a
)
>
(
b
))
return
(
a
);
else
return
(
b
);
}
void
usage
(
char
*
progname
)
{
...
...
@@ -388,6 +398,7 @@ int main (int argc, char **argv) {
bzero
(
client_connected
,
sizeof
(
client_connected
));
pthread_mutex_init
(
&
lock
,
NULL
);
pthread_cond_init
(
&
cond
,
NULL
);
#ifdef EMULAB
/*
...
...
@@ -667,6 +678,7 @@ int main (int argc, char **argv) {
args
->
cli
=
0
;
args
->
interval
=
filetime
;
client_connected
[
0
]
=
1
;
active
=
1
;
pthread_create
(
&
thread
,
NULL
,
feedclient
,
args
);
}
...
...
@@ -729,6 +741,13 @@ int main (int argc, char **argv) {
if
(
!
client_connected
[
i
])
{
/* printf("New client is %i\n",i); */
client_connected
[
i
]
=
1
;
if
(
active
>=
MAX_CLIENTS
)
{
fprintf
(
stderr
,
"active count screwed
\n
"
);
exit
(
1
);
}
if
(
++
active
==
1
)
pthread_cond_broadcast
(
&
cond
);
printf
(
"Now have %d clients
\n
"
,
active
);
break
;
}
}
...
...
@@ -766,6 +785,7 @@ void *feedclient(void *args) {
int
i
;
struct
timeval
next_time
,
now
,
interval_tv
;
int
dropped
;
int
called
=
0
;
s_args
=
(
struct
feedclient_args
*
)
args
;
cli
=
s_args
->
cli
;
...
...
@@ -901,11 +921,17 @@ void *feedclient(void *args) {
/*
* Drop information is not kept per-interface, so we just
* grab it from one of them.
* grab it from one of them. Note that since we close all
* devices when no one is active, it is possible that the
* device threads have not yet reopened their devices when
* we reach here.
*/
if
(
pcap_stats
(
pcap_devs
[
0
],
&
ps
))
{
printf
(
"Unable to get stats
\n
"
);
exit
(
1
);
if
(
pcap_devs
[
0
]
==
0
||
pcap_stats
(
pcap_devs
[
0
],
&
ps
))
{
if
(
!
called
)
{
fprintf
(
stderr
,
"WARNING: unable to get drop stats
\n
"
);
called
=
1
;
}
}
/*
...
...
@@ -927,7 +953,15 @@ void *feedclient(void *args) {
perror
(
"write"
);
}
/* printf("Client %i disconnected\n",cli);*/
pthread_mutex_lock
(
&
lock
);
if
(
client_connected
[
cli
]
==
0
||
active
<=
0
)
{
fprintf
(
stderr
,
"active count screwed
\n
"
);
exit
(
1
);
}
client_connected
[
cli
]
=
0
;
active
--
;
printf
(
"Now have %d clients
\n
"
,
active
);
pthread_mutex_unlock
(
&
lock
);
/*
* Client disconnected - exit the loop
*/
...
...
@@ -958,15 +992,21 @@ void *readpackets(void *args) {
sizeof
(
struct
tcphdr
);
sargs
=
(
struct
readpackets_args
*
)
args
;
again:
pthread_mutex_lock
(
&
lock
);
while
(
active
==
0
)
pthread_cond_wait
(
&
cond
,
&
lock
);
pthread_mutex_unlock
(
&
lock
);
/*
* NOTE: We set the timeout to a full second - if we set it lower, we
* don't get to see packets until a certain number have been buffered
* up, for some reason.
*/
dev
=
pcap_open_live
(
sargs
->
devname
,
size
,
1
,
1
,
ebuf
);
dev
=
pcap_open_live
(
sargs
->
devname
,
size
,
1
,
1
,
ebuf
);
if
(
!
dev
)
{
fprintf
(
stderr
,
"Failed to open %s: %s
\n
"
,
sargs
->
devname
,
ebuf
);
fprintf
(
stderr
,
"Failed to open %s: %s
\n
"
,
sargs
->
devname
,
ebuf
);
exit
(
1
);
}
...
...
@@ -984,14 +1024,23 @@ void *readpackets(void *args) {
pcap_lookupnet
(
sargs
->
devname
,
&
net
,
&
mask
,
ebuf
);
pcap_compile
(
dev
,
&
filter
,
""
,
0
,
net
);
pcap_setfilter
(
dev
,
&
filter
);
pcap_freecode
(
&
filter
);
#endif
if
(
pcap_loop
((
pcap_t
*
)
dev
,
-
1
,
got_packet
,
&
(
sargs
->
index
)))
{
printf
(
"Failed to start pcap_loop for %s
\n
"
,
sargs
->
devname
);
exit
(
1
);
/*
* We don't bother to lock the access to active. If it gets cleared
* immediately after a test, we make an extra loop. If it gets set
* immediately after, we do an extra open/close of the device.
* Neither case is life threatening.
*/
while
(
active
>
0
)
{
if
(
pcap_dispatch
(
dev
,
-
1
,
got_packet
,
&
sargs
->
index
)
<
0
)
{
printf
(
"pcap_dispatch failed for %s
\n
"
,
sargs
->
devname
);
exit
(
1
);
}
}
return
NULL
;
pcap_close
(
dev
);
goto
again
;
}
/*
...
...
@@ -1135,7 +1184,6 @@ void got_packet(u_char *args, const struct pcap_pkthdr *header,
}
}
pthread_mutex_unlock
(
&
lock
);
}
/*
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment