# 2.11BSD#431 - /usr/src/sys/net/raw_usrreq.c

##### Functions

    raw_ctlinput      X
    raw_init          X
    raw_input         X
    raw_usrreq        X
    rawintr           X

##### Macros

    equal             X

       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

- in line 116-119(2)

Last modified: 1988-04-28 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1603 |