Deleted Added
sdiff udiff text old ( 63543 ) new ( 64358 )
full compact
1
2/*
3 * ng_ether.c
4 *
5 * Copyright (c) 1996-2000 Whistle Communications, Inc.
6 * All rights reserved.
7 *
8 * Subject to the following obligations and disclaimer of warranty, use and

--- 23 unchanged lines hidden (view full) ---

32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34 * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
35 * OF SUCH DAMAGE.
36 *
37 * Authors: Archie Cobbs <archie@freebsd.org>
38 * Julian Elischer <julian@freebsd.org>
39 *
40 * $FreeBSD: head/sys/netgraph/ng_ether.c 64358 2000-08-07 18:52:26Z archie $
41 */
42
43/*
44 * ng_ether(4) netgraph node type
45 */
46
47#include <sys/param.h>
48#include <sys/systm.h>

--- 19 unchanged lines hidden (view full) ---

68#define IFP2NG(ifp) ((struct ng_node *)((struct arpcom *)(ifp))->ac_netgraph)
69
70/* Per-node private data */
71struct private {
72 struct ifnet *ifp; /* associated interface */
73 hook_p upper; /* upper hook connection */
74 hook_p lower; /* lower OR orphan hook connection */
75 u_char lowerOrphan; /* whether lower is lower or orphan */
76 u_char autoSrcAddr; /* always overwrite source address */
77 u_char promisc; /* promiscuous mode enabled */
78};
79typedef struct private *priv_p;
80
81/* Functional hooks called from if_ethersubr.c */
82static void ng_ether_input(struct ifnet *ifp,
83 struct mbuf **mp, struct ether_header *eh);
84static void ng_ether_input_orphan(struct ifnet *ifp,
85 struct mbuf *m, struct ether_header *eh);

--- 13 unchanged lines hidden (view full) ---

99static ng_constructor_t ng_ether_constructor;
100static ng_rcvmsg_t ng_ether_rcvmsg;
101static ng_shutdown_t ng_ether_rmnode;
102static ng_newhook_t ng_ether_newhook;
103static ng_rcvdata_t ng_ether_rcvdata;
104static ng_disconnect_t ng_ether_disconnect;
105static int ng_ether_mod_event(module_t mod, int event, void *data);
106
107/* Parse type for an Ethernet address. Slightly better than an array of
108 six int8's would be the more common colon-separated hex byte format. */
109static const struct ng_parse_fixedarray_info ng_ether_enaddr_type_info = {
110 &ng_parse_int8_type,
111 ETHER_ADDR_LEN
112};
113static const struct ng_parse_type ng_ether_enaddr_type = {
114 &ng_parse_fixedarray_type,
115 &ng_ether_enaddr_type_info
116};
117
118/* List of commands and how to convert arguments to/from ASCII */
119static const struct ng_cmdlist ng_ether_cmdlist[] = {
120 {
121 NGM_ETHER_COOKIE,
122 NGM_ETHER_GET_IFNAME,
123 "getifname",
124 NULL,
125 &ng_parse_string_type
126 },
127 {
128 NGM_ETHER_COOKIE,
129 NGM_ETHER_GET_IFINDEX,
130 "getifindex",
131 NULL,
132 &ng_parse_int32_type
133 },
134 {
135 NGM_ETHER_COOKIE,
136 NGM_ETHER_GET_ENADDR,
137 "getenaddr",
138 NULL,
139 &ng_ether_enaddr_type
140 },
141 {
142 NGM_ETHER_COOKIE,
143 NGM_ETHER_SET_PROMISC,
144 "setpromisc",
145 &ng_parse_int32_type,
146 NULL
147 },
148 {
149 NGM_ETHER_COOKIE,
150 NGM_ETHER_SET_AUTOSRC,
151 "setautosrc",
152 &ng_parse_int32_type,
153 NULL
154 },
155 { 0 }
156};
157
158static struct ng_type ng_ether_typestruct = {
159 NG_VERSION,
160 NG_ETHER_NODE_TYPE,
161 ng_ether_mod_event,
162 ng_ether_constructor,

--- 132 unchanged lines hidden (view full) ---

295 __FUNCTION__, "allocate memory", name);
296 ng_unref(node);
297 return;
298 }
299 bzero(priv, sizeof(*priv));
300 node->private = priv;
301 priv->ifp = ifp;
302 IFP2NG(ifp) = node;
303 priv->autoSrcAddr = 1;
304
305 /* Try to give the node the same name as the interface */
306 if (ng_name_node(node, name) != 0) {
307 log(LOG_WARNING, "%s: can't name node %s\n",
308 __FUNCTION__, name);
309 }
310}
311

--- 172 unchanged lines hidden (view full) ---

484 case NGM_ETHER_GET_IFINDEX:
485 NG_MKRESPONSE(resp, msg, sizeof(u_int32_t), M_NOWAIT);
486 if (resp == NULL) {
487 error = ENOMEM;
488 break;
489 }
490 *((u_int32_t *)resp->data) = priv->ifp->if_index;
491 break;
492 case NGM_ETHER_GET_ENADDR:
493 NG_MKRESPONSE(resp, msg, ETHER_ADDR_LEN, M_NOWAIT);
494 if (resp == NULL) {
495 error = ENOMEM;
496 break;
497 }
498 bcopy((IFP2AC(priv->ifp))->ac_enaddr,
499 resp->data, ETHER_ADDR_LEN);
500 break;
501 case NGM_ETHER_SET_PROMISC:
502 {
503 u_char want;
504
505 if (msg->header.arglen != sizeof(u_int32_t)) {
506 error = EINVAL;
507 break;
508 }
509 want = !!*((u_int32_t *)msg->data);
510 if (want ^ priv->promisc) {
511 if ((error = ifpromisc(priv->ifp, want)) != 0)
512 break;
513 priv->promisc = want;
514 }
515 break;
516 }
517 case NGM_ETHER_SET_AUTOSRC:
518 if (msg->header.arglen != sizeof(u_int32_t)) {
519 error = EINVAL;
520 break;
521 }
522 priv->autoSrcAddr = !!*((u_int32_t *)msg->data);
523 break;
524 default:
525 error = EINVAL;
526 break;
527 }
528 break;
529 default:
530 error = EINVAL;
531 break;

--- 25 unchanged lines hidden (view full) ---

557
558/*
559 * Handle an mbuf received on the "lower" hook.
560 */
561static int
562ng_ether_rcv_lower(node_p node, struct mbuf *m, meta_p meta)
563{
564 const priv_p priv = node->private;
565
566 /* Make sure header is fully pulled up */
567 if (m->m_pkthdr.len < sizeof(struct ether_header)) {
568 NG_FREE_DATA(m, meta);
569 return (EINVAL);
570 }
571 if (m->m_len < sizeof(struct ether_header)
572 && (m = m_pullup(m, sizeof(struct ether_header))) == NULL) {
573 NG_FREE_META(meta);
574 return (ENOBUFS);
575 }
576
577 /* Drop in the MAC address if desired */
578 if (priv->autoSrcAddr) {
579 bcopy((IFP2AC(priv->ifp))->ac_enaddr,
580 mtod(m, struct ether_header *)->ether_shost,
581 ETHER_ADDR_LEN);
582 }
583
584 /* Send it on its way */
585 NG_FREE_META(meta);
586 return ether_output_frame(priv->ifp, m);
587}
588
589/*
590 * Handle an mbuf received on the "upper" hook.

--- 25 unchanged lines hidden (view full) ---

616}
617
618/*
619 * Shutdown node. This resets the node but does not remove it.
620 */
621static int
622ng_ether_rmnode(node_p node)
623{
624 const priv_p priv = node->private;
625
626 ng_cutlinks(node);
627 node->flags &= ~NG_INVALID; /* bounce back to life */
628 if (priv->promisc) { /* disable promiscuous mode */
629 (void)ifpromisc(priv->ifp, 0);
630 priv->promisc = 0;
631 }
632 priv->autoSrcAddr = 1; /* reset auto-src-addr flag */
633 return (0);
634}
635
636/*
637 * Hook disconnection.
638 */
639static int
640ng_ether_disconnect(hook_p hook)

--- 75 unchanged lines hidden ---