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@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..06b6cad 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); +int socket_bind_to_iface(const int fd, const int ifindex); +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..f69349e 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)); +}