1: /*
   2:  * Copyright (c) 1980, 1986 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  *
   6:  *	@(#)raw_usrreq.c	7.1 (Berkeley) 6/4/86
   7:  */
   8: 
   9: #include "param.h"
  10: #include "mbuf.h"
  11: #include "domain.h"
  12: #include "protosw.h"
  13: #include "socket.h"
  14: #include "socketvar.h"
  15: #include "errno.h"
  16: 
  17: #include "if.h"
  18: #include "route.h"
  19: #include "netisr.h"
  20: #include "raw_cb.h"
  21: 
  22: #include "../vax/mtpr.h"
  23: 
  24: /*
  25:  * Initialize raw connection block q.
  26:  */
  27: raw_init()
  28: {
  29: 
  30:     rawcb.rcb_next = rawcb.rcb_prev = &rawcb;
  31:     rawintrq.ifq_maxlen = IFQ_MAXLEN;
  32: }
  33: 
  34: /*
  35:  * Raw protocol interface.
  36:  */
  37: raw_input(m0, proto, src, dst)
  38:     struct mbuf *m0;
  39:     struct sockproto *proto;
  40:     struct sockaddr *src, *dst;
  41: {
  42:     register struct mbuf *m;
  43:     struct raw_header *rh;
  44:     int s;
  45: 
  46:     /*
  47: 	 * Rip off an mbuf for a generic header.
  48: 	 */
  49:     m = m_get(M_DONTWAIT, MT_HEADER);
  50:     if (m == 0) {
  51:         m_freem(m0);
  52:         return;
  53:     }
  54:     m->m_next = m0;
  55:     m->m_len = sizeof(struct raw_header);
  56:     rh = mtod(m, struct raw_header *);
  57:     rh->raw_dst = *dst;
  58:     rh->raw_src = *src;
  59:     rh->raw_proto = *proto;
  60: 
  61:     /*
  62: 	 * Header now contains enough info to decide
  63: 	 * which socket to place packet in (if any).
  64: 	 * Queue it up for the raw protocol process
  65: 	 * running at software interrupt level.
  66: 	 */
  67:     s = splimp();
  68:     if (IF_QFULL(&rawintrq))
  69:         m_freem(m);
  70:     else
  71:         IF_ENQUEUE(&rawintrq, m);
  72:     splx(s);
  73:     schednetisr(NETISR_RAW);
  74: }
  75: 
  76: /*
  77:  * Raw protocol input routine.  Process packets entered
  78:  * into the queue at interrupt time.  Find the socket
  79:  * associated with the packet(s) and move them over.  If
  80:  * nothing exists for this packet, drop it.
  81:  */
  82: rawintr()
  83: {
  84:     int s;
  85:     struct mbuf *m;
  86:     register struct rawcb *rp;
  87:     register struct raw_header *rh;
  88:     struct socket *last;
  89: 
  90: next:
  91:     s = splimp();
  92:     IF_DEQUEUE(&rawintrq, m);
  93:     splx(s);
  94:     if (m == 0)
  95:         return;
  96:     rh = mtod(m, struct raw_header *);
  97:     last = 0;
  98:     for (rp = rawcb.rcb_next; rp != &rawcb; rp = rp->rcb_next) {
  99:         if (rp->rcb_proto.sp_family != rh->raw_proto.sp_family)
 100:             continue;
 101:         if (rp->rcb_proto.sp_protocol  &&
 102:             rp->rcb_proto.sp_protocol != rh->raw_proto.sp_protocol)
 103:             continue;
 104:         /*
 105: 		 * We assume the lower level routines have
 106: 		 * placed the address in a canonical format
 107: 		 * suitable for a structure comparison.
 108: 		 */
 109: #define equal(a1, a2) \
 110:     (bcmp((caddr_t)&(a1), (caddr_t)&(a2), sizeof (struct sockaddr)) == 0)
 111:         if ((rp->rcb_flags & RAW_LADDR) &&
 112:             !equal(rp->rcb_laddr, rh->raw_dst))
 113:             continue;
 114:         if ((rp->rcb_flags & RAW_FADDR) &&
 115:             !equal(rp->rcb_faddr, rh->raw_src))
 116:             continue;
 117:         if (last) {
 118:             struct mbuf *n;
 119:             if (n = m_copy(m->m_next, 0, (int)M_COPYALL)) {
 120:                 if (sbappendaddr(&last->so_rcv, &rh->raw_src,
 121:                     n, (struct mbuf *)0) == 0)
 122:                     /* should notify about lost packet */
 123:                     m_freem(n);
 124:                 else
 125:                     sorwakeup(last);
 126:             }
 127:         }
 128:         last = rp->rcb_socket;
 129:     }
 130:     if (last) {
 131:         if (sbappendaddr(&last->so_rcv, &rh->raw_src,
 132:             m->m_next, (struct mbuf *)0) == 0)
 133:             m_freem(m->m_next);
 134:         else
 135:             sorwakeup(last);
 136:         (void) m_free(m);       /* header */
 137:     } else
 138:         m_freem(m);
 139:     goto next;
 140: }
 141: 
 142: /*ARGSUSED*/
 143: raw_ctlinput(cmd, arg)
 144:     int cmd;
 145:     struct sockaddr *arg;
 146: {
 147: 
 148:     if (cmd < 0 || cmd > PRC_NCMDS)
 149:         return;
 150:     /* INCOMPLETE */
 151: }
 152: 
 153: /*ARGSUSED*/
 154: raw_usrreq(so, req, m, nam, rights)
 155:     struct socket *so;
 156:     int req;
 157:     struct mbuf *m, *nam, *rights;
 158: {
 159:     register struct rawcb *rp = sotorawcb(so);
 160:     register int error = 0;
 161: 
 162:     if (req == PRU_CONTROL)
 163:         return (EOPNOTSUPP);
 164:     if (rights && rights->m_len) {
 165:         error = EOPNOTSUPP;
 166:         goto release;
 167:     }
 168:     if (rp == 0 && req != PRU_ATTACH) {
 169:         error = EINVAL;
 170:         goto release;
 171:     }
 172:     switch (req) {
 173: 
 174:     /*
 175: 	 * Allocate a raw control block and fill in the
 176: 	 * necessary info to allow packets to be routed to
 177: 	 * the appropriate raw interface routine.
 178: 	 */
 179:     case PRU_ATTACH:
 180:         if ((so->so_state & SS_PRIV) == 0) {
 181:             error = EACCES;
 182:             break;
 183:         }
 184:         if (rp) {
 185:             error = EINVAL;
 186:             break;
 187:         }
 188:         error = raw_attach(so, (int)nam);
 189:         break;
 190: 
 191:     /*
 192: 	 * Destroy state just before socket deallocation.
 193: 	 * Flush data or not depending on the options.
 194: 	 */
 195:     case PRU_DETACH:
 196:         if (rp == 0) {
 197:             error = ENOTCONN;
 198:             break;
 199:         }
 200:         raw_detach(rp);
 201:         break;
 202: 
 203:     /*
 204: 	 * If a socket isn't bound to a single address,
 205: 	 * the raw input routine will hand it anything
 206: 	 * within that protocol family (assuming there's
 207: 	 * nothing else around it should go to).
 208: 	 */
 209:     case PRU_CONNECT:
 210:         if (rp->rcb_flags & RAW_FADDR) {
 211:             error = EISCONN;
 212:             break;
 213:         }
 214:         raw_connaddr(rp, nam);
 215:         soisconnected(so);
 216:         break;
 217: 
 218:     case PRU_CONNECT2:
 219:         error = EOPNOTSUPP;
 220:         goto release;
 221: 
 222:     case PRU_BIND:
 223:         if (rp->rcb_flags & RAW_LADDR) {
 224:             error = EINVAL;         /* XXX */
 225:             break;
 226:         }
 227:         error = raw_bind(so, nam);
 228:         break;
 229: 
 230:     case PRU_DISCONNECT:
 231:         if ((rp->rcb_flags & RAW_FADDR) == 0) {
 232:             error = ENOTCONN;
 233:             break;
 234:         }
 235:         raw_disconnect(rp);
 236:         soisdisconnected(so);
 237:         break;
 238: 
 239:     /*
 240: 	 * Mark the connection as being incapable of further input.
 241: 	 */
 242:     case PRU_SHUTDOWN:
 243:         socantsendmore(so);
 244:         break;
 245: 
 246:     /*
 247: 	 * Ship a packet out.  The appropriate raw output
 248: 	 * routine handles any massaging necessary.
 249: 	 */
 250:     case PRU_SEND:
 251:         if (nam) {
 252:             if (rp->rcb_flags & RAW_FADDR) {
 253:                 error = EISCONN;
 254:                 break;
 255:             }
 256:             raw_connaddr(rp, nam);
 257:         } else if ((rp->rcb_flags & RAW_FADDR) == 0) {
 258:             error = ENOTCONN;
 259:             break;
 260:         }
 261:         error = (*so->so_proto->pr_output)(m, so);
 262:         m = NULL;
 263:         if (nam)
 264:             rp->rcb_flags &= ~RAW_FADDR;
 265:         break;
 266: 
 267:     case PRU_ABORT:
 268:         raw_disconnect(rp);
 269:         sofree(so);
 270:         soisdisconnected(so);
 271:         break;
 272: 
 273:     case PRU_SENSE:
 274:         /*
 275: 		 * stat: don't bother with a blocksize.
 276: 		 */
 277:         return (0);
 278: 
 279:     /*
 280: 	 * Not supported.
 281: 	 */
 282:     case PRU_RCVOOB:
 283:     case PRU_RCVD:
 284:         return(EOPNOTSUPP);
 285: 
 286:     case PRU_LISTEN:
 287:     case PRU_ACCEPT:
 288:     case PRU_SENDOOB:
 289:         error = EOPNOTSUPP;
 290:         break;
 291: 
 292:     case PRU_SOCKADDR:
 293:         bcopy((caddr_t)&rp->rcb_laddr, mtod(nam, caddr_t),
 294:             sizeof (struct sockaddr));
 295:         nam->m_len = sizeof (struct sockaddr);
 296:         break;
 297: 
 298:     case PRU_PEERADDR:
 299:         bcopy((caddr_t)&rp->rcb_faddr, mtod(nam, caddr_t),
 300:             sizeof (struct sockaddr));
 301:         nam->m_len = sizeof (struct sockaddr);
 302:         break;
 303: 
 304:     default:
 305:         panic("raw_usrreq");
 306:     }
 307: release:
 308:     if (m != NULL)
 309:         m_freem(m);
 310:     return (error);
 311: }

Defined functions

raw_ctlinput defined in line 143; used 3 times
raw_init defined in line 27; used 2 times
rawintr defined in line 82; used 2 times

Defined macros

equal defined in line 109; used 2 times
Last modified: 1986-06-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1295
Valid CSS Valid XHTML 1.0 Strict