Add three new control messages to the ng_ether(4) netgraph node type:
NGM_ETHER_GET_ENADDR: Get the device's Ethernet address NGM_ETHER_SET_PROMISC: Enable/disable promiscuous mode NGM_ETHER_SET_AUTOSRC: Enable/disable packet source address override
This commit is contained in:
parent
d27e361b58
commit
4b39c3c7b3
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=64358
@ -73,6 +73,8 @@ struct private {
|
||||
hook_p upper; /* upper hook connection */
|
||||
hook_p lower; /* lower OR orphan hook connection */
|
||||
u_char lowerOrphan; /* whether lower is lower or orphan */
|
||||
u_char autoSrcAddr; /* always overwrite source address */
|
||||
u_char promisc; /* promiscuous mode enabled */
|
||||
};
|
||||
typedef struct private *priv_p;
|
||||
|
||||
@ -102,6 +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 int8'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_int8_type,
|
||||
ETHER_ADDR_LEN
|
||||
};
|
||||
static const struct ng_parse_type ng_ether_enaddr_type = {
|
||||
&ng_parse_fixedarray_type,
|
||||
&ng_ether_enaddr_type_info
|
||||
};
|
||||
|
||||
/* List of commands and how to convert arguments to/from ASCII */
|
||||
static const struct ng_cmdlist ng_ether_cmdlist[] = {
|
||||
{
|
||||
@ -118,6 +131,27 @@ static const struct ng_cmdlist ng_ether_cmdlist[] = {
|
||||
NULL,
|
||||
&ng_parse_int32_type
|
||||
},
|
||||
{
|
||||
NGM_ETHER_COOKIE,
|
||||
NGM_ETHER_GET_ENADDR,
|
||||
"getenaddr",
|
||||
NULL,
|
||||
&ng_ether_enaddr_type
|
||||
},
|
||||
{
|
||||
NGM_ETHER_COOKIE,
|
||||
NGM_ETHER_SET_PROMISC,
|
||||
"setpromisc",
|
||||
&ng_parse_int32_type,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
NGM_ETHER_COOKIE,
|
||||
NGM_ETHER_SET_AUTOSRC,
|
||||
"setautosrc",
|
||||
&ng_parse_int32_type,
|
||||
NULL
|
||||
},
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
@ -266,6 +300,7 @@ ng_ether_attach(struct ifnet *ifp)
|
||||
node->private = priv;
|
||||
priv->ifp = ifp;
|
||||
IFP2NG(ifp) = node;
|
||||
priv->autoSrcAddr = 1;
|
||||
|
||||
/* Try to give the node the same name as the interface */
|
||||
if (ng_name_node(node, name) != 0) {
|
||||
@ -454,6 +489,38 @@ ng_ether_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr,
|
||||
}
|
||||
*((u_int32_t *)resp->data) = priv->ifp->if_index;
|
||||
break;
|
||||
case NGM_ETHER_GET_ENADDR:
|
||||
NG_MKRESPONSE(resp, msg, ETHER_ADDR_LEN, M_NOWAIT);
|
||||
if (resp == NULL) {
|
||||
error = ENOMEM;
|
||||
break;
|
||||
}
|
||||
bcopy((IFP2AC(priv->ifp))->ac_enaddr,
|
||||
resp->data, ETHER_ADDR_LEN);
|
||||
break;
|
||||
case NGM_ETHER_SET_PROMISC:
|
||||
{
|
||||
u_char want;
|
||||
|
||||
if (msg->header.arglen != sizeof(u_int32_t)) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
want = !!*((u_int32_t *)msg->data);
|
||||
if (want ^ priv->promisc) {
|
||||
if ((error = ifpromisc(priv->ifp, want)) != 0)
|
||||
break;
|
||||
priv->promisc = want;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NGM_ETHER_SET_AUTOSRC:
|
||||
if (msg->header.arglen != sizeof(u_int32_t)) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
priv->autoSrcAddr = !!*((u_int32_t *)msg->data);
|
||||
break;
|
||||
default:
|
||||
error = EINVAL;
|
||||
break;
|
||||
@ -495,7 +562,6 @@ static int
|
||||
ng_ether_rcv_lower(node_p node, struct mbuf *m, meta_p meta)
|
||||
{
|
||||
const priv_p priv = node->private;
|
||||
struct ether_header *eh;
|
||||
|
||||
/* Make sure header is fully pulled up */
|
||||
if (m->m_pkthdr.len < sizeof(struct ether_header)) {
|
||||
@ -508,9 +574,12 @@ ng_ether_rcv_lower(node_p node, struct mbuf *m, meta_p meta)
|
||||
return (ENOBUFS);
|
||||
}
|
||||
|
||||
/* drop in the MAC address */
|
||||
eh = mtod(m, struct ether_header *);
|
||||
bcopy((IFP2AC(priv->ifp))->ac_enaddr, eh->ether_shost, 6);
|
||||
/* Drop in the MAC address if desired */
|
||||
if (priv->autoSrcAddr) {
|
||||
bcopy((IFP2AC(priv->ifp))->ac_enaddr,
|
||||
mtod(m, struct ether_header *)->ether_shost,
|
||||
ETHER_ADDR_LEN);
|
||||
}
|
||||
|
||||
/* Send it on its way */
|
||||
NG_FREE_META(meta);
|
||||
@ -552,8 +621,15 @@ ng_ether_rcv_upper(node_p node, struct mbuf *m, meta_p meta)
|
||||
static int
|
||||
ng_ether_rmnode(node_p node)
|
||||
{
|
||||
const priv_p priv = node->private;
|
||||
|
||||
ng_cutlinks(node);
|
||||
node->flags &= ~NG_INVALID; /* bounce back to life */
|
||||
if (priv->promisc) { /* disable promiscuous mode */
|
||||
(void)ifpromisc(priv->ifp, 0);
|
||||
priv->promisc = 0;
|
||||
}
|
||||
priv->autoSrcAddr = 1; /* reset auto-src-addr flag */
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -57,6 +57,9 @@
|
||||
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_PROMISC, /* enable/disable promiscuous mode */
|
||||
NGM_ETHER_SET_AUTOSRC, /* enable/disable src addr override */
|
||||
};
|
||||
|
||||
#endif /* _NETGRAPH_NG_ETHER_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user