14a5d661aSToomas Soome /* Taken from $NetBSD: net.c,v 1.20 1997/12/26 22:41:30 scottr 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 434a5d661aSToomas Soome #include <string.h> 444a5d661aSToomas Soome 454a5d661aSToomas Soome #include <net/if.h> 464a5d661aSToomas Soome #include <netinet/in.h> 474a5d661aSToomas Soome #include <netinet/if_ether.h> 484a5d661aSToomas Soome #include <netinet/in_systm.h> 494a5d661aSToomas Soome 504a5d661aSToomas Soome #include <netinet/in_pcb.h> 514a5d661aSToomas Soome #include <netinet/ip.h> 524a5d661aSToomas Soome #include <netinet/ip_var.h> 534a5d661aSToomas Soome #include <netinet/udp.h> 544a5d661aSToomas Soome #include <netinet/udp_var.h> 554a5d661aSToomas Soome 564a5d661aSToomas Soome #include "stand.h" 574a5d661aSToomas Soome #include "net.h" 584a5d661aSToomas Soome 594a5d661aSToomas Soome /* Caller must leave room for ethernet, ip and udp headers in front!! */ 604a5d661aSToomas Soome ssize_t 617b2a1233SToomas Soome sendudp(struct iodesc *d, void *pkt, size_t len) 624a5d661aSToomas Soome { 634a5d661aSToomas Soome ssize_t cc; 64*a4a2722fSToomas Soome struct udpiphdr *ui; 654a5d661aSToomas Soome struct udphdr *uh; 664a5d661aSToomas Soome 674a5d661aSToomas Soome #ifdef NET_DEBUG 684a5d661aSToomas Soome if (debug) { 694a5d661aSToomas Soome printf("sendudp: d=%lx called.\n", (long)d); 704a5d661aSToomas Soome if (d) { 714a5d661aSToomas Soome printf("saddr: %s:%d", 724a5d661aSToomas Soome inet_ntoa(d->myip), ntohs(d->myport)); 734a5d661aSToomas Soome printf(" daddr: %s:%d\n", 744a5d661aSToomas Soome inet_ntoa(d->destip), ntohs(d->destport)); 754a5d661aSToomas Soome } 764a5d661aSToomas Soome } 774a5d661aSToomas Soome #endif 784a5d661aSToomas Soome 79*a4a2722fSToomas Soome ui = (struct udpiphdr *)pkt - 1; 80*a4a2722fSToomas Soome bzero(ui, sizeof(*ui)); 81*a4a2722fSToomas Soome 824a5d661aSToomas Soome uh = (struct udphdr *)pkt - 1; 83*a4a2722fSToomas Soome len += sizeof(*uh); 844a5d661aSToomas Soome 854a5d661aSToomas Soome uh->uh_sport = d->myport; 864a5d661aSToomas Soome uh->uh_dport = d->destport; 87*a4a2722fSToomas Soome uh->uh_ulen = htons(len); 88*a4a2722fSToomas Soome 89*a4a2722fSToomas Soome ui->ui_pr = IPPROTO_UDP; 90*a4a2722fSToomas Soome ui->ui_len = uh->uh_ulen; 91*a4a2722fSToomas Soome ui->ui_src = d->myip; 92*a4a2722fSToomas Soome ui->ui_dst = d->destip; 934a5d661aSToomas Soome 944a5d661aSToomas Soome #ifndef UDP_NO_CKSUM 95*a4a2722fSToomas Soome uh->uh_sum = in_cksum(ui, len + sizeof (struct ip)); 964a5d661aSToomas Soome #endif 974a5d661aSToomas Soome 98*a4a2722fSToomas Soome cc = sendip(d, uh, len, IPPROTO_UDP); 994a5d661aSToomas Soome if (cc == -1) 1004a5d661aSToomas Soome return (-1); 1014a5d661aSToomas Soome if (cc != len) 1024a5d661aSToomas Soome panic("sendudp: bad write (%zd != %zd)", cc, len); 103*a4a2722fSToomas Soome return (cc - sizeof(*uh)); 1044a5d661aSToomas Soome } 1054a5d661aSToomas Soome 1064a5d661aSToomas Soome /* 1074a5d661aSToomas Soome * Receive a UDP packet and validate it is for us. 1084a5d661aSToomas Soome */ 1094a5d661aSToomas Soome ssize_t 1107b2a1233SToomas Soome readudp(struct iodesc *d, void **pkt, void **payload, time_t tleft) 1114a5d661aSToomas Soome { 1124a5d661aSToomas Soome ssize_t n; 1134a5d661aSToomas Soome struct udphdr *uh; 1147b2a1233SToomas Soome void *ptr; 1154a5d661aSToomas Soome 1164a5d661aSToomas Soome #ifdef NET_DEBUG 1174a5d661aSToomas Soome if (debug) 1184a5d661aSToomas Soome printf("readudp: called\n"); 1194a5d661aSToomas Soome #endif 1204a5d661aSToomas Soome 121*a4a2722fSToomas Soome uh = NULL; 1227b2a1233SToomas Soome ptr = NULL; 123*a4a2722fSToomas Soome n = readip(d, &ptr, (void **)&uh, tleft, IPPROTO_UDP); 124*a4a2722fSToomas Soome if (n == -1 || n < sizeof(*uh) || n != ntohs(uh->uh_ulen)) { 1257b2a1233SToomas Soome free(ptr); 1267b2a1233SToomas Soome return (-1); 1277b2a1233SToomas Soome } 1284a5d661aSToomas Soome 1294a5d661aSToomas Soome if (uh->uh_dport != d->myport) { 1304a5d661aSToomas Soome #ifdef NET_DEBUG 1314a5d661aSToomas Soome if (debug) 1324a5d661aSToomas Soome printf("readudp: bad dport %d != %d\n", 1334a5d661aSToomas Soome d->myport, ntohs(uh->uh_dport)); 1344a5d661aSToomas Soome #endif 1357b2a1233SToomas Soome free(ptr); 1367b2a1233SToomas Soome return (-1); 1374a5d661aSToomas Soome } 1384a5d661aSToomas Soome 1394a5d661aSToomas Soome #ifndef UDP_NO_CKSUM 1404a5d661aSToomas Soome if (uh->uh_sum) { 1414a5d661aSToomas Soome struct udpiphdr *ui; 142*a4a2722fSToomas Soome struct ip *ip; 1434a5d661aSToomas Soome struct ip tip; 1444a5d661aSToomas Soome 1454a5d661aSToomas Soome n = ntohs(uh->uh_ulen) + sizeof(*ip); 1464a5d661aSToomas Soome 1474a5d661aSToomas Soome /* Check checksum (must save and restore ip header) */ 148*a4a2722fSToomas Soome ip = (struct ip *)uh - 1; 1494a5d661aSToomas Soome tip = *ip; 1504a5d661aSToomas Soome ui = (struct udpiphdr *)ip; 1514a5d661aSToomas Soome bzero(&ui->ui_x1, sizeof(ui->ui_x1)); 1524a5d661aSToomas Soome ui->ui_len = uh->uh_ulen; 1534a5d661aSToomas Soome if (in_cksum(ui, n) != 0) { 1544a5d661aSToomas Soome #ifdef NET_DEBUG 1554a5d661aSToomas Soome if (debug) 1564a5d661aSToomas Soome printf("readudp: bad cksum\n"); 1574a5d661aSToomas Soome #endif 1587b2a1233SToomas Soome free(ptr); 1597b2a1233SToomas Soome return (-1); 1604a5d661aSToomas Soome } 1614a5d661aSToomas Soome *ip = tip; 1624a5d661aSToomas Soome } 1634a5d661aSToomas Soome #endif 1644a5d661aSToomas Soome if (ntohs(uh->uh_ulen) < sizeof(*uh)) { 1654a5d661aSToomas Soome #ifdef NET_DEBUG 1664a5d661aSToomas Soome if (debug) 1674a5d661aSToomas Soome printf("readudp: bad udp len %d < %d\n", 1684a5d661aSToomas Soome ntohs(uh->uh_ulen), (int)sizeof(*uh)); 1694a5d661aSToomas Soome #endif 1707b2a1233SToomas Soome free(ptr); 1717b2a1233SToomas Soome return (-1); 1724a5d661aSToomas Soome } 1734a5d661aSToomas Soome 1744a5d661aSToomas Soome n = (n > (ntohs(uh->uh_ulen) - sizeof(*uh))) ? 1754a5d661aSToomas Soome ntohs(uh->uh_ulen) - sizeof(*uh) : n; 1767b2a1233SToomas Soome *pkt = ptr; 1777b2a1233SToomas Soome *payload = (void *)((uintptr_t)uh + sizeof(*uh)); 1784a5d661aSToomas Soome return (n); 1794a5d661aSToomas Soome } 180