Right now on every received packet we get the interface name
on which it arrived. This is not needed and is slow.
Make use of ifindex and retrieve interface name only when needed
(when capturing on "All interfaces").
Signed-off-by: Vitezslav Samel <vitezslav(a)samel.cz>
---
src/hostmon.c | 19 +++++++++++++--
src/ifaces.c | 38 ++++++++++++++++++++++++++++++
src/ifaces.h | 2 +
src/ifstats.c | 69 +++++++++++++++++++++++++++++--------------------------
src/ifstats.h | 1 +
src/itrafmon.c | 19 +++++++++++++--
src/packet.c | 8 ++++--
src/pktsize.c | 5 +--
src/serv.c | 5 +--
9 files changed, 118 insertions(+), 48 deletions(-)
diff --git a/src/hostmon.c b/src/hostmon.c
index d61967d..2ea0552 100644
--- a/src/hostmon.c
+++ b/src/hostmon.c
@@ -679,7 +679,7 @@ void hostmon(const struct OPTIONS *options, int facilitytime, char
*ifptr,
int is_ip;
int ch;
- char ifname[IFNAMSIZ];
+ char *ifname = ifptr;
struct timeval tv;
unsigned long starttime;
@@ -817,7 +817,7 @@ void hostmon(const struct OPTIONS *options, int facilitytime, char
*ifptr,
&& (((now - statbegin) / 60) >= facilitytime))
exitloop = 1;
- getpacket(fd, buf, &fromaddr, &ch, &br, ifname, table.tabwin);
+ getpacket(fd, buf, &fromaddr, &ch, &br, NULL, table.tabwin);
if (ch != ERR) {
if (keymode == 0) {
@@ -867,16 +867,29 @@ void hostmon(const struct OPTIONS *options, int facilitytime, char
*ifptr,
}
}
if (br > 0) {
+ char ifnamebuf[IFNAMSIZ];
+
pkt_result =
processpacket(buf, &ipacket, (unsigned int *) &br,
NULL, NULL, NULL, &fromaddr,
ofilter,
- MATCH_OPPOSITE_USECONFIG, ifname,
+ MATCH_OPPOSITE_USECONFIG, NULL,
0);
if (pkt_result != PACKET_OK)
continue;
+ if (!ifptr) {
+ /* we're capturing on "All interfaces", */
+ /* so get the name of the interface */
+ /* of this packet */
+ if (iface_get_ifname(fromaddr.sll_ifindex, ifname, sizeof(ifname)) != 0) {
+ write_error("Unable to get interface name");
+ break; /* can't get interface name, get out! */
+ }
+ ifname = ifnamebuf;
+ }
+
if ((fromaddr.sll_hatype == ARPHRD_ETHER)
|| (fromaddr.sll_hatype == ARPHRD_FDDI)
/* fix me
diff --git a/src/ifaces.c b/src/ifaces.c
index c1e0be5..8b47769 100644
--- a/src/ifaces.c
+++ b/src/ifaces.c
@@ -100,6 +100,44 @@ void err_iface_down(void)
write_error("Specified interface not active");
}
+int iface_get_ifindex(const char const *iface)
+{
+ int fd;
+ int ir;
+ struct ifreq ifr;
+
+ fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
+
+ strcpy(ifr.ifr_name, iface);
+ ir = ioctl(fd, SIOCGIFINDEX, &ifr);
+
+ close(fd);
+
+ if (ir != 0)
+ return(ir);
+
+ return(ifr.ifr_ifindex);
+}
+
+int iface_get_ifname(const int ifindex, char *ifname, int ifname_space)
+{
+ int fd;
+ int ir;
+ struct ifreq ifr;
+
+ fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
+
+ ifr.ifr_ifindex = ifindex;
+ ir = ioctl(fd, SIOCGIFNAME, &ifr);
+
+ close(fd);
+
+ if (ir == 0)
+ strncpy(ifname, ifr.ifr_name, ifname_space);
+
+ return(ir);
+}
+
void isdn_iface_check(int *fd, char *ifname)
{
if (*fd == -1) {
diff --git a/src/ifaces.h b/src/ifaces.h
index 5bf313d..d1b01e8 100644
--- a/src/ifaces.h
+++ b/src/ifaces.h
@@ -11,6 +11,8 @@ ifaces.h - prototype declaration for interface support determination
FILE *open_procnetdev(void);
int get_next_iface(FILE * fd, char *ifname, int n);
int iface_up(char *iface);
+extern int iface_get_ifindex(const char const *iface);
+extern int iface_get_ifname(const int ifindex, char *ifname, int ifname_space);
void err_iface_down(void);
void isdn_iface_check(int *fd, char *ifname);
char *gen_iface_msg(char *ifptr);
diff --git a/src/ifstats.c b/src/ifstats.c
index 2da2176..acba6f2 100644
--- a/src/ifstats.c
+++ b/src/ifstats.c
@@ -116,6 +116,8 @@ void initiflist(struct iflist **list)
}
while (get_next_iface(fd, ifname, sizeof(ifname))) {
+ int ifindex;
+
if (!*ifname)
continue;
@@ -131,6 +133,9 @@ void initiflist(struct iflist **list)
if (!iface_up(ifname))
continue;
+ ifindex = iface_get_ifindex(ifname);
+ if(ifindex < 0)
+ continue;
/*
* At this point, the interface is now sure to be up and running.
*/
@@ -138,6 +143,7 @@ void initiflist(struct iflist **list)
itmp = xmalloc(sizeof(struct iflist));
memset(itmp, 0, sizeof(struct iflist));
strcpy(itmp->ifname, ifname);
+ itmp->ifindex = ifindex;
index++;
itmp->index = index;
@@ -156,36 +162,32 @@ void initiflist(struct iflist **list)
fclose(fd);
}
-void positionptr(struct iftab *table, struct iflist **ptmp, char *ifname)
+struct iflist *positionptr(struct iflist *iflist, const int ifindex)
{
- struct iflist *plast = NULL;
- int ok = 0;
-
- *ptmp = table->head;
+ struct iflist *ptmp = iflist;
+ struct iflist *last = ptmp;
- while ((*ptmp != NULL) && (!ok)) {
- ok = (strcmp((*ptmp)->ifname, ifname) == 0);
-
- if (!ok) {
- if ((*ptmp)->next_entry == NULL)
- plast = *ptmp;
-
- *ptmp = (*ptmp)->next_entry;
- }
+ while ((ptmp != NULL) && (ptmp->ifindex != ifindex)) {
+ last = ptmp;
+ ptmp = ptmp->next_entry;
}
-
- if (*ptmp == NULL) {
- *ptmp = xmalloc(sizeof(struct iflist));
- memset(*ptmp, 0, sizeof(struct iflist));
- (*ptmp)->index = plast->index + 1;
- plast->next_entry = *ptmp;
- (*ptmp)->prev_entry = plast;
- (*ptmp)->next_entry = NULL;
- strcpy((*ptmp)->ifname, ifname);
-
- if ((*ptmp)->index <= LINES - 4)
- table->lastvisible = *ptmp;
+ /* no interface was found, try to create new one */
+ if(ptmp == NULL) {
+ struct iflist *itmp;
+
+ itmp = xmallocz(sizeof(struct iflist));
+ itmp->ifindex = ifindex;
+ itmp->index = last->index + 1;
+ if(!iface_get_ifname(ifindex, itmp->ifname, sizeof(itmp->ifname)))
+ return(NULL);
+
+ /* last can't be NULL otherwise we will have empty iflist */
+ last->next_entry = itmp;
+ itmp->prev_entry = last;
+ itmp->next_entry = NULL;
+ ptmp = itmp;
}
+ return(ptmp);
}
void destroyiflist(struct iflist *list)
@@ -407,7 +409,6 @@ void ifstats(const struct OPTIONS *options, struct filterstate
*ofilter,
FILE *logfile = NULL;
int br;
- char ifname[IFNAMSIZ];
int ch;
@@ -521,7 +522,7 @@ void ifstats(const struct OPTIONS *options, struct filterstate
*ofilter,
&& (((now - statbegin) / 60) >= facilitytime))
exitloop = 1;
- getpacket(fd, buf, &fromaddr, &ch, &br, ifname, table.statwin);
+ getpacket(fd, buf, &fromaddr, &ch, &br, NULL, table.statwin);
switch (ch) {
case ERR:
@@ -562,13 +563,15 @@ void ifstats(const struct OPTIONS *options, struct filterstate
*ofilter,
NULL, NULL, NULL, &fromaddr,
ofilter,
MATCH_OPPOSITE_USECONFIG,
- ifname, options->v6inv4asv6);
+ NULL, options->v6inv4asv6);
if (pkt_result != PACKET_OK
&& pkt_result != MORE_FRAGMENTS)
continue;
- positionptr(&table, &ptmp, ifname);
+ ptmp = positionptr(table.head, fromaddr.sll_ifindex);
+ if(!ptmp)
+ continue;
ptmp->total++;
@@ -745,7 +748,6 @@ void detstats(char *iface, const struct OPTIONS *options, int
facilitytime,
struct ip6_hdr *ip6packet = NULL;
unsigned int iphlen;
- char ifname[IFNAMSIZ];
struct sockaddr_ll fromaddr;
int br;
@@ -983,7 +985,7 @@ void detstats(char *iface, const struct OPTIONS *options, int
facilitytime,
&& (((now - statbegin) / 60) >= facilitytime))
exitloop = 1;
- getpacket(fd, buf, &fromaddr, &ch, &br, ifname, statwin);
+ getpacket(fd, buf, &fromaddr, &ch, &br, NULL, statwin);
switch (ch) {
case ERR:
@@ -1013,7 +1015,7 @@ void detstats(char *iface, const struct OPTIONS *options, int
facilitytime,
processpacket(buf, &packet, (unsigned int *) &br,
NULL, NULL, NULL, &fromaddr,
ofilter,
- MATCH_OPPOSITE_USECONFIG, ifname,
+ MATCH_OPPOSITE_USECONFIG, NULL,
options->v6inv4asv6);
if (pkt_result != PACKET_OK
@@ -1126,6 +1128,7 @@ void selectiface(char *ifname, int withall, int *aborted)
if ((withall) && (list != NULL)) {
ptmp = xmalloc(sizeof(struct iflist));
strncpy(ptmp->ifname, "All interfaces", sizeof(ptmp->ifname));
+ ptmp->ifindex = 0;
ptmp->prev_entry = NULL;
list->prev_entry = ptmp;
diff --git a/src/ifstats.h b/src/ifstats.h
index 781c8df..1dfb517 100644
--- a/src/ifstats.h
+++ b/src/ifstats.h
@@ -9,6 +9,7 @@ ifstats.h - structure definitions for interface counts
struct iflist {
char ifname[IFNAMSIZ];
+ int ifindex;
unsigned int encap;
unsigned long long iptotal;
unsigned long long ip6total;
diff --git a/src/itrafmon.c b/src/itrafmon.c
index 597f82c..dac8122 100644
--- a/src/itrafmon.c
+++ b/src/itrafmon.c
@@ -604,7 +604,7 @@ void ipmon(struct OPTIONS *options, struct filterstate *ofilter,
int curwin = 0;
int readlen;
- char ifname[IFNAMSIZ];
+ char *ifname = ifptr;
unsigned long long total_pkts = 0;
@@ -836,7 +836,7 @@ void ipmon(struct OPTIONS *options, struct filterstate *ofilter,
rotate_flag = 0;
}
- getpacket(fd, tpacket, &fromaddr, &ch, &readlen, ifname,
+ getpacket(fd, tpacket, &fromaddr, &ch, &readlen, NULL,
table.tcpscreen);
if (ch != ERR) {
@@ -1142,6 +1142,8 @@ void ipmon(struct OPTIONS *options, struct filterstate *ofilter,
}
if (readlen > 0) {
+ char ifnamebuf[IFNAMSIZ];
+
total_pkts++;
show_stats(statwin, total_pkts);
@@ -1150,11 +1152,22 @@ void ipmon(struct OPTIONS *options, struct filterstate *ofilter,
(unsigned int *) &readlen, &br,
&sport, &dport, &fromaddr,
ofilter, MATCH_OPPOSITE_ALWAYS,
- ifname, options->v6inv4asv6);
+ NULL, options->v6inv4asv6);
if (pkt_result != PACKET_OK)
continue;
+ if (!ifptr) {
+ /* we're capturing on "All interfaces", */
+ /* so get the name of the interface */
+ /* of this packet */
+ if (iface_get_ifname(fromaddr.sll_ifindex, ifnamebuf, sizeof(ifnamebuf)) != 0) {
+ write_error("Unable to get interface name");
+ break; /* error getting interface name, get out! */
+ }
+ ifname = ifnamebuf;
+ }
+
if ((fromaddr.sll_protocol != ETH_P_IP)
&& (fromaddr.sll_protocol != ETH_P_IPV6)) {
add_othp_entry(&othptbl, &table, 0, 0, NULL,
diff --git a/src/packet.c b/src/packet.c
index f99d959..d8211a9 100644
--- a/src/packet.c
+++ b/src/packet.c
@@ -143,9 +143,11 @@ void getpacket(int fd, char *buf, struct sockaddr_ll *fromaddr, int
*ch,
fromlen = sizeof(struct sockaddr_ll);
*br = recvfrom(fd, buf, MAX_PACKET_SIZE, 0,
(struct sockaddr *) fromaddr, &fromlen);
- ifr.ifr_ifindex = fromaddr->sll_ifindex;
- ioctl(fd, SIOCGIFNAME, &ifr);
- strcpy(ifname, ifr.ifr_name);
+ if(ifname) {
+ ifr.ifr_ifindex = fromaddr->sll_ifindex;
+ ioctl(fd, SIOCGIFNAME, &ifr);
+ strcpy(ifname, ifr.ifr_name);
+ }
}
if (!daemonized && FD_ISSET(0, &set))
*ch = wgetch(win);
diff --git a/src/pktsize.c b/src/pktsize.c
index a1e747f..b6e3790 100644
--- a/src/pktsize.c
+++ b/src/pktsize.c
@@ -155,7 +155,6 @@ void packet_size_breakdown(struct OPTIONS *options, char *ifname,
char buf[MAX_PACKET_SIZE];
int br;
char *ipacket;
- char iface[IFNAMSIZ];
unsigned int mtu;
struct sockaddr_ll fromaddr;
@@ -294,7 +293,7 @@ void packet_size_breakdown(struct OPTIONS *options, char *ifname,
&& (((now - starttime) / 60) >= facilitytime))
exitloop = 1;
- getpacket(fd, buf, &fromaddr, &ch, &br, iface, win);
+ getpacket(fd, buf, &fromaddr, &ch, &br, NULL, win);
if (ch != ERR) {
switch (ch) {
@@ -317,7 +316,7 @@ void packet_size_breakdown(struct OPTIONS *options, char *ifname,
processpacket(buf, &ipacket, (unsigned int *) &br,
NULL, NULL, NULL, &fromaddr,
ofilter,
- MATCH_OPPOSITE_USECONFIG, iface,
+ MATCH_OPPOSITE_USECONFIG, NULL,
0);
if (pkt_result != PACKET_OK)
diff --git a/src/serv.c b/src/serv.c
index cdb7738..a6d6b64 100644
--- a/src/serv.c
+++ b/src/serv.c
@@ -703,7 +703,6 @@ void servmon(char *ifname, struct porttab *ports, const struct OPTIONS
*options,
struct sockaddr_ll fromaddr;
int br;
- char iface[IFNAMSIZ];
unsigned int idx = 1;
unsigned int sport = 0;
@@ -867,7 +866,7 @@ void servmon(char *ifname, struct porttab *ports, const struct OPTIONS
*options,
&& (((now - starttime) / 60) >= facilitytime))
exitloop = 1;
- getpacket(fd, buf, &fromaddr, &ch, &br, iface, list.win);
+ getpacket(fd, buf, &fromaddr, &ch, &br, NULL, list.win);
if (ch != ERR) {
if (keymode == 0) {
@@ -1056,7 +1055,7 @@ void servmon(char *ifname, struct porttab *ports, const struct
OPTIONS *options,
processpacket(buf, &ipacket, (unsigned int *) &br,
&tot_br, &sport, &dport, &fromaddr,
ofilter,
- MATCH_OPPOSITE_USECONFIG, iface,
+ MATCH_OPPOSITE_USECONFIG, NULL,
options->v6inv4asv6);
if (pkt_result != PACKET_OK)
--
1.7.8.4