aboutsummaryrefslogtreecommitdiff
path: root/sys/netgraph/ng_ether.c
diff options
context:
space:
mode:
authorArchie Cobbs <archie@FreeBSD.org>2000-08-15 01:05:50 +0000
committerArchie Cobbs <archie@FreeBSD.org>2000-08-15 01:05:50 +0000
commit56045c6673062b0af52a25b4075e27f45522be3c (patch)
treec725ad83bf8f23f0522574fdd23b96c76f892124 /sys/netgraph/ng_ether.c
parent11572abf626ca2987b18a6bf2335445be4b294a0 (diff)
downloadsrc-56045c6673062b0af52a25b4075e27f45522be3c.tar.gz
src-56045c6673062b0af52a25b4075e27f45522be3c.zip
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.
Notes
Notes: svn path=/head/; revision=64653
Diffstat (limited to 'sys/netgraph/ng_ether.c')
-rw-r--r--sys/netgraph/ng_ether.c108
1 files changed, 99 insertions, 9 deletions
diff --git a/sys/netgraph/ng_ether.c b/sys/netgraph/ng_ether.c
index 10ad2ddf4ff9..1b2b9cca6496 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
******************************************************************/