To reduce number of compares of interface name (to throw away
packets we don't want) lock the socket to the given interface
using bind() interface.
Signed-off-by: Vitezslav Samel <vitezslav(a)samel.cz>
---
src/hostmon.c | 16 ++++++++++++++--
src/ifstats.c | 25 ++++++++++++++++++++++---
src/iptraf-ng-compat.h | 2 ++
src/itrafmon.c | 20 ++++++++++++++++----
src/pktsize.c | 19 +++++++++++++++----
src/serv.c | 17 +++++++++++++++--
src/wrapper.c | 24 ++++++++++++++++++++++++
7 files changed, 108 insertions(+), 15 deletions(-)
diff --git a/src/hostmon.c b/src/hostmon.c
index 57f6b82..e64ab9c 100644
--- a/src/hostmon.c
+++ b/src/hostmon.c
@@ -705,6 +705,8 @@ void hostmon(const struct OPTIONS *options, int facilitytime, char
*ifptr,
int instance_id;
char msgstring[80];
+ int fd;
+
struct promisc_states *promisc_list;
if (!facility_active(LANMONIDFILE, ifptr))
@@ -725,8 +727,6 @@ void hostmon(const struct OPTIONS *options, int facilitytime, char
*ifptr,
}
}
- int fd = xsocket_raw_eth_p_all();
-
if ((first_active_facility()) && (options->promisc)) {
init_promisc_list(&promisc_list);
save_promisc_list(promisc_list);
@@ -771,6 +771,16 @@ void hostmon(const struct OPTIONS *options, int facilitytime, char
*ifptr,
"******** LAN traffic monitor started ********");
leaveok(table.tabwin, TRUE);
+ fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
+ if(fd == -1) {
+ write_error("Unable to obtain monitoring socket");
+ goto err;
+ }
+ if(ifptr && socket_bind_to_iface_by_name(fd, ifptr) == -1) {
+ write_error("Unable to bind interface on the socket");
+ goto err_close;
+ }
+
exitloop = 0;
gettimeofday(&tv, NULL);
starttime = statbegin = startlog = tv.tv_sec;
@@ -964,8 +974,10 @@ void hostmon(const struct OPTIONS *options, int facilitytime, char
*ifptr,
}
} while (!exitloop);
+err_close:
close(fd);
+err:
if ((options->promisc) && (is_last_instance())) {
load_promisc_list(&promisc_list);
srpromisc(0, promisc_list);
diff --git a/src/ifstats.c b/src/ifstats.c
index 67fc399..74beb97 100644
--- a/src/ifstats.c
+++ b/src/ifstats.c
@@ -411,6 +411,8 @@ void ifstats(const struct OPTIONS *options, struct filterstate
*ofilter,
int ch;
+ int fd;
+
struct timeval tv;
unsigned long starttime = 0;
unsigned long statbegin = 0;
@@ -438,7 +440,6 @@ void ifstats(const struct OPTIONS *options, struct filterstate
*ofilter,
}
initiftab(&table);
- int fd = xsocket_raw_eth_p_all();
if ((first_active_facility()) && (options->promisc)) {
init_promisc_list(&promisc_list);
@@ -476,6 +477,12 @@ void ifstats(const struct OPTIONS *options, struct filterstate
*ofilter,
update_panels();
doupdate();
+ fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
+ if(fd == -1) {
+ write_error("Unable to obtain monitoring socket");
+ goto err;
+ }
+
//isdnfd = -1;
exitloop = 0;
gettimeofday(&tv, NULL);
@@ -584,6 +591,7 @@ void ifstats(const struct OPTIONS *options, struct filterstate
*ofilter,
}
close(fd);
+err:
if ((options->promisc) && (is_last_instance())) {
load_promisc_list(&promisc_list);
srpromisc(0, promisc_list);
@@ -777,6 +785,7 @@ void detstats(char *iface, const struct OPTIONS *options, int
facilitytime,
struct promisc_states *promisc_list;
char err_msg[80];
+ int fd;
/*
* Mark this facility
@@ -793,8 +802,6 @@ void detstats(char *iface, const struct OPTIONS *options, int
facilitytime,
return;
}
- int fd = xsocket_raw_eth_p_all();
-
if (!iface_up(iface)) {
err_iface_down();
unmark_facility(DSTATIDFILE, iface);
@@ -862,6 +869,16 @@ void detstats(char *iface, const struct OPTIONS *options, int
facilitytime,
leaveok(statwin, TRUE);
+ fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
+ if(fd == -1) {
+ write_error("Unable to obtain monitoring socket");
+ goto err;
+ }
+ if(socket_bind_to_iface_by_name(fd, iface) == -1) {
+ write_error("Unable to bind interface on the socket");
+ goto err_close;
+ }
+
//isdnfd = -1;
exitloop = 0;
@@ -1184,8 +1201,10 @@ void detstats(char *iface, const struct OPTIONS *options, int
facilitytime,
}
}
+err_close:
close(fd);
+err:
if ((options->promisc) && (is_last_instance())) {
load_promisc_list(&promisc_list);
srpromisc(0, promisc_list);
diff --git a/src/iptraf-ng-compat.h b/src/iptraf-ng-compat.h
index 28af383..ea42979 100644
--- a/src/iptraf-ng-compat.h
+++ b/src/iptraf-ng-compat.h
@@ -96,6 +96,8 @@ extern char *xstrdup(const char *s);
extern int xsocket(int domain, int type, int protocol);
extern int xsocket_raw_eth_p_all(void);
+extern int socket_bind_to_iface(const int fd, const int ifindex);
+extern int socket_bind_to_iface_by_name(const int fd, const char const *ifname);
extern void die(const char *err, ...);
extern void NORETURN die_errno(const char *err);
diff --git a/src/itrafmon.c b/src/itrafmon.c
index 8d37051..85f2781 100644
--- a/src/itrafmon.c
+++ b/src/itrafmon.c
@@ -88,7 +88,7 @@ void prepare_statwin(WINDOW * win)
{
wattrset(win, IPSTATLABELATTR);
wmove(win, 0, 1);
- wprintw(win, "Pkts captured (all interfaces):");
+ wprintw(win, "Packets captured:");
mvwaddch(win, 0, 45 * COLS / 80, ACS_VLINE);
}
@@ -627,6 +627,8 @@ void ipmon(struct OPTIONS *options, struct filterstate *ofilter,
int fragment = 0; /* Set to 1 if not first fragment */
+ int fd;
+
int ch;
int keymode = 0;
char msgstring[80];
@@ -665,8 +667,6 @@ void ipmon(struct OPTIONS *options, struct filterstate *ofilter,
}
}
- int fd = xsocket_raw_eth_p_all();
-
if (options->promisc) {
if (first_active_facility()) {
init_promisc_list(&promisc_list);
@@ -745,6 +745,16 @@ void ipmon(struct OPTIONS *options, struct filterstate *ofilter,
writelog(logging, logfile,
"******** IP traffic monitor started ********");
+ fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
+ if(fd == -1) {
+ write_error("Unable to obtain monitoring socket");
+ goto err;
+ }
+ if(ifptr && socket_bind_to_iface_by_name(fd, ifptr) == -1) {
+ write_error("Unable to bind interface on the socket");
+ goto err_close;
+ }
+
//isdnfd = -1;
exitloop = 0;
gettimeofday(&tv, NULL);
@@ -1519,6 +1529,9 @@ void ipmon(struct OPTIONS *options, struct filterstate *ofilter,
}
}
+err_close:
+ close(fd);
+err:
if (get_instance_count(ITRAFMONCOUNTFILE) <= 1)
killrvnamed();
@@ -1550,7 +1563,6 @@ void ipmon(struct OPTIONS *options, struct filterstate *ofilter,
delwin(othptbl.othpwin);
delwin(othptbl.borderwin);
delwin(statwin);
- close(fd);
destroytcptable(&table);
destroyothptable(&othptbl);
pkt_cleanup();
diff --git a/src/pktsize.c b/src/pktsize.c
index 49abf3f..88be980 100644
--- a/src/pktsize.c
+++ b/src/pktsize.c
@@ -174,6 +174,7 @@ void packet_size_breakdown(struct OPTIONS *options, char *ifname,
struct promisc_states *promisc_list;
char msgstring[80];
+ int fd;
if (!facility_active(PKTSIZEIDFILE, ifname))
mark_facility(PKTSIZEIDFILE, "Packet size breakdown", ifname);
@@ -242,9 +243,7 @@ void packet_size_breakdown(struct OPTIONS *options, char *ifname,
exitloop = 0;
gettimeofday(&tv, NULL);
- starttime = startlog = timeint = tv.tv_sec;
-
- int fd = xsocket_raw_eth_p_all();
+ now = starttime = startlog = timeint = tv.tv_sec;
if ((first_active_facility()) && (options->promisc)) {
init_promisc_list(&promisc_list);
@@ -255,6 +254,16 @@ void packet_size_breakdown(struct OPTIONS *options, char *ifname,
adjust_instance_count(PROCCOUNTFILE, 1);
+ fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
+ if(fd == -1) {
+ write_error("Unable to obtain monitoring socket");
+ goto err;
+ }
+ if(socket_bind_to_iface_by_name(fd, ifname) == -1) {
+ write_error("Unable to bind interface on the socket");
+ goto err_close;
+ }
+
do {
gettimeofday(&tv, NULL);
now = tv.tv_sec;
@@ -318,6 +327,9 @@ void packet_size_breakdown(struct OPTIONS *options, char *ifname,
}
} while (!exitloop);
+err_close:
+ close(fd);
+err:
if (logging) {
signal(SIGUSR1, SIG_DFL);
write_size_log(brackets, now - starttime, ifname, mtu, logfile);
@@ -325,7 +337,6 @@ void packet_size_breakdown(struct OPTIONS *options, char *ifname,
"******** Packet size distribution facility stopped ********");
fclose(logfile);
}
- close(fd);
if ((options->promisc) && (is_last_instance())) {
load_promisc_list(&promisc_list);
diff --git a/src/serv.c b/src/serv.c
index 1130ff7..8ea2f04 100644
--- a/src/serv.c
+++ b/src/serv.c
@@ -739,6 +739,8 @@ void servmon(char *ifname, struct porttab *ports, const struct OPTIONS
*options,
const int statx = 1;
+ int fd;
+
/*
* Mark this facility
*/
@@ -752,8 +754,6 @@ void servmon(char *ifname, struct porttab *ports, const struct OPTIONS
*options,
return;
}
- int fd = xsocket_raw_eth_p_all();
-
if (!iface_up(ifname)) {
err_iface_down();
unmark_facility(TCPUDPIDFILE, ifname);
@@ -818,6 +818,16 @@ void servmon(char *ifname, struct porttab *ports, const struct
OPTIONS *options,
update_panels();
doupdate();
+ fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
+ if(fd == -1) {
+ write_error("Unable to obtain monitoring socket");
+ goto err;
+ }
+ if(socket_bind_to_iface_by_name(fd, ifname) == -1) {
+ write_error("Unable to bind interface on the socket");
+ goto err_close;
+ }
+
while (!exitloop) {
gettimeofday(&tv, NULL);
now = tv.tv_sec;
@@ -1090,6 +1100,9 @@ void servmon(char *ifname, struct porttab *ports, const struct
OPTIONS *options,
}
}
+err_close:
+ close(fd);
+err:
if (logging) {
signal(SIGUSR1, SIG_DFL);
writeutslog(list.head, time((time_t *) NULL) - starttime,
diff --git a/src/wrapper.c b/src/wrapper.c
index 9cbd538..3636b5b 100644
--- a/src/wrapper.c
+++ b/src/wrapper.c
@@ -95,3 +95,27 @@ int xsocket_raw_eth_p_all(void)
{
return xsocket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
}
+
+int socket_bind_to_iface(const int fd, const int ifindex)
+{
+ struct sockaddr_ll fromaddr;
+ socklen_t addrlen = sizeof(fromaddr);
+
+ fromaddr.sll_family = AF_PACKET;
+ fromaddr.sll_protocol = htons(ETH_P_ALL);
+ fromaddr.sll_ifindex = ifindex;
+ return bind(fd, (struct sockaddr *) &fromaddr, addrlen);
+}
+
+int socket_bind_to_iface_by_name(const int fd, const char const *ifname)
+{
+ int ir;
+ struct ifreq ifr;
+
+ strcpy(ifr.ifr_name, ifname);
+ ir = ioctl(fd, SIOCGIFINDEX, &ifr);
+ if(ir != 0)
+ return(ir);
+
+ return socket_bind_to_iface(fd, ifr.ifr_ifindex);
+}
--
1.7.8.4