/* $NetBSD: ether.c,v 1.11 1997/07/07 15:52:50 drochner Exp $ */12/*3* Copyright (c) 1992 Regents of the University of California.4* All rights reserved.5*6* This software was developed by the Computer Systems Engineering group7* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and8* contributed to Berkeley.9*10* Redistribution and use in source and binary forms, with or without11* modification, are permitted provided that the following conditions12* are met:13* 1. Redistributions of source code must retain the above copyright14* notice, this list of conditions and the following disclaimer.15* 2. Redistributions in binary form must reproduce the above copyright16* notice, this list of conditions and the following disclaimer in the17* documentation and/or other materials provided with the distribution.18* 3. Neither the name of the University nor the names of its contributors19* may be used to endorse or promote products derived from this software20* without specific prior written permission.21*22* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND23* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE24* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE25* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE26* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL27* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS28* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)29* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT30* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY31* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF32* SUCH DAMAGE.33*/3435#include <sys/param.h>36#include <sys/socket.h>37#include <string.h>3839#include <net/if.h>40#include <netinet/in.h>41#include <netinet/if_ether.h>42#include <netinet/in_systm.h>43#include <netinet/ip.h>4445#include "stand.h"46#include "net.h"47#include "netif.h"4849/* Caller must leave room for ethernet header in front!! */50ssize_t51sendether(struct iodesc *d, void *pkt, size_t len, uint8_t *dea, int etype)52{53ssize_t n;54struct ether_header *eh;5556#ifdef ETHER_DEBUG57if (debug)58printf("sendether: called\n");59#endif6061eh = (struct ether_header *)pkt - 1;62len += sizeof(*eh);6364MACPY(d->myea, eh->ether_shost); /* by byte */65MACPY(dea, eh->ether_dhost); /* by byte */66eh->ether_type = htons(etype);6768n = netif_put(d, eh, len);69if (n == -1 || n < sizeof(*eh))70return (-1);7172n -= sizeof(*eh);73return (n);74}7576/*77* Get a packet of any Ethernet type, with our address or78* the broadcast address. Save the Ether type in etype.79* Unless there is an error, we pass the whole packet and the unencapsulated80* data.81*/82ssize_t83readether(struct iodesc *d, void **pkt, void **payload, time_t tleft,84uint16_t *etype)85{86ssize_t n;87struct ether_header *eh;88void *ptr;8990#ifdef ETHER_DEBUG91if (debug)92printf("readether: called\n");93#endif9495ptr = NULL;96n = netif_get(d, &ptr, tleft);97if (n == -1 || n < sizeof(*eh)) {98free(ptr);99return (-1);100}101102eh = (struct ether_header *)((uintptr_t)ptr + ETHER_ALIGN);103/* Validate Ethernet address. */104if (bcmp(d->myea, eh->ether_dhost, 6) != 0 &&105bcmp(bcea, eh->ether_dhost, 6) != 0) {106#ifdef ETHER_DEBUG107if (debug)108printf("readether: not ours (ea=%s)\n",109ether_sprintf(eh->ether_dhost));110#endif111free(ptr);112return (-1);113}114115*pkt = ptr;116*payload = (void *)((uintptr_t)eh + sizeof(*eh));117*etype = ntohs(eh->ether_type);118119n -= sizeof(*eh);120return (n);121}122123/*124* Convert Ethernet address to printable (loggable) representation.125*/126static char digits[] = "0123456789abcdef";127char *128ether_sprintf(u_char *ap)129{130int i;131static char etherbuf[18];132char *cp = etherbuf;133134for (i = 0; i < 6; i++) {135*cp++ = digits[*ap >> 4];136*cp++ = digits[*ap++ & 0xf];137*cp++ = ':';138}139*--cp = 0;140return (etherbuf);141}142143144