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