Annotation of src/sys/netinet/raw_ip.c, Revision 1.1
1.1 ! cgd 1: /*
! 2: * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
! 3: * All rights reserved.
! 4: *
! 5: * Redistribution and use in source and binary forms, with or without
! 6: * modification, are permitted provided that the following conditions
! 7: * are met:
! 8: * 1. Redistributions of source code must retain the above copyright
! 9: * notice, this list of conditions and the following disclaimer.
! 10: * 2. Redistributions in binary form must reproduce the above copyright
! 11: * notice, this list of conditions and the following disclaimer in the
! 12: * documentation and/or other materials provided with the distribution.
! 13: * 3. All advertising materials mentioning features or use of this software
! 14: * must display the following acknowledgement:
! 15: * This product includes software developed by the University of
! 16: * California, Berkeley and its contributors.
! 17: * 4. Neither the name of the University nor the names of its contributors
! 18: * may be used to endorse or promote products derived from this software
! 19: * without specific prior written permission.
! 20: *
! 21: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
! 22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 24: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 31: * SUCH DAMAGE.
! 32: *
! 33: * @(#)raw_ip.c 7.8 (Berkeley) 7/25/90
! 34: */
! 35:
! 36: #include "param.h"
! 37: #include "malloc.h"
! 38: #include "mbuf.h"
! 39: #include "socket.h"
! 40: #include "protosw.h"
! 41: #include "socketvar.h"
! 42: #include "errno.h"
! 43:
! 44: #include "../net/if.h"
! 45: #include "../net/route.h"
! 46: #include "../net/raw_cb.h"
! 47:
! 48: #include "in.h"
! 49: #include "in_systm.h"
! 50: #include "ip.h"
! 51: #include "ip_var.h"
! 52: #include "in_pcb.h"
! 53:
! 54: /*
! 55: * Raw interface to IP protocol.
! 56: */
! 57:
! 58: struct sockaddr_in ripdst = { sizeof(ripdst), AF_INET };
! 59: struct sockaddr_in ripsrc = { sizeof(ripsrc), AF_INET };
! 60: struct sockproto ripproto = { PF_INET };
! 61: /*
! 62: * Setup generic address and protocol structures
! 63: * for raw_input routine, then pass them along with
! 64: * mbuf chain.
! 65: */
! 66: rip_input(m)
! 67: struct mbuf *m;
! 68: {
! 69: register struct ip *ip = mtod(m, struct ip *);
! 70:
! 71: ripproto.sp_protocol = ip->ip_p;
! 72: ripdst.sin_addr = ip->ip_dst;
! 73: ripsrc.sin_addr = ip->ip_src;
! 74: if (raw_input(m, &ripproto, (struct sockaddr *)&ripsrc,
! 75: (struct sockaddr *)&ripdst) == 0) {
! 76: ipstat.ips_noproto++;
! 77: ipstat.ips_delivered--;
! 78: }
! 79: }
! 80:
! 81: /*
! 82: * Generate IP header and pass packet to ip_output.
! 83: * Tack on options user may have setup with control call.
! 84: */
! 85: #define satosin(sa) ((struct sockaddr_in *)(sa))
! 86: rip_output(m, so)
! 87: register struct mbuf *m;
! 88: struct socket *so;
! 89: {
! 90: register struct ip *ip;
! 91: register struct raw_inpcb *rp = sotorawinpcb(so);
! 92: register struct sockaddr_in *sin;
! 93:
! 94: /*
! 95: * If the user handed us a complete IP packet, use it.
! 96: * Otherwise, allocate an mbuf for a header and fill it in.
! 97: */
! 98: if (rp->rinp_flags & RINPF_HDRINCL)
! 99: ip = mtod(m, struct ip *);
! 100: else {
! 101: M_PREPEND(m, sizeof(struct ip), M_WAIT);
! 102: ip = mtod(m, struct ip *);
! 103: ip->ip_tos = 0;
! 104: ip->ip_off = 0;
! 105: ip->ip_p = rp->rinp_rcb.rcb_proto.sp_protocol;
! 106: ip->ip_len = m->m_pkthdr.len;
! 107: if (sin = satosin(rp->rinp_rcb.rcb_laddr)) {
! 108: ip->ip_src = sin->sin_addr;
! 109: } else
! 110: ip->ip_src.s_addr = 0;
! 111: if (sin = satosin(rp->rinp_rcb.rcb_faddr))
! 112: ip->ip_dst = sin->sin_addr;
! 113: ip->ip_ttl = MAXTTL;
! 114: }
! 115: return (ip_output(m,
! 116: (rp->rinp_flags & RINPF_HDRINCL)? (struct mbuf *)0: rp->rinp_options,
! 117: &rp->rinp_route,
! 118: (so->so_options & SO_DONTROUTE) | IP_ALLOWBROADCAST));
! 119: }
! 120:
! 121: /*
! 122: * Raw IP socket option processing.
! 123: */
! 124: rip_ctloutput(op, so, level, optname, m)
! 125: int op;
! 126: struct socket *so;
! 127: int level, optname;
! 128: struct mbuf **m;
! 129: {
! 130: int error = 0;
! 131: register struct raw_inpcb *rp = sotorawinpcb(so);
! 132:
! 133: if (level != IPPROTO_IP)
! 134: error = EINVAL;
! 135: else switch (op) {
! 136:
! 137: case PRCO_SETOPT:
! 138: switch (optname) {
! 139:
! 140: case IP_OPTIONS:
! 141: return (ip_pcbopts(&rp->rinp_options, *m));
! 142:
! 143: case IP_HDRINCL:
! 144: if (m == 0 || *m == 0 || (*m)->m_len < sizeof (int)) {
! 145: error = EINVAL;
! 146: break;
! 147: }
! 148: if (*mtod(*m, int *))
! 149: rp->rinp_flags |= RINPF_HDRINCL;
! 150: else
! 151: rp->rinp_flags &= ~RINPF_HDRINCL;
! 152: break;
! 153:
! 154: default:
! 155: error = EINVAL;
! 156: break;
! 157: }
! 158: break;
! 159:
! 160: case PRCO_GETOPT:
! 161: *m = m_get(M_WAIT, MT_SOOPTS);
! 162: switch (optname) {
! 163:
! 164: case IP_OPTIONS:
! 165: if (rp->rinp_options) {
! 166: (*m)->m_len = rp->rinp_options->m_len;
! 167: bcopy(mtod(rp->rinp_options, caddr_t),
! 168: mtod(*m, caddr_t), (unsigned)(*m)->m_len);
! 169: } else
! 170: (*m)->m_len = 0;
! 171: break;
! 172:
! 173: case IP_HDRINCL:
! 174: (*m)->m_len = sizeof (int);
! 175: *mtod(*m, int *) = rp->rinp_flags & RINPF_HDRINCL;
! 176: break;
! 177:
! 178: default:
! 179: error = EINVAL;
! 180: m_freem(*m);
! 181: *m = 0;
! 182: break;
! 183: }
! 184: break;
! 185: }
! 186: if (op == PRCO_SETOPT && *m)
! 187: (void)m_free(*m);
! 188: return (error);
! 189: }
! 190:
! 191: /*ARGSUSED*/
! 192: rip_usrreq(so, req, m, nam, rights, control)
! 193: register struct socket *so;
! 194: int req;
! 195: struct mbuf *m, *nam, *rights, *control;
! 196: {
! 197: register int error = 0;
! 198: register struct raw_inpcb *rp = sotorawinpcb(so);
! 199:
! 200: switch (req) {
! 201:
! 202: case PRU_ATTACH:
! 203: if (rp)
! 204: panic("rip_attach");
! 205: MALLOC(rp, struct raw_inpcb *, sizeof *rp, M_PCB, M_WAITOK);
! 206: if (rp == 0)
! 207: return (ENOBUFS);
! 208: bzero((caddr_t)rp, sizeof *rp);
! 209: so->so_pcb = (caddr_t)rp;
! 210: break;
! 211:
! 212: case PRU_DETACH:
! 213: if (rp == 0)
! 214: panic("rip_detach");
! 215: if (rp->rinp_options)
! 216: m_freem(rp->rinp_options);
! 217: if (rp->rinp_route.ro_rt)
! 218: RTFREE(rp->rinp_route.ro_rt);
! 219: if (rp->rinp_rcb.rcb_laddr)
! 220: rp->rinp_rcb.rcb_laddr = 0;
! 221: break;
! 222:
! 223: case PRU_BIND:
! 224: {
! 225: struct sockaddr_in *addr = mtod(nam, struct sockaddr_in *);
! 226:
! 227: if (nam->m_len != sizeof(*addr))
! 228: return (EINVAL);
! 229: if ((ifnet == 0) ||
! 230: ((addr->sin_family != AF_INET) &&
! 231: (addr->sin_family != AF_IMPLINK)) ||
! 232: (addr->sin_addr.s_addr &&
! 233: ifa_ifwithaddr((struct sockaddr *)addr) == 0))
! 234: return (EADDRNOTAVAIL);
! 235: rp->rinp_rcb.rcb_laddr = (struct sockaddr *)&rp->rinp_laddr;
! 236: rp->rinp_laddr = *addr;
! 237: return (0);
! 238: }
! 239: case PRU_CONNECT:
! 240: {
! 241: struct sockaddr_in *addr = mtod(nam, struct sockaddr_in *);
! 242:
! 243: if (nam->m_len != sizeof(*addr))
! 244: return (EINVAL);
! 245: if (ifnet == 0)
! 246: return (EADDRNOTAVAIL);
! 247: if ((addr->sin_family != AF_INET) &&
! 248: (addr->sin_family != AF_IMPLINK))
! 249: return (EAFNOSUPPORT);
! 250: rp->rinp_rcb.rcb_faddr = (struct sockaddr *)&rp->rinp_faddr;
! 251: rp->rinp_faddr = *addr;
! 252: soisconnected(so);
! 253: return (0);
! 254: }
! 255: }
! 256: error = raw_usrreq(so, req, m, nam, control);
! 257:
! 258: if (error && (req == PRU_ATTACH) && so->so_pcb)
! 259: free(so->so_pcb, M_PCB);
! 260: return (error);
! 261: }
CVSweb <webmaster@jp.NetBSD.org>