diff options
author | archie <archie@FreeBSD.org> | 2000-08-15 01:05:50 +0000 |
---|---|---|
committer | archie <archie@FreeBSD.org> | 2000-08-15 01:05:50 +0000 |
commit | d826d6c208f3cdd33a7a9e1b9f534515a595be56 (patch) | |
tree | 930f7a36c9bdd683848c0790d1a10160a35acf51 /sys | |
parent | 99a91bd0c26b2f7b5c04ac078ddedd9550f164e8 (diff) | |
download | FreeBSD-src-d826d6c208f3cdd33a7a9e1b9f534515a595be56.zip FreeBSD-src-d826d6c208f3cdd33a7a9e1b9f534515a595be56.tar.gz |
Add three more control messages to complement their opposites:
NGM_ETHER_SET_ENADDR, NGM_ETHER_GET_PROMISC, and NGM_ETHER_GET_AUTOSRC.
Alter parsing algorithm so the EN address really looks like one.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/netgraph/ng_ether.c | 108 | ||||
-rw-r--r-- | sys/netgraph/ng_ether.h | 5 |
2 files changed, 103 insertions, 10 deletions
diff --git a/sys/netgraph/ng_ether.c b/sys/netgraph/ng_ether.c index 10ad2dd..1b2b9cc 100644 --- a/sys/netgraph/ng_ether.c +++ b/sys/netgraph/ng_ether.c @@ -104,15 +104,17 @@ static ng_rcvdata_t ng_ether_rcvdata; static ng_disconnect_t ng_ether_disconnect; static int ng_ether_mod_event(module_t mod, int event, void *data); -/* Parse type for an Ethernet address. Slightly better than an array of - six hint8's would be the more common colon-separated hex byte format. */ -static const struct ng_parse_fixedarray_info ng_ether_enaddr_type_info = { - &ng_parse_hint8_type, - ETHER_ADDR_LEN -}; -static const struct ng_parse_type ng_ether_enaddr_type = { - &ng_parse_fixedarray_type, - &ng_ether_enaddr_type_info +/* Parse type for an Ethernet address */ +static ng_parse_t ng_enaddr_parse; +static ng_unparse_t ng_enaddr_unparse; +const struct ng_parse_type ng_ether_enaddr_type = { + NULL, + NULL, + NULL, + ng_enaddr_parse, + ng_enaddr_unparse, + NULL, /* no such thing as a "default" EN address */ + 0 }; /* List of commands and how to convert arguments to/from ASCII */ @@ -140,6 +142,20 @@ static const struct ng_cmdlist ng_ether_cmdlist[] = { }, { NGM_ETHER_COOKIE, + NGM_ETHER_SET_ENADDR, + "setenaddr", + &ng_ether_enaddr_type, + NULL + }, + { + NGM_ETHER_COOKIE, + NGM_ETHER_GET_PROMISC, + "getpromisc", + NULL, + &ng_parse_int32_type + }, + { + NGM_ETHER_COOKIE, NGM_ETHER_SET_PROMISC, "setpromisc", &ng_parse_int32_type, @@ -147,6 +163,13 @@ static const struct ng_cmdlist ng_ether_cmdlist[] = { }, { NGM_ETHER_COOKIE, + NGM_ETHER_GET_AUTOSRC, + "getautosrc", + NULL, + &ng_parse_int32_type + }, + { + NGM_ETHER_COOKIE, NGM_ETHER_SET_AUTOSRC, "setautosrc", &ng_parse_int32_type, @@ -498,6 +521,24 @@ ng_ether_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, bcopy((IFP2AC(priv->ifp))->ac_enaddr, resp->data, ETHER_ADDR_LEN); break; + case NGM_ETHER_SET_ENADDR: + { + if (msg->header.arglen != ETHER_ADDR_LEN) { + error = EINVAL; + break; + } + error = if_setlladdr(priv->ifp, + (u_char *)msg->data, ETHER_ADDR_LEN); + break; + } + case NGM_ETHER_GET_PROMISC: + NG_MKRESPONSE(resp, msg, sizeof(u_int32_t), M_NOWAIT); + if (resp == NULL) { + error = ENOMEM; + break; + } + *((u_int32_t *)resp->data) = priv->promisc; + break; case NGM_ETHER_SET_PROMISC: { u_char want; @@ -514,6 +555,14 @@ ng_ether_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, } break; } + case NGM_ETHER_GET_AUTOSRC: + NG_MKRESPONSE(resp, msg, sizeof(u_int32_t), M_NOWAIT); + if (resp == NULL) { + error = ENOMEM; + break; + } + *((u_int32_t *)resp->data) = priv->autoSrcAddr; + break; case NGM_ETHER_SET_AUTOSRC: if (msg->header.arglen != sizeof(u_int32_t)) { error = EINVAL; @@ -651,6 +700,47 @@ ng_ether_disconnect(hook_p hook) return (0); } +static int +ng_enaddr_parse(const struct ng_parse_type *type, + const char *s, int *const off, const u_char *const start, + u_char *const buf, int *const buflen) +{ + char *eptr; + u_long val; + int i; + + if (*buflen < ETHER_ADDR_LEN) + return (ERANGE); + for (i = 0; i < ETHER_ADDR_LEN; i++) { + val = strtoul(s + *off, &eptr, 16); + if (val > 0xff || eptr == s + *off) + return (EINVAL); + buf[i] = (u_char)val; + *off = (eptr - s); + if (i < ETHER_ADDR_LEN - 1) { + if (*eptr != ':') + return (EINVAL); + (*off)++; + } + } + *buflen = ETHER_ADDR_LEN; + return (0); +} + +static int +ng_enaddr_unparse(const struct ng_parse_type *type, + const u_char *data, int *off, char *cbuf, int cbuflen) +{ + int len; + + len = snprintf(cbuf, cbuflen, "%02x:%02x:%02x:%02x:%02x:%02x", + data[0], data[1], data[2], data[3], data[4], data[5]); + if (len >= cbuflen) + return (ERANGE); + *off += ETHER_ADDR_LEN; + return (0); +} + /****************************************************************** INITIALIZATION ******************************************************************/ diff --git a/sys/netgraph/ng_ether.h b/sys/netgraph/ng_ether.h index c8cbf1f..1d20b64 100644 --- a/sys/netgraph/ng_ether.h +++ b/sys/netgraph/ng_ether.h @@ -45,7 +45,7 @@ /* Node type name and magic cookie */ #define NG_ETHER_NODE_TYPE "ether" -#define NGM_ETHER_COOKIE 917786905 +#define NGM_ETHER_COOKIE 917786906 /* Hook names */ #define NG_ETHER_HOOK_LOWER "lower" /* connection to raw device */ @@ -58,7 +58,10 @@ enum { NGM_ETHER_GET_IFNAME = 1, /* get the interface name */ NGM_ETHER_GET_IFINDEX, /* get the interface global index # */ NGM_ETHER_GET_ENADDR, /* get Ethernet address */ + NGM_ETHER_SET_ENADDR, /* set Ethernet address */ + NGM_ETHER_GET_PROMISC, /* get node's promiscuous mode bit */ NGM_ETHER_SET_PROMISC, /* enable/disable promiscuous mode */ + NGM_ETHER_GET_AUTOSRC, /* get source address override */ NGM_ETHER_SET_AUTOSRC, /* enable/disable src addr override */ }; |