1 1.5 skrll /* $NetBSD: ip.c,v 1.5 2022/07/08 07:02:47 skrll Exp $ */ 2 1.1 zoltan 3 1.1 zoltan /* 4 1.1 zoltan * Copyright (c) 1992 Regents of the University of California. 5 1.1 zoltan * Copyright (c) 2010 Zoltan Arnold NAGY 6 1.1 zoltan * All rights reserved. 7 1.1 zoltan * 8 1.1 zoltan * This software was developed by the Computer Systems Engineering group 9 1.1 zoltan * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 10 1.1 zoltan * contributed to Berkeley. 11 1.1 zoltan * 12 1.1 zoltan * Redistribution and use in source and binary forms, with or without 13 1.1 zoltan * modification, are permitted provided that the following conditions 14 1.1 zoltan * are met: 15 1.1 zoltan * 1. Redistributions of source code must retain the above copyright 16 1.1 zoltan * notice, this list of conditions and the following disclaimer. 17 1.1 zoltan * 2. Redistributions in binary form must reproduce the above copyright 18 1.1 zoltan * notice, this list of conditions and the following disclaimer in the 19 1.1 zoltan * documentation and/or other materials provided with the distribution. 20 1.1 zoltan * 3. All advertising materials mentioning features or use of this software 21 1.1 zoltan * must display the following acknowledgement: 22 1.1 zoltan * This product includes software developed by the University of 23 1.1 zoltan * California, Lawrence Berkeley Laboratory and its contributors. 24 1.1 zoltan * 4. Neither the name of the University nor the names of its contributors 25 1.1 zoltan * may be used to endorse or promote products derived from this software 26 1.1 zoltan * without specific prior written permission. 27 1.1 zoltan * 28 1.1 zoltan * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 29 1.1 zoltan * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 30 1.1 zoltan * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 31 1.1 zoltan * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 32 1.1 zoltan * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 33 1.1 zoltan * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 34 1.1 zoltan * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 1.1 zoltan * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 1.1 zoltan * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 37 1.1 zoltan * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38 1.1 zoltan * SUCH DAMAGE. 39 1.1 zoltan */ 40 1.1 zoltan 41 1.1 zoltan #include <sys/param.h> 42 1.1 zoltan #include <sys/socket.h> 43 1.1 zoltan #include <net/if.h> 44 1.1 zoltan #include <net/if_ether.h> 45 1.1 zoltan #include <netinet/in.h> 46 1.1 zoltan #include <netinet/in_systm.h> 47 1.1 zoltan #include <netinet/ip.h> 48 1.1 zoltan #include <netinet/ip_var.h> 49 1.1 zoltan #include <netinet/udp.h> 50 1.1 zoltan #include <netinet/udp_var.h> 51 1.1 zoltan 52 1.1 zoltan #ifdef _STANDALONE 53 1.1 zoltan #include <lib/libkern/libkern.h> 54 1.1 zoltan #else 55 1.1 zoltan #include <string.h> 56 1.1 zoltan #endif 57 1.1 zoltan 58 1.1 zoltan #include "stand.h" 59 1.1 zoltan #include "net.h" 60 1.1 zoltan 61 1.1 zoltan /* 62 1.5 skrll * sends an IP packet, if it's already constructed 63 1.1 zoltan */ 64 1.1 zoltan static ssize_t 65 1.3 maxv _sendip(struct iodesc *d, struct ip *ip, size_t len) 66 1.1 zoltan { 67 1.1 zoltan u_char *ea; 68 1.1 zoltan 69 1.1 zoltan if (ip->ip_dst.s_addr == INADDR_BROADCAST || ip->ip_src.s_addr == 0 || 70 1.1 zoltan netmask == 0 || SAMENET(ip->ip_src, ip->ip_dst, netmask)) { 71 1.1 zoltan ea = arpwhohas(d, ip->ip_dst); 72 1.1 zoltan } else { 73 1.1 zoltan ea = arpwhohas(d, gateip); 74 1.1 zoltan } 75 1.1 zoltan 76 1.1 zoltan return sendether(d, ip, len, ea, ETHERTYPE_IP); 77 1.1 zoltan } 78 1.1 zoltan 79 1.1 zoltan /* 80 1.1 zoltan * fills out the IP header 81 1.1 zoltan * Caller must leave room for ethernet, ip and udp headers in front! 82 1.1 zoltan */ 83 1.1 zoltan ssize_t 84 1.3 maxv sendip(struct iodesc *d, void *pkt, size_t len, u_int8_t proto) 85 1.1 zoltan { 86 1.1 zoltan ssize_t cc; 87 1.1 zoltan struct ip *ip; 88 1.1 zoltan 89 1.3 maxv ip = (struct ip *)pkt - 1; 90 1.1 zoltan len += sizeof(*ip); 91 1.1 zoltan 92 1.3 maxv memset(ip, 0, sizeof(*ip)); 93 1.1 zoltan 94 1.1 zoltan ip->ip_v = IPVERSION; 95 1.1 zoltan ip->ip_hl = sizeof(*ip) >> 2; 96 1.1 zoltan ip->ip_len = htons(len); 97 1.1 zoltan ip->ip_p = proto; 98 1.1 zoltan ip->ip_ttl = IPDEFTTL; 99 1.1 zoltan ip->ip_src = d->myip; 100 1.1 zoltan ip->ip_dst = d->destip; 101 1.1 zoltan ip->ip_sum = ip_cksum(ip, sizeof(*ip)); 102 1.1 zoltan 103 1.1 zoltan cc = _sendip(d, ip, len); 104 1.1 zoltan 105 1.1 zoltan if (cc == -1) 106 1.1 zoltan return -1; 107 1.3 maxv if ((size_t)cc != len) 108 1.4 christos panic("%s: bad write (%zd != %zu)", __func__, cc, len); 109 1.1 zoltan return (cc - (sizeof(*ip))); 110 1.1 zoltan } 111 1.1 zoltan 112 1.1 zoltan /* 113 1.1 zoltan * reads an IP packet 114 1.1 zoltan * WARNING: the old version stripped the IP options, if there were 115 1.1 zoltan * any. Because we have absolutely no idea if the upper layer needs 116 1.1 zoltan * these or not, it's best to leave them there. 117 1.1 zoltan * 118 1.1 zoltan * The size returned is the size indicated in the header. 119 1.1 zoltan */ 120 1.1 zoltan ssize_t 121 1.3 maxv readip(struct iodesc *d, void *pkt, size_t len, time_t tleft, u_int8_t proto) 122 1.1 zoltan { 123 1.1 zoltan ssize_t n; 124 1.1 zoltan size_t hlen; 125 1.1 zoltan struct ip *ip; 126 1.1 zoltan u_int16_t etype; 127 1.1 zoltan 128 1.3 maxv ip = (struct ip *)pkt - 1; 129 1.1 zoltan 130 1.1 zoltan n = readether(d, ip, len + sizeof(*ip), tleft, &etype); 131 1.3 maxv if (n == -1 || (size_t)n < sizeof(*ip)) 132 1.1 zoltan return -1; 133 1.1 zoltan 134 1.1 zoltan if (etype == ETHERTYPE_ARP) { 135 1.3 maxv struct arphdr *ah = (void *)ip; 136 1.4 christos if (n < (ssize_t)(sizeof(*ah) + 2 * (ah->ar_hln + ah->ar_pln))) { 137 1.3 maxv return -1; 138 1.3 maxv } 139 1.1 zoltan if (ah->ar_op == htons(ARPOP_REQUEST)) { 140 1.1 zoltan /* Send ARP reply */ 141 1.1 zoltan arp_reply(d, ah); 142 1.1 zoltan } 143 1.1 zoltan return -1; 144 1.1 zoltan } 145 1.1 zoltan if (etype != ETHERTYPE_IP) { 146 1.1 zoltan return -1; 147 1.1 zoltan } 148 1.1 zoltan 149 1.3 maxv if (ip->ip_v != IPVERSION || ip->ip_p != proto) { 150 1.1 zoltan return -1; 151 1.1 zoltan } 152 1.1 zoltan 153 1.1 zoltan hlen = ip->ip_hl << 2; 154 1.3 maxv if (hlen != sizeof(*ip) || ip_cksum(ip, hlen) != 0) { 155 1.3 maxv return -1; 156 1.3 maxv } 157 1.3 maxv if (ntohs(ip->ip_len) < hlen) { 158 1.1 zoltan return -1; 159 1.1 zoltan } 160 1.1 zoltan if (n < ntohs(ip->ip_len)) { 161 1.1 zoltan return -1; 162 1.1 zoltan } 163 1.1 zoltan if (d->myip.s_addr && ip->ip_dst.s_addr != d->myip.s_addr) { 164 1.1 zoltan return -1; 165 1.1 zoltan } 166 1.3 maxv 167 1.3 maxv return (ntohs(ip->ip_len) - hlen); 168 1.1 zoltan } 169