|
|
1.1 ! root 1: /*- ! 2: * Copyright (c) 1991 The 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: * @(#)clnp_raw.c 7.8 (Berkeley) 5/6/91 ! 34: */ ! 35: ! 36: /*********************************************************** ! 37: Copyright IBM Corporation 1987 ! 38: ! 39: All Rights Reserved ! 40: ! 41: Permission to use, copy, modify, and distribute this software and its ! 42: documentation for any purpose and without fee is hereby granted, ! 43: provided that the above copyright notice appear in all copies and that ! 44: both that copyright notice and this permission notice appear in ! 45: supporting documentation, and that the name of IBM not be ! 46: used in advertising or publicity pertaining to distribution of the ! 47: software without specific, written prior permission. ! 48: ! 49: IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ! 50: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL ! 51: IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ! 52: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, ! 53: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ! 54: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ! 55: SOFTWARE. ! 56: ! 57: ******************************************************************/ ! 58: ! 59: /* ! 60: * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison ! 61: */ ! 62: /* $Header: clnp_raw.c,v 4.2 88/06/29 14:58:56 hagens Exp $ */ ! 63: /* $Source: /usr/argo/sys/netiso/RCS/clnp_raw.c,v $ */ ! 64: ! 65: #include "param.h" ! 66: #include "mbuf.h" ! 67: #include "domain.h" ! 68: #include "protosw.h" ! 69: #include "socket.h" ! 70: #include "socketvar.h" ! 71: #include "errno.h" ! 72: #include "time.h" ! 73: ! 74: #include "../net/if.h" ! 75: #include "../net/route.h" ! 76: #include "../net/raw_cb.h" ! 77: ! 78: #include "iso.h" ! 79: #include "iso_pcb.h" ! 80: #include "clnp.h" ! 81: #include "clnp_stat.h" ! 82: #include "argo_debug.h" ! 83: ! 84: #include "tp_user.h"/* XXX -- defines SOL_NETWORK */ ! 85: ! 86: struct sockproto rclnp_proto = { PF_ISO, 0 }; ! 87: /* ! 88: * FUNCTION: rclnp_input ! 89: * ! 90: * PURPOSE: Setup generic address an protocol structures for ! 91: * raw input routine, then pass them along with the ! 92: * mbuf chain. ! 93: * ! 94: * RETURNS: none ! 95: * ! 96: * SIDE EFFECTS: ! 97: * ! 98: * NOTES: The protocol field of rclnp_proto is set to zero indicating ! 99: * no protocol. ! 100: */ ! 101: rclnp_input(m, src, dst, hdrlen) ! 102: struct mbuf *m; /* ptr to packet */ ! 103: struct sockaddr_iso *src; /* ptr to src address */ ! 104: struct sockaddr_iso *dst; /* ptr to dest address */ ! 105: int hdrlen; /* length (in bytes) of clnp header */ ! 106: { ! 107: #ifdef TROLL ! 108: if (trollctl.tr_ops & TR_CHUCK) { ! 109: m_freem(m); ! 110: return; ! 111: } ! 112: #endif TROLL ! 113: ! 114: if (raw_input(m, &rclnp_proto, (struct sockaddr *)src, ! 115: (struct sockaddr *)dst) == 0) { ! 116: clnp_stat.cns_delivered--; ! 117: clnp_stat.cns_noproto++; ! 118: } ! 119: } ! 120: ! 121: /* ! 122: * FUNCTION: rclnp_output ! 123: * ! 124: * PURPOSE: Prepare to send a raw clnp packet. Setup src and dest ! 125: * addresses, count the number of bytes to send, and ! 126: * call clnp_output. ! 127: * ! 128: * RETURNS: success - 0 ! 129: * failure - an appropriate error code ! 130: * ! 131: * SIDE EFFECTS: ! 132: * ! 133: * NOTES: ! 134: */ ! 135: rclnp_output(m0, so) ! 136: struct mbuf *m0; /* packet to send */ ! 137: struct socket *so; /* socket to send from */ ! 138: { ! 139: register struct mbuf *m; /* used to scan a chain */ ! 140: int len = 0; /* store length of chain here */ ! 141: struct rawisopcb *rp = sotorawisopcb(so); /* ptr to raw cb */ ! 142: int error; /* return value of function */ ! 143: int flags; /* flags for clnp_output */ ! 144: ! 145: if (0 == m0->m_flags & M_PKTHDR) ! 146: return (EINVAL); ! 147: /* ! 148: * Set up src address. If user has bound socket to an address, use it. ! 149: * Otherwise, do not specify src (clnp_output will fill it in). ! 150: */ ! 151: if (rp->risop_rcb.rcb_laddr) { ! 152: if (rp->risop_isop.isop_sladdr.siso_family != AF_ISO) { ! 153: bad: ! 154: m_freem(m0); ! 155: return(EAFNOSUPPORT); ! 156: } ! 157: } ! 158: /* set up dest address */ ! 159: if (rp->risop_rcb.rcb_faddr == 0) ! 160: goto bad; ! 161: rp->risop_isop.isop_sfaddr = ! 162: *(struct sockaddr_iso *)rp->risop_rcb.rcb_faddr; ! 163: rp->risop_isop.isop_faddr = &rp->risop_isop.isop_sfaddr; ! 164: ! 165: /* get flags and ship it off */ ! 166: flags = rp->risop_flags & CLNP_VFLAGS; ! 167: ! 168: error = clnp_output(m0, &rp->risop_isop, m0->m_pkthdr.len, ! 169: flags|CLNP_NOCACHE); ! 170: ! 171: return (error); ! 172: } ! 173: ! 174: /* ! 175: * FUNCTION: rclnp_ctloutput ! 176: * ! 177: * PURPOSE: Raw clnp socket option processing ! 178: * All options are stored inside an mbuf. ! 179: * ! 180: * RETURNS: success - 0 ! 181: * failure - unix error code ! 182: * ! 183: * SIDE EFFECTS: If the options mbuf does not exist, it the mbuf passed ! 184: * is used. ! 185: * ! 186: * NOTES: ! 187: */ ! 188: rclnp_ctloutput(op, so, level, optname, m) ! 189: int op; /* type of operation */ ! 190: struct socket *so; /* ptr to socket */ ! 191: int level; /* level of option */ ! 192: int optname; /* name of option */ ! 193: struct mbuf **m; /* ptr to ptr to option data */ ! 194: { ! 195: int error = 0; ! 196: register struct rawisopcb *rp = sotorawisopcb(so);/* raw cb ptr */ ! 197: ! 198: IFDEBUG(D_CTLOUTPUT) ! 199: printf("rclnp_ctloutput: op = x%x, level = x%x, name = x%x\n", ! 200: op, level, optname); ! 201: if (*m != NULL) { ! 202: printf("rclnp_ctloutput: %d bytes of mbuf data\n", (*m)->m_len); ! 203: dump_buf(mtod((*m), caddr_t), (*m)->m_len); ! 204: } ! 205: ENDDEBUG ! 206: ! 207: #ifdef SOL_NETWORK ! 208: if (level != SOL_NETWORK) ! 209: error = EINVAL; ! 210: else switch (op) { ! 211: #else ! 212: switch (op) { ! 213: #endif SOL_NETWORK ! 214: case PRCO_SETOPT: ! 215: switch (optname) { ! 216: case CLNPOPT_FLAGS: { ! 217: u_short usr_flags; ! 218: /* ! 219: * Insure that the data passed has exactly one short in it ! 220: */ ! 221: if ((*m == NULL) || ((*m)->m_len != sizeof(short))) { ! 222: error = EINVAL; ! 223: break; ! 224: } ! 225: ! 226: /* ! 227: * Don't allow invalid flags to be set ! 228: */ ! 229: usr_flags = (*mtod((*m), short *)); ! 230: ! 231: if ((usr_flags & (CLNP_VFLAGS)) != usr_flags) { ! 232: error = EINVAL; ! 233: } else ! 234: rp->risop_flags |= usr_flags; ! 235: ! 236: } break; ! 237: ! 238: case CLNPOPT_OPTS: ! 239: if (error = clnp_set_opts(&rp->risop_isop.isop_options, m)) ! 240: break; ! 241: rp->risop_isop.isop_optindex = m_get(M_WAIT, MT_SOOPTS); ! 242: (void) clnp_opt_sanity(rp->risop_isop.isop_options, ! 243: mtod(rp->risop_isop.isop_options, caddr_t), ! 244: rp->risop_isop.isop_options->m_len, ! 245: mtod(rp->risop_isop.isop_optindex, ! 246: struct clnp_optidx *)); ! 247: break; ! 248: } ! 249: break; ! 250: ! 251: case PRCO_GETOPT: ! 252: #ifdef notdef ! 253: /* commented out to keep hi C quiet */ ! 254: switch (optname) { ! 255: default: ! 256: error = EINVAL; ! 257: break; ! 258: } ! 259: #endif notdef ! 260: break; ! 261: default: ! 262: error = EINVAL; ! 263: break; ! 264: } ! 265: if (op == PRCO_SETOPT) { ! 266: /* note: m_freem does not barf is *m is NULL */ ! 267: m_freem(*m); ! 268: *m = NULL; ! 269: } ! 270: ! 271: return error; ! 272: } ! 273: ! 274: /*ARGSUSED*/ ! 275: clnp_usrreq(so, req, m, nam, control) ! 276: register struct socket *so; ! 277: int req; ! 278: struct mbuf *m, *nam, *control; ! 279: { ! 280: register int error = 0; ! 281: register struct rawisopcb *rp = sotorawisopcb(so); ! 282: ! 283: rp = sotorawisopcb(so); ! 284: switch (req) { ! 285: ! 286: case PRU_ATTACH: ! 287: if (rp) ! 288: panic("rip_attach"); ! 289: MALLOC(rp, struct rawisopcb *, sizeof *rp, M_PCB, M_WAITOK); ! 290: if (rp == 0) ! 291: return (ENOBUFS); ! 292: bzero((caddr_t)rp, sizeof *rp); ! 293: so->so_pcb = (caddr_t)rp; ! 294: break; ! 295: ! 296: case PRU_DETACH: ! 297: if (rp == 0) ! 298: panic("rip_detach"); ! 299: if (rp->risop_isop.isop_options) ! 300: m_freem(rp->risop_isop.isop_options); ! 301: if (rp->risop_isop.isop_route.ro_rt) ! 302: RTFREE(rp->risop_isop.isop_route.ro_rt); ! 303: if (rp->risop_rcb.rcb_laddr) ! 304: rp->risop_rcb.rcb_laddr = 0; ! 305: /* free clnp cached hdr if necessary */ ! 306: if (rp->risop_isop.isop_clnpcache != NULL) { ! 307: struct clnp_cache *clcp = ! 308: mtod(rp->risop_isop.isop_clnpcache, struct clnp_cache *); ! 309: if (clcp->clc_hdr != NULL) { ! 310: m_free(clcp->clc_hdr); ! 311: } ! 312: m_free(rp->risop_isop.isop_clnpcache); ! 313: } ! 314: if (rp->risop_isop.isop_optindex != NULL) ! 315: m_free(rp->risop_isop.isop_optindex); ! 316: ! 317: break; ! 318: ! 319: case PRU_BIND: ! 320: { ! 321: struct sockaddr_iso *addr = mtod(nam, struct sockaddr_iso *); ! 322: ! 323: if (nam->m_len != sizeof(*addr)) ! 324: return (EINVAL); ! 325: if ((ifnet == 0) || ! 326: (addr->siso_family != AF_ISO) || ! 327: (addr->siso_addr.isoa_len && ! 328: ifa_ifwithaddr((struct sockaddr *)addr) == 0)) ! 329: return (EADDRNOTAVAIL); ! 330: rp->risop_isop.isop_sladdr = *addr; ! 331: rp->risop_rcb.rcb_laddr = (struct sockaddr *) ! 332: (rp->risop_isop.isop_laddr = &rp->risop_isop.isop_sladdr); ! 333: return (0); ! 334: } ! 335: case PRU_CONNECT: ! 336: { ! 337: struct sockaddr_iso *addr = mtod(nam, struct sockaddr_iso *); ! 338: ! 339: if ((nam->m_len > sizeof(*addr)) || (addr->siso_len > sizeof(*addr))) ! 340: return (EINVAL); ! 341: if (ifnet == 0) ! 342: return (EADDRNOTAVAIL); ! 343: if (addr->siso_family != AF_ISO) ! 344: rp->risop_isop.isop_sfaddr = *addr; ! 345: rp->risop_rcb.rcb_faddr = (struct sockaddr *) ! 346: (rp->risop_isop.isop_faddr = &rp->risop_isop.isop_sfaddr); ! 347: soisconnected(so); ! 348: return (0); ! 349: } ! 350: } ! 351: error = raw_usrreq(so, req, m, nam, control); ! 352: ! 353: if (error && req == PRU_ATTACH && so->so_pcb) ! 354: free((caddr_t)rp, M_PCB); ! 355: return (error); ! 356: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.