From 4279a8389736181b99fe846e1994aa822d4da980 Mon Sep 17 00:00:00 2001 From: dyoung Date: Mon, 12 May 2008 00:39:18 +0000 Subject: [PATCH] Add code for parsing link-layer addresses of the form xx:xx:...:xx. --- sbin/ifconfig/parse.c | 70 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/sbin/ifconfig/parse.c b/sbin/ifconfig/parse.c index c31ee69cb8f9..9b3de516c6aa 100644 --- a/sbin/ifconfig/parse.c +++ b/sbin/ifconfig/parse.c @@ -1,4 +1,4 @@ -/* $NetBSD: parse.c,v 1.5 2008/05/09 20:48:59 dyoung Exp $ */ +/* $NetBSD: parse.c,v 1.6 2008/05/12 00:39:18 dyoung Exp $ */ /*- * Copyright (c)2008 David Young. All rights reserved. @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -216,6 +217,66 @@ pinteger_match(const struct parser *p, const struct match *im, struct match *om, return 0; } +static int +parse_linkaddr(const char *addr, struct sockaddr_storage *ss) +{ + static const size_t maxlen = + sizeof(*ss) - offsetof(struct sockaddr_dl, sdl_data[0]); + enum { + LLADDR_S_INITIAL = 0, + LLADDR_S_ONE_OCTET, + LLADDR_S_TWO_OCTETS, + LLADDR_S_COLON + } state = LLADDR_S_INITIAL; + uint8_t octet = 0, val; + struct sockaddr_dl *sdl; + const char *p; + int i; + + memset(ss, 0, sizeof(*ss)); + ss->ss_family = AF_LINK; + sdl = (struct sockaddr_dl *)ss; + + for (i = 0, p = addr; i < maxlen; p++) { + if (*p == '\0') { + if (state != LLADDR_S_ONE_OCTET && + state != LLADDR_S_TWO_OCTETS) + return -1; + sdl->sdl_data[i++] = octet; + sdl->sdl_len = + offsetof(struct sockaddr_dl, sdl_data[i]); + return 0; + } + if (*p == ':') { + if (state != LLADDR_S_ONE_OCTET && + state != LLADDR_S_TWO_OCTETS) + return -1; + sdl->sdl_data[i++] = octet; + state = LLADDR_S_COLON; + } + if ('a' <= *p && *p <= 'f') + val = 10 + *p - 'a'; + else if ('A' <= *p && *p <= 'F') + val = 10 + *p - 'A'; + else if ('0' <= *p && *p <= '9') + val = *p - '0'; + else + return -1; + + if (state == LLADDR_S_ONE_OCTET) { + state = LLADDR_S_TWO_OCTETS; + octet <<= 4; + octet |= val; + } else if (state != LLADDR_S_INITIAL && state != LLADDR_S_COLON) + return -1; + else { + state = LLADDR_S_ONE_OCTET; + octet = val; + } + } + return -1; +} + static int paddr_match(const struct parser *p, const struct match *im, struct match *om, int argidx, const char *arg0) @@ -227,6 +288,7 @@ paddr_match(const struct parser *p, const struct match *im, struct match *om, struct sockaddr_at sat; struct sockaddr_iso siso; struct sockaddr_in sin; + struct sockaddr_storage ss; } u; const struct paddr *pa = (const struct paddr *)p; prop_data_t d; @@ -343,6 +405,12 @@ paddr_match(const struct parser *p, const struct match *im, struct match *om, u.siso.siso_addr = *iso_addr(arg0); sa = &u.sa; break; + case AF_LINK: + if (parse_linkaddr(arg0, &u.ss) == -1) + sa = NULL; + else + sa = &u.sa; + break; } if (sa == NULL)