summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Habets <thomas@habets.se>2012-11-03 16:46:40 +0000
committerSam Roberts <vieuxtech@gmail.com>2012-11-10 20:34:31 -0800
commitcba0dd86aaffa8d38c265f516c4822f615841bea (patch)
tree65526b8efe7ee81b69351c3c0a8ed462a83907f4
parent2fd3e50d79a84e67bb1bb76b0f6a45f04baff280 (diff)
downloadlibnet-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.c36
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);