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

Defined functions

raw_ctlinput defined in line 147; never used
raw_init defined in line 31; never used
raw_input defined in line 41; never used
raw_usrreq defined in line 158; never used
rawintr defined in line 86; never used

Defined macros

equal defined in line 113; used 2 times
Last modified: 1988-04-28
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4040
Valid CSS Valid XHTML 1.0 Strict