14a5d661aSToomas Soome /* $NetBSD: ether.c,v 1.11 1997/07/07 15:52:50 drochner Exp $ */ 24a5d661aSToomas Soome 34a5d661aSToomas Soome /* 44a5d661aSToomas Soome * Copyright (c) 1992 Regents of the University of California. 54a5d661aSToomas Soome * All rights reserved. 64a5d661aSToomas Soome * 74a5d661aSToomas Soome * This software was developed by the Computer Systems Engineering group 84a5d661aSToomas Soome * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 94a5d661aSToomas Soome * contributed to Berkeley. 104a5d661aSToomas Soome * 114a5d661aSToomas Soome * Redistribution and use in source and binary forms, with or without 124a5d661aSToomas Soome * modification, are permitted provided that the following conditions 134a5d661aSToomas Soome * are met: 144a5d661aSToomas Soome * 1. Redistributions of source code must retain the above copyright 154a5d661aSToomas Soome * notice, this list of conditions and the following disclaimer. 164a5d661aSToomas Soome * 2. Redistributions in binary form must reproduce the above copyright 174a5d661aSToomas Soome * notice, this list of conditions and the following disclaimer in the 184a5d661aSToomas Soome * documentation and/or other materials provided with the distribution. 194a5d661aSToomas Soome * 4. Neither the name of the University nor the names of its contributors 204a5d661aSToomas Soome * may be used to endorse or promote products derived from this software 214a5d661aSToomas Soome * without specific prior written permission. 224a5d661aSToomas Soome * 234a5d661aSToomas Soome * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 244a5d661aSToomas Soome * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 254a5d661aSToomas Soome * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 264a5d661aSToomas Soome * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 274a5d661aSToomas Soome * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 284a5d661aSToomas Soome * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 294a5d661aSToomas Soome * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 304a5d661aSToomas Soome * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 314a5d661aSToomas Soome * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 324a5d661aSToomas Soome * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 334a5d661aSToomas Soome * SUCH DAMAGE. 344a5d661aSToomas Soome * 354a5d661aSToomas Soome * @(#) Header: net.c,v 1.9 93/08/06 19:32:15 leres Exp (LBL) 364a5d661aSToomas Soome */ 374a5d661aSToomas Soome 384a5d661aSToomas Soome #include <sys/cdefs.h> 394a5d661aSToomas Soome 404a5d661aSToomas Soome #include <sys/param.h> 414a5d661aSToomas Soome #include <sys/socket.h> 424a5d661aSToomas Soome #include <string.h> 434a5d661aSToomas Soome 444a5d661aSToomas Soome #include <net/if.h> 454a5d661aSToomas Soome #include <netinet/in.h> 464a5d661aSToomas Soome #include <netinet/if_ether.h> 474a5d661aSToomas Soome #include <netinet/in_systm.h> 484a5d661aSToomas Soome #include <netinet/ip.h> 494a5d661aSToomas Soome 504a5d661aSToomas Soome #include "stand.h" 514a5d661aSToomas Soome #include "net.h" 524a5d661aSToomas Soome #include "netif.h" 534a5d661aSToomas Soome 544a5d661aSToomas Soome /* Caller must leave room for ethernet header in front!! */ 554a5d661aSToomas Soome ssize_t 56*7b2a1233SToomas Soome sendether(struct iodesc *d, void *pkt, size_t len, uint8_t *dea, int etype) 574a5d661aSToomas Soome { 584a5d661aSToomas Soome ssize_t n; 594a5d661aSToomas Soome struct ether_header *eh; 604a5d661aSToomas Soome 614a5d661aSToomas Soome #ifdef ETHER_DEBUG 624a5d661aSToomas Soome if (debug) 634a5d661aSToomas Soome printf("sendether: called\n"); 644a5d661aSToomas Soome #endif 654a5d661aSToomas Soome 664a5d661aSToomas Soome eh = (struct ether_header *)pkt - 1; 674a5d661aSToomas Soome len += sizeof(*eh); 684a5d661aSToomas Soome 694a5d661aSToomas Soome MACPY(d->myea, eh->ether_shost); /* by byte */ 704a5d661aSToomas Soome MACPY(dea, eh->ether_dhost); /* by byte */ 714a5d661aSToomas Soome eh->ether_type = htons(etype); 724a5d661aSToomas Soome 734a5d661aSToomas Soome n = netif_put(d, eh, len); 744a5d661aSToomas Soome if (n == -1 || n < sizeof(*eh)) 754a5d661aSToomas Soome return (-1); 764a5d661aSToomas Soome 774a5d661aSToomas Soome n -= sizeof(*eh); 784a5d661aSToomas Soome return (n); 794a5d661aSToomas Soome } 804a5d661aSToomas Soome 814a5d661aSToomas Soome /* 824a5d661aSToomas Soome * Get a packet of any Ethernet type, with our address or 83*7b2a1233SToomas Soome * the broadcast address. Save the Ether type in etype. 84*7b2a1233SToomas Soome * Unless there is an error, we pass the whole packet and the unencapsulated 85*7b2a1233SToomas Soome * data. 864a5d661aSToomas Soome */ 874a5d661aSToomas Soome ssize_t 88*7b2a1233SToomas Soome readether(struct iodesc *d, void **pkt, void **payload, time_t tleft, 89*7b2a1233SToomas Soome uint16_t *etype) 904a5d661aSToomas Soome { 914a5d661aSToomas Soome ssize_t n; 924a5d661aSToomas Soome struct ether_header *eh; 93*7b2a1233SToomas Soome void *ptr; 944a5d661aSToomas Soome 954a5d661aSToomas Soome #ifdef ETHER_DEBUG 964a5d661aSToomas Soome if (debug) 974a5d661aSToomas Soome printf("readether: called\n"); 984a5d661aSToomas Soome #endif 994a5d661aSToomas Soome 100*7b2a1233SToomas Soome ptr = NULL; 101*7b2a1233SToomas Soome n = netif_get(d, &ptr, tleft); 102*7b2a1233SToomas Soome if (n == -1 || n < sizeof(*eh)) { 103*7b2a1233SToomas Soome free(ptr); 1044a5d661aSToomas Soome return (-1); 105*7b2a1233SToomas Soome } 1064a5d661aSToomas Soome 107*7b2a1233SToomas Soome eh = (struct ether_header *)((uintptr_t)ptr + ETHER_ALIGN); 1084a5d661aSToomas Soome /* Validate Ethernet address. */ 1094a5d661aSToomas Soome if (bcmp(d->myea, eh->ether_dhost, 6) != 0 && 1104a5d661aSToomas Soome bcmp(bcea, eh->ether_dhost, 6) != 0) { 1114a5d661aSToomas Soome #ifdef ETHER_DEBUG 1124a5d661aSToomas Soome if (debug) 1134a5d661aSToomas Soome printf("readether: not ours (ea=%s)\n", 1144a5d661aSToomas Soome ether_sprintf(eh->ether_dhost)); 1154a5d661aSToomas Soome #endif 116*7b2a1233SToomas Soome free(ptr); 1174a5d661aSToomas Soome return (-1); 1184a5d661aSToomas Soome } 119*7b2a1233SToomas Soome 120*7b2a1233SToomas Soome *pkt = ptr; 121*7b2a1233SToomas Soome *payload = (void *)((uintptr_t)eh + sizeof(*eh)); 1224a5d661aSToomas Soome *etype = ntohs(eh->ether_type); 1234a5d661aSToomas Soome 1244a5d661aSToomas Soome n -= sizeof(*eh); 1254a5d661aSToomas Soome return (n); 1264a5d661aSToomas Soome } 1274a5d661aSToomas Soome 1284a5d661aSToomas Soome /* 1294a5d661aSToomas Soome * Convert Ethernet address to printable (loggable) representation. 1304a5d661aSToomas Soome */ 1314a5d661aSToomas Soome static char digits[] = "0123456789abcdef"; 1324a5d661aSToomas Soome char * 1334a5d661aSToomas Soome ether_sprintf(ap) 1344a5d661aSToomas Soome u_char *ap; 1354a5d661aSToomas Soome { 1364a5d661aSToomas Soome int i; 1374a5d661aSToomas Soome static char etherbuf[18]; 1384a5d661aSToomas Soome char *cp = etherbuf; 1394a5d661aSToomas Soome 1404a5d661aSToomas Soome for (i = 0; i < 6; i++) { 1414a5d661aSToomas Soome *cp++ = digits[*ap >> 4]; 1424a5d661aSToomas Soome *cp++ = digits[*ap++ & 0xf]; 1434a5d661aSToomas Soome *cp++ = ':'; 1444a5d661aSToomas Soome } 1454a5d661aSToomas Soome *--cp = 0; 1464a5d661aSToomas Soome return (etherbuf); 1474a5d661aSToomas Soome } 148