Vitezslav Samel <vitezslav(a)samel.cz> writes:
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(-)
this patch looks to me suspicious
diff --git a/src/hostmon.c b/src/hostmon.c
index 59be4e9..d8854e8 100644
--- a/src/hostmon.c
+++ b/src/hostmon.c
@@ -678,7 +678,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;
@@ -814,7 +814,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) {
@@ -864,16 +864,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) {
iface_get_ifname() has too much parameters. sizeof(ifname) is alway
IFNAMSIZ. get rid of it.
+ write_error("Unable to get interface name");
+ break; /* can't get interface name, get out! */
+ }
+ ifname = ifnamebuf;
bug. you fill ifname in iface_get_ifname() by resolving name given by
sll_ifindex and here [ifname = ifnamebuf] you dicard resovled name.
I susspect you that you wanted to use it like that:
if (iface_get_ifname(fromaddr.sll_ifindex, ifnamebuf, sizeof(ifname)) != 0) {
^^^^^^^^^ not ifname
I also don't like to use if (func()).
it's way better to use
int r = func(params);
if (r)
do_something();
+ }
+
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)
if you want to have a constant pointer to constant data than it is
_const char * const iface_
const char *iface is enough
+{
+ int fd;
+ int ir;
+ struct ifreq ifr;
+
+ fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
bug. what it socket fails and fd = -1? According to man pages:
int ioctl(int d, int request, ...);
"The argument d must be an open file descriptor."
+ strcpy(ifr.ifr_name, iface);
+ ir = ioctl(fd, SIOCGIFINDEX, &ifr);
+
+ close(fd);
+
+ if (ir != 0)
+ return(ir);
+
+ return(ifr.ifr_ifindex);
+}
we must check socket(), ioctl() and inform user and return appropriate
err code. correct your coding style _return(foo)_ to _retun foo_
just curiosity. why are you using
int fd;
fd = socket();
insted of
int fd = socket(); ?
+int iface_get_ifname(const int ifindex, char *ifname, int
ifname_space)
^^^^^ pointless const casting
it already is constant, because the ifindex value is copied from origin.
+{
+ int fd;
+ int ir;
+ struct ifreq ifr;
+
+ fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
> +
> + ifr.ifr_ifindex = ifindex;
simply init struct
struct ifreq ifr = {
.ifr_ifindex = ifindex;
};
and you will kill two birds with one stone.
+ ir = ioctl(fd, SIOCGIFNAME, &ifr);
+
+ close(fd);
+
+ if (ir == 0)
+ strncpy(ifname, ifr.ifr_name, ifname_space);
+
+ return(ir);
+}
+
ditto w/ checking socket() and ioctl().
int iface_get_ifname(int ifindex, char *ifname)
{
int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (fd < 0)
return fd;
struct ifreq ifr = {
.ifr_ifindex = ifindex;
};
int ir = ioctl(fd, SIOCGIFNAME, &ifr);
if (ir < 0)
return ir;
return strncpy(ifname, ifr.ifr_name, IFNAMSIZ);
}
whenever iface_get_ifname() returns < 0, print errno
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 9997a34..7a0de75 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 dea71b2..8815a92 100644
--- a/src/itrafmon.c
+++ b/src/itrafmon.c
@@ -602,7 +602,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;
@@ -758,6 +758,8 @@ void ipmon(struct OPTIONS *options, struct filterstate *ofilter,
starttime = timeint = closedint = tv.tv_sec;
while (!exitloop) {
+ char ifnamebuf[IFNAMSIZ];
+
gettimeofday(&tv, NULL);
now = tv.tv_sec;
unow = tv.tv_sec * 1e+06 + tv.tv_usec;
@@ -833,7 +835,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)
@@ -1042,11 +1044,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;
+ }
+
ha! this is correct ;)
switch(fromaddr.sll_protocol) {
case ETH_P_IP:
ippacket = (struct iphdr *) packet;
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) {
^^ if *space* (
+ 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 5bfbeaf..ce0fd78 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 912b8e4..9566ecc 100644
--- a/src/serv.c
+++ b/src/serv.c
@@ -700,7 +700,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;
@@ -864,7 +863,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)
goto no_key_ready;
@@ -999,7 +998,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)
--
Nikola