aboutsummaryrefslogtreecommitdiff
path: root/pcap-linux.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2019-08-04 20:25:14 -0700
committerGuy Harris <guy@alum.mit.edu>2019-08-04 20:25:14 -0700
commit7d97bb23a7ecd40bde41385236b9dd5db167afc4 (patch)
tree553559069cf8060537a0d9d9d2a1e126d3695fb9 /pcap-linux.c
parentdd0edaf7eb97c05aff6502056c1e5de9944eb209 (diff)
Clean up the code to parse /proc/net/dev.
Diffstat (limited to 'pcap-linux.c')
-rw-r--r--pcap-linux.c78
1 files changed, 61 insertions, 17 deletions
diff --git a/pcap-linux.c b/pcap-linux.c
index 6f1eb642..e310d6b7 100644
--- a/pcap-linux.c
+++ b/pcap-linux.c
@@ -1178,17 +1178,16 @@ static long int
linux_if_drops(const char * if_name)
{
char buffer[512];
- char * bufptr;
- FILE * file;
+ FILE *file;
+ char *bufptr, *nameptr, *colonptr;
int field_to_convert = 3;
- size_t if_name_sz = strlen(if_name);
long int dropped_pkts = 0;
file = fopen("/proc/net/dev", "r");
if (!file)
return 0;
- while (!dropped_pkts && fgets( buffer, sizeof(buffer), file ))
+ while (fgets(buffer, sizeof(buffer), file) != NULL)
{
/* search for 'bytes' -- if its in there, then
that means we need to grab the fourth field. otherwise
@@ -1199,26 +1198,71 @@ linux_if_drops(const char * if_name)
continue;
}
- /* find iface and make sure it actually matches -- space before the name and : after it */
- if ((bufptr = strstr(buffer, if_name)) &&
- (bufptr == buffer || *(bufptr-1) == ' ') &&
- *(bufptr + if_name_sz) == ':')
+ /*
+ * See whether this line corresponds to this device.
+ * The line should have zero or more leading blanks,
+ * followed by a device name, followed by a colon,
+ * followed by the statistics.
+ */
+ bufptr = buffer;
+ /* Skip leading blanks */
+ while (*bufptr == ' ')
+ bufptr++;
+ nameptr = bufptr;
+ /* Look for the colon */
+ colonptr = strchr(nameptr, ':');
+ if (colonptr == NULL)
+ {
+ /*
+ * Not found; this could, for example, be the
+ * header line.
+ */
+ continue;
+ }
+ /* Null-terminate the interface name. */
+ *colonptr = '\0';
+ if (strcmp(if_name, nameptr) == 0)
{
- bufptr = bufptr + if_name_sz + 1;
+ /*
+ * OK, this line has the statistics for the interface.
+ * Skip past the interface name.
+ */
+ bufptr = colonptr + 1;
/* grab the nth field from it */
- while( --field_to_convert && *bufptr != '\0')
+ while (--field_to_convert && *bufptr != '\0')
{
- while (*bufptr != '\0' && *(bufptr++) == ' ');
- while (*bufptr != '\0' && *(bufptr++) != ' ');
- }
+ /*
+ * This isn't the field we want.
+ * First, skip any leading blanks before
+ * the field.
+ */
+ while (*bufptr == ' ')
+ bufptr++;
- /* get rid of any final spaces */
- while (*bufptr != '\0' && *bufptr == ' ') bufptr++;
+ /*
+ * Now skip the non-blank characters of
+ * the field.
+ */
+ while (*bufptr != '\0' && *bufptr != ' ')
+ bufptr++;
+ }
- if (*bufptr != '\0')
- dropped_pkts = strtol(bufptr, NULL, 10);
+ if (field_to_convert == 0)
+ {
+ /*
+ * We've found the field we want.
+ * Skip any leading blanks before it.
+ */
+ while (*bufptr == ' ')
+ bufptr++;
+ /*
+ * Now extract the value, if we have one.
+ */
+ if (*bufptr != '\0')
+ dropped_pkts = strtol(bufptr, NULL, 10);
+ }
break;
}
}