diff options
author | Thomas Habets <thomas@habets.se> | 2012-11-03 16:46:40 +0000 |
---|---|---|
committer | Sam Roberts <vieuxtech@gmail.com> | 2012-11-10 20:34:31 -0800 |
commit | cba0dd86aaffa8d38c265f516c4822f615841bea (patch) | |
tree | 65526b8efe7ee81b69351c3c0a8ed462a83907f4 | |
parent | 2fd3e50d79a84e67bb1bb76b0f6a45f04baff280 (diff) | |
download | libnet-cba0dd86aaffa8d38c265f516c4822f615841bea.tar.gz |
dlpi: Correctly extract the unit number from devices with numbers in their name.
Bug: https://github.com/sam-github/libnet/issues/20
Example:
e1000g0 would be parsed as device "e" unit "1000g0", and then fail.
This fix will treat any trailing digits as the unit number.
-rw-r--r-- | libnet/src/libnet_link_dlpi.c | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/libnet/src/libnet_link_dlpi.c b/libnet/src/libnet_link_dlpi.c index 65c3a46..2bacd2b 100644 --- a/libnet/src/libnet_link_dlpi.c +++ b/libnet/src/libnet_link_dlpi.c @@ -108,6 +108,38 @@ static int get_dlpi_ppa(int, const int8_t *, int, int8_t *); /* XXX Needed by HP-UX (at least) */ static bpf_u_int32 ctlbuf[MAXDLBUF]; +/* Return a pointer to the last character in 'in' that is not in 's', + * or NULL if no such character exists. */ +static char *find_last_not_of(char *in, const char *s) +{ + char* cur; + cur = in + strlen(in); + for(; cur != in; cur--) { + if (!strchr(s, *cur)) { + break; + } + } + return cur == in ? NULL : cur; +} + +/* For a given device name, return the trailing number, called unit number. */ +static char *dlpi_unit(char *dev) +{ + char* ret; + if (!*dev) { + return NULL; + } + ret = find_last_not_of(dev, "0123456789"); + if (!ret) { + ret = dev; + } else { + ret++; + if (!*ret) { + return NULL; + } + } + return ret; +} int libnet_open_link(libnet_t *l) @@ -130,7 +162,7 @@ libnet_open_link(libnet_t *l) /* * Determine device and ppa */ - cp = strpbrk(l->device, "0123456789"); + cp = dlpi_unit(l->device); if (cp == NULL) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, @@ -182,7 +214,7 @@ libnet_open_link(libnet_t *l) * Try device without unit number */ strcpy(dname2, dname); - cp = strchr(dname, *cp); + cp = dlpi_unit(dname); *cp = '\0'; l->fd = open(dname, O_RDWR); |