138451Smsmith/*	$NetBSD: ether.c,v 1.11 1997/07/07 15:52:50 drochner Exp $	*/
238451Smsmith
338451Smsmith/*
438451Smsmith * Copyright (c) 1992 Regents of the University of California.
538451Smsmith * All rights reserved.
638451Smsmith *
738451Smsmith * This software was developed by the Computer Systems Engineering group
838451Smsmith * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
938451Smsmith * contributed to Berkeley.
1038451Smsmith *
1138451Smsmith * Redistribution and use in source and binary forms, with or without
1238451Smsmith * modification, are permitted provided that the following conditions
1338451Smsmith * are met:
1438451Smsmith * 1. Redistributions of source code must retain the above copyright
1538451Smsmith *    notice, this list of conditions and the following disclaimer.
1638451Smsmith * 2. Redistributions in binary form must reproduce the above copyright
1738451Smsmith *    notice, this list of conditions and the following disclaimer in the
1838451Smsmith *    documentation and/or other materials provided with the distribution.
1938451Smsmith * 4. Neither the name of the University nor the names of its contributors
2038451Smsmith *    may be used to endorse or promote products derived from this software
2138451Smsmith *    without specific prior written permission.
2238451Smsmith *
2338451Smsmith * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2438451Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2538451Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2638451Smsmith * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2738451Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2838451Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2938451Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3038451Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3138451Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3238451Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3338451Smsmith * SUCH DAMAGE.
3438451Smsmith *
3538451Smsmith * @(#) Header: net.c,v 1.9 93/08/06 19:32:15 leres Exp  (LBL)
3638451Smsmith */
3738451Smsmith
3884221Sdillon#include <sys/cdefs.h>
3984221Sdillon__FBSDID("$FreeBSD: stable/11/stand/libsa/ether.c 329132 2018-02-11 19:51:29Z kevans $");
4084221Sdillon
4138451Smsmith#include <sys/param.h>
4238451Smsmith#include <sys/socket.h>
4338451Smsmith#include <string.h>
4438451Smsmith
4538451Smsmith#include <net/if.h>
4638451Smsmith#include <netinet/in.h>
4738451Smsmith#include <netinet/if_ether.h>
4838451Smsmith#include <netinet/in_systm.h>
4938451Smsmith#include <netinet/ip.h>
5038451Smsmith
5138451Smsmith#include "stand.h"
5238451Smsmith#include "net.h"
5338451Smsmith#include "netif.h"
5438451Smsmith
5538451Smsmith/* Caller must leave room for ethernet header in front!! */
5638451Smsmithssize_t
57329100Skevanssendether(struct iodesc *d, void *pkt, size_t len, uint8_t *dea, int etype)
5838451Smsmith{
5992913Sobrien	ssize_t n;
6092913Sobrien	struct ether_header *eh;
6138451Smsmith
6238451Smsmith#ifdef ETHER_DEBUG
6338451Smsmith 	if (debug)
6438451Smsmith		printf("sendether: called\n");
6538451Smsmith#endif
6638451Smsmith
6738451Smsmith	eh = (struct ether_header *)pkt - 1;
6838451Smsmith	len += sizeof(*eh);
6938451Smsmith
7038451Smsmith	MACPY(d->myea, eh->ether_shost);		/* by byte */
7138451Smsmith	MACPY(dea, eh->ether_dhost);			/* by byte */
7238451Smsmith	eh->ether_type = htons(etype);
7338451Smsmith
7438451Smsmith	n = netif_put(d, eh, len);
7538451Smsmith	if (n == -1 || n < sizeof(*eh))
7638451Smsmith		return (-1);
7738451Smsmith
7838451Smsmith	n -= sizeof(*eh);
7938451Smsmith	return (n);
8038451Smsmith}
8138451Smsmith
8238451Smsmith/*
8338451Smsmith * Get a packet of any Ethernet type, with our address or
84329100Skevans * the broadcast address.  Save the Ether type in etype.
85329100Skevans * Unless there is an error, we pass the whole packet and the unencapsulated
86329100Skevans * data.
8738451Smsmith */
8838451Smsmithssize_t
89329100Skevansreadether(struct iodesc *d, void **pkt, void **payload, time_t tleft,
90329100Skevans    uint16_t *etype)
9138451Smsmith{
9292913Sobrien	ssize_t n;
9392913Sobrien	struct ether_header *eh;
94329100Skevans	void *ptr;
9538451Smsmith
9638451Smsmith#ifdef ETHER_DEBUG
9738451Smsmith 	if (debug)
9838451Smsmith		printf("readether: called\n");
9938451Smsmith#endif
10038451Smsmith
101329100Skevans	ptr = NULL;
102329100Skevans	n = netif_get(d, &ptr, tleft);
103329100Skevans	if (n == -1 || n < sizeof(*eh)) {
104329100Skevans		free(ptr);
10538451Smsmith		return (-1);
106329100Skevans	}
10738451Smsmith
108329100Skevans	eh = (struct ether_header *)((uintptr_t)ptr + ETHER_ALIGN);
10938451Smsmith	/* Validate Ethernet address. */
11038451Smsmith	if (bcmp(d->myea, eh->ether_dhost, 6) != 0 &&
11138451Smsmith	    bcmp(bcea, eh->ether_dhost, 6) != 0) {
11238451Smsmith#ifdef ETHER_DEBUG
11338451Smsmith		if (debug)
11438451Smsmith			printf("readether: not ours (ea=%s)\n",
11538451Smsmith			    ether_sprintf(eh->ether_dhost));
11638451Smsmith#endif
117329100Skevans		free(ptr);
11838451Smsmith		return (-1);
11938451Smsmith	}
120329100Skevans
121329100Skevans	*pkt = ptr;
122329100Skevans	*payload = (void *)((uintptr_t)eh + sizeof(*eh));
12338451Smsmith	*etype = ntohs(eh->ether_type);
12438451Smsmith
12538451Smsmith	n -= sizeof(*eh);
12638451Smsmith	return (n);
12738451Smsmith}
12838451Smsmith
12938451Smsmith/*
13038451Smsmith * Convert Ethernet address to printable (loggable) representation.
13138451Smsmith */
13238451Smsmithstatic char digits[] = "0123456789abcdef";
13338451Smsmithchar *
134329100Skevansether_sprintf(u_char *ap)
13538451Smsmith{
13692913Sobrien	int i;
13738451Smsmith	static char etherbuf[18];
13892913Sobrien	char *cp = etherbuf;
13938451Smsmith
14038451Smsmith	for (i = 0; i < 6; i++) {
14138451Smsmith		*cp++ = digits[*ap >> 4];
14238451Smsmith		*cp++ = digits[*ap++ & 0xf];
14338451Smsmith		*cp++ = ':';
14438451Smsmith	}
14538451Smsmith	*--cp = 0;
14638451Smsmith	return (etherbuf);
14738451Smsmith}
148