# 2.11BSD#431 - /usr/src/sys/netns/idp_usrreq.c

##### Functions

    idp_abort         X
    idp_ctloutput     X
    idp_drop          X
    idp_input         X
    idp_output        X
    idp_raw_usrreq    X
    idp_usrreq        X

##### Variables

    idp_ns            X
    noIdpRoute        X

       1: /*
       2:  * Copyright (c) 1984, 1985, 1986, 1987 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:  *      @(#)idp_usrreq.c	7.2 (Berkeley) 1/20/88
      13:  */
      14:
      15: #include "param.h"
      16: #ifdef  NS
      17: #include "user.h"
      18: #include "mbuf.h"
      19: #include "protosw.h"
      20: #include "socket.h"
      21: #include "socketvar.h"
      22: #include "errno.h"
      23: #include "stat.h"
      24:
      25: #include "../net/if.h"
      26: #include "../net/route.h"
      27:
      28: #include "ns.h"
      29: #include "ns_pcb.h"
      30: #include "ns_if.h"
      31: #include "idp.h"
      32: #include "idp_var.h"
      33: #include "ns_error.h"
      34:
      35: /*
      36:  * IDP protocol implementation.
      37:  */
      38:
      39: struct  sockaddr_ns idp_ns = { AF_NS };
      40:
      41: /*
      42:  *  This may also be called for raw listeners.
      43:  */
      44: idp_input(m, nsp, ifp)
      45:     struct mbuf *m;
      46:     register struct nspcb *nsp;
      47:     struct ifnet *ifp;
      48: {
      49:     register struct idp *idp = mtod(m, struct idp *);
      50:
      51:     if (nsp==0)
      52:         panic("No nspcb");
      53:     /*
      54: 	 * Construct sockaddr format source address.
      55: 	 * Stuff source address and datagram in user buffer.
      56: 	 */
      57:     idp_ns.sns_addr = idp->idp_sna;
      58:     if (ns_neteqnn(idp->idp_sna.x_net, ns_zeronet) && ifp) {
      59:         register struct ifaddr *ia;
      60:
      61:         for (ia = ifp->if_addrlist; ia; ia = ia->ifa_next) {
      62:             if (ia->ifa_addr.sa_family == AF_NS) {
      63:                 idp_ns.sns_addr.x_net =
      64:                     IA_SNS(ia)->sns_addr.x_net;
      65:                 break;
      66:             }
      67:         }
      68:     }
      69:     nsp->nsp_rpt = idp->idp_pt;
      70:     if ( ! (nsp->nsp_flags & NSP_RAWIN) ) {
      71:         m->m_len -= sizeof (struct idp);
      72:         m->m_off += sizeof (struct idp);
      73:     }
      74:     if (sbappendaddr(&nsp->nsp_socket->so_rcv, (struct sockaddr *)&idp_ns,
      75:         m, (struct mbuf *)0) == 0)
      76:         goto bad;
      77:     sorwakeup(nsp->nsp_socket);
      78:     return;
      79: bad:
      80:     m_freem(m);
      81: }
      82:
      83: idp_abort(nsp)
      84:     struct nspcb *nsp;
      85: {
      86:     struct socket *so = nsp->nsp_socket;
      87:
      88:     ns_pcbdisconnect(nsp);
      89:     soisdisconnected(so);
      90: }
      91: /*
      92:  * Drop connection, reporting
      93:  * the specified error.
      94:  */
      95: struct nspcb *
      96: idp_drop(nsp, errno)
      97:     register struct nspcb *nsp;
      98:     int errno;
      99: {
     100:     struct socket *so = nsp->nsp_socket;
     101:
     102:     /*
     103: 	 * someday, in the xerox world
     104: 	 * we will generate error protocol packets
     105: 	 * announcing that the socket has gone away.
     106: 	 */
     107:     /*if (TCPS_HAVERCVDSYN(tp->t_state)) {
     108: 		tp->t_state = TCPS_CLOSED;
     109: 		(void) tcp_output(tp);
     110: 	}*/
     111:     so->so_error = errno;
     112:     ns_pcbdisconnect(nsp);
     113:     soisdisconnected(so);
     114: }
     115:
     116: int noIdpRoute;
     117: idp_output(nsp, m0)
     118:     struct nspcb *nsp;
     119:     struct mbuf *m0;
     120: {
     121:     register struct mbuf *m;
     122:     register struct idp *idp;
     123:     register struct socket *so;
     124:     register int len = 0;
     125:     register struct route *ro;
     126:     struct mbuf *mprev;
     127:     extern int idpcksum;
     128:
     129:     /*
     130: 	 * Calculate data length.
     131: 	 */
     132:     for (m = m0; m; m = m->m_next) {
     133:         mprev = m;
     134:         len += m->m_len;
     135:     }
     136:     /*
     137: 	 * Make sure packet is actually of even length.
     138: 	 */
     139:
     140:     if (len & 1) {
     141:         m = mprev;
     142:         if (m->m_len + m->m_off < MMAXOFF) {
     143:             m->m_len++;
     144:         } else {
     145:             struct mbuf *m1 = m_get(M_DONTWAIT, MT_DATA);
     146:
     147:             if (m1 == 0) {
     148:                 m_freem(m0);
     149:                 return (ENOBUFS);
     150:             }
     151:             m1->m_len = 1;
     152:             m1->m_off = MMAXOFF - 1;
     153:             * mtod(m1, char *) = 0;
     154:             m->m_next = m1;
     155:         }
     156:     }
     157:
     158:     /*
     159: 	 * Fill in mbuf with extended IDP header
     160: 	 * and addresses and length put into network format.
     161: 	 */
     162:     if (nsp->nsp_flags & NSP_RAWOUT) {
     163:         m = m0;
     164:         idp = mtod(m, struct idp *);
     165:     } else {
     166:         m = m_get(M_DONTWAIT, MT_HEADER);
     167:         if (m == 0) {
     168:             m_freem(m0);
     169:             return (ENOBUFS);
     170:         }
     171:         m->m_off = MMAXOFF - sizeof (struct idp) - 2;
     172:                 /* adjust to start on longword bdry
     173: 				   for NSIP on gould */
     174:         m->m_len = sizeof (struct idp);
     175:         m->m_next = m0;
     176:         idp = mtod(m, struct idp *);
     177:         idp->idp_tc = 0;
     178:         idp->idp_pt = nsp->nsp_dpt;
     179:         idp->idp_sna = nsp->nsp_laddr;
     180:         idp->idp_dna = nsp->nsp_faddr;
     181:         len += sizeof (struct idp);
     182:     }
     183:
     184:     idp->idp_len = htons((u_short)len);
     185:
     186:     if (idpcksum) {
     187:         idp->idp_sum = 0;
     188:         len = ((len - 1) | 1) + 1;
     189:         idp->idp_sum = ns_cksum(m, len);
     190:     } else
     191:         idp->idp_sum = 0xffff;
     192:
     193:     /*
     194: 	 * Output datagram.
     195: 	 */
     196:     so = nsp->nsp_socket;
     197:     if (so->so_options & SO_DONTROUTE)
     198:         return (ns_output(m, (struct route *)0,
     199:             (so->so_options & SO_BROADCAST) | NS_ROUTETOIF));
     200:     /*
     201: 	 * Use cached route for previous datagram if
     202: 	 * possible.  If the previous net was the same
     203: 	 * and the interface was a broadcast medium, or
     204: 	 * if the previous destination was identical,
     205: 	 * then we are ok.
     206: 	 *
     207: 	 * NB: We don't handle broadcasts because that
     208: 	 *     would require 3 subroutine calls.
     209: 	 */
     210:     ro = &nsp->nsp_route;
     211: #ifdef ancient_history
     212:     /*
     213: 	 * I think that this will all be handled in ns_pcbconnect!
     214: 	 */
     215:     if (ro->ro_rt) {
     216:         if(ns_neteq(nsp->nsp_lastdst, idp->idp_dna)) {
     217:             /*
     218: 			 * This assumes we have no GH type routes
     219: 			 */
     220:             if (ro->ro_rt->rt_flags & RTF_HOST) {
     221:                 if (!ns_hosteq(nsp->nsp_lastdst, idp->idp_dna))
     222:                     goto re_route;
     223:
     224:             }
     225:             if ((ro->ro_rt->rt_flags & RTF_GATEWAY) == 0) {
     226:                 register struct ns_addr *dst =
     227:                         &satons_addr(ro->ro_dst);
     228:                 dst->x_host = idp->idp_dna.x_host;
     229:             }
     230:             /*
     231: 			 * Otherwise, we go through the same gateway
     232: 			 * and dst is already set up.
     233: 			 */
     234:         } else {
     235:         re_route:
     236:             RTFREE(ro->ro_rt);
     237:             ro->ro_rt = (struct rtentry *)0;
     238:         }
     239:     }
     240:     nsp->nsp_lastdst = idp->idp_dna;
     241: #endif ancient_history
     242:     if (noIdpRoute) ro = 0;
     243:     return (ns_output(m, ro, so->so_options & SO_BROADCAST));
     244: }
     245: /* ARGSUSED */
     246: idp_ctloutput(req, so, level, name, value)
     247:     int req, level;
     248:     struct socket *so;
     249:     int name;
     250:     struct mbuf **value;
     251: {
     252:     register struct mbuf *m;
     253:     struct nspcb *nsp = sotonspcb(so);
     254:     int mask, error = 0;
     255:     extern long ns_pexseq;
     256:
     257:     if (nsp == NULL)
     258:         return (EINVAL);
     259:
     260:     switch (req) {
     261:
     262:     case PRCO_GETOPT:
     263:         if (value==NULL)
     264:             return (EINVAL);
     265:         m = m_get(M_DONTWAIT, MT_DATA);
     266:         if (m==NULL)
     267:             return (ENOBUFS);
     268:         switch (name) {
     269:
     270:         case SO_ALL_PACKETS:
     271:             mask = NSP_ALL_PACKETS;
     272:             goto get_flags;
     273:
     274:         case SO_HEADERS_ON_INPUT:
     275:             mask = NSP_RAWIN;
     276:             goto get_flags;
     277:
     278:         case SO_HEADERS_ON_OUTPUT:
     279:             mask = NSP_RAWOUT;
     280:         get_flags:
     281:             m->m_len = sizeof(short);
     282:             m->m_off = MMAXOFF - sizeof(short);
     283:             *mtod(m, short *) = nsp->nsp_flags & mask;
     284:             break;
     285:
     286:         case SO_DEFAULT_HEADERS:
     287:             m->m_len = sizeof(struct idp);
     288:             m->m_off = MMAXOFF - sizeof(struct idp);
     289:             {
     290:                 register struct idp *idp = mtod(m, struct idp *);
     291:                 idp->idp_len = 0;
     292:                 idp->idp_sum = 0;
     293:                 idp->idp_tc = 0;
     294:                 idp->idp_pt = nsp->nsp_dpt;
     295:                 idp->idp_dna = nsp->nsp_faddr;
     296:                 idp->idp_sna = nsp->nsp_laddr;
     297:             }
     298:             break;
     299:
     300:         case SO_SEQNO:
     301:             m->m_len = sizeof(long);
     302:             m->m_off = MMAXOFF - sizeof(long);
     303:             *mtod(m, long *) = ns_pexseq++;
     304:             break;
     305:
     306:         default:
     307:             error = EINVAL;
     308:         }
     309:         *value = m;
     310:         break;
     311:
     312:     case PRCO_SETOPT:
     313:         switch (name) {
     314:             int *ok;
     315:
     316:         case SO_ALL_PACKETS:
     317:             mask = NSP_ALL_PACKETS;
     318:             goto set_head;
     319:
     320:         case SO_HEADERS_ON_INPUT:
     321:             mask = NSP_RAWIN;
     322:             goto set_head;
     323:
     324:         case SO_HEADERS_ON_OUTPUT:
     325:             mask = NSP_RAWOUT;
     326:         set_head:
     327:             if (value && *value) {
     328:                 ok = mtod(*value, int *);
     329:                 if (*ok)
     330:                     nsp->nsp_flags |= mask;
     331:                 else
     332:                     nsp->nsp_flags &= ~mask;
     333:             } else error = EINVAL;
     334:             break;
     335:
     336:         case SO_DEFAULT_HEADERS:
     337:             {
     338:                 register struct idp *idp
     339:                     = mtod(*value, struct idp *);
     340:                 nsp->nsp_dpt = idp->idp_pt;
     341:             }
     342:             break;
     343: #ifdef NSIP
     344:
     345:         case SO_NSIP_ROUTE:
     346:             error = nsip_route(*value);
     347:             break;
     348: #endif NSIP
     349:         default:
     350:             error = EINVAL;
     351:         }
     352:         if (value && *value)
     353:             m_freem(*value);
     354:         break;
     355:     }
     356:     return (error);
     357: }
     358:
     359: /*ARGSUSED*/
     360: idp_usrreq(so, req, m, nam, rights)
     361:     struct socket *so;
     362:     int req;
     363:     struct mbuf *m, *nam, *rights;
     364: {
     365:     struct nspcb *nsp = sotonspcb(so);
     366:     int error = 0;
     367:
     368:     if (req == PRU_CONTROL)
     369:                 return (ns_control(so, (int)m, (caddr_t)nam,
     370:             (struct ifnet *)rights));
     371:     if (rights && rights->m_len) {
     372:         error = EINVAL;
     373:         goto release;
     374:     }
     375:     if (nsp == NULL && req != PRU_ATTACH) {
     376:         error = EINVAL;
     377:         goto release;
     378:     }
     379:     switch (req) {
     380:
     381:     case PRU_ATTACH:
     382:         if (nsp != NULL) {
     383:             error = EINVAL;
     384:             break;
     385:         }
     386:         error = ns_pcballoc(so, &nspcb);
     387:         if (error)
     388:             break;
     389:         error = soreserve(so, 2048, 2048);
     390:         if (error)
     391:             break;
     392:         break;
     393:
     394:     case PRU_DETACH:
     395:         if (nsp == NULL) {
     396:             error = ENOTCONN;
     397:             break;
     398:         }
     399:         ns_pcbdetach(nsp);
     400:         break;
     401:
     402:     case PRU_BIND:
     403:         error = ns_pcbbind(nsp, nam);
     404:         break;
     405:
     406:     case PRU_LISTEN:
     407:         error = EOPNOTSUPP;
     408:         break;
     409:
     410:     case PRU_CONNECT:
     411:         if (!ns_nullhost(nsp->nsp_faddr)) {
     412:             error = EISCONN;
     413:             break;
     414:         }
     415:         error = ns_pcbconnect(nsp, nam);
     416:         if (error == 0)
     417:             soisconnected(so);
     418:         break;
     419:
     420:     case PRU_CONNECT2:
     421:         error = EOPNOTSUPP;
     422:         break;
     423:
     424:     case PRU_ACCEPT:
     425:         error = EOPNOTSUPP;
     426:         break;
     427:
     428:     case PRU_DISCONNECT:
     429:         if (ns_nullhost(nsp->nsp_faddr)) {
     430:             error = ENOTCONN;
     431:             break;
     432:         }
     433:         ns_pcbdisconnect(nsp);
     434:         soisdisconnected(so);
     435:         break;
     436:
     437:     case PRU_SHUTDOWN:
     438:         socantsendmore(so);
     439:         break;
     440:
     441:     case PRU_SEND:
     442:     {
     443:         struct ns_addr laddr;
     444:         int s;
     445:
     446:         if (nam) {
     447:             laddr = nsp->nsp_laddr;
     448:             if (!ns_nullhost(nsp->nsp_faddr)) {
     449:                 error = EISCONN;
     450:                 break;
     451:             }
     452:             /*
     453: 			 * Must block input while temporarily connected.
     454: 			 */
     455:             s = splnet();
     456:             error = ns_pcbconnect(nsp, nam);
     457:             if (error) {
     458:                 splx(s);
     459:                 break;
     460:             }
     461:         } else {
     462:             if (ns_nullhost(nsp->nsp_faddr)) {
     463:                 error = ENOTCONN;
     464:                 break;
     465:             }
     466:         }
     467:         error = idp_output(nsp, m);
     468:         m = NULL;
     469:         if (nam) {
     470:             ns_pcbdisconnect(nsp);
     471:             splx(s);
     472:             nsp->nsp_laddr.x_host = laddr.x_host;
     473:             nsp->nsp_laddr.x_port = laddr.x_port;
     474:         }
     475:     }
     476:         break;
     477:
     478:     case PRU_ABORT:
     479:         ns_pcbdetach(nsp);
     480:         sofree(so);
     481:         soisdisconnected(so);
     482:         break;
     483:
     484:     case PRU_SOCKADDR:
     485:         ns_setsockaddr(nsp, nam);
     486:         break;
     487:
     488:     case PRU_PEERADDR:
     489:         ns_setpeeraddr(nsp, nam);
     490:         break;
     491:
     492:     case PRU_SENSE:
     493:         /*
     494: 		 * stat: don't bother with a blocksize.
     495: 		 */
     496:         return (0);
     497:
     498:     case PRU_SENDOOB:
     499:     case PRU_FASTTIMO:
     500:     case PRU_SLOWTIMO:
     501:     case PRU_PROTORCV:
     502:     case PRU_PROTOSEND:
     503:         error =  EOPNOTSUPP;
     504:         break;
     505:
     506:     case PRU_CONTROL:
     507:     case PRU_RCVD:
     508:     case PRU_RCVOOB:
     509:         return (EOPNOTSUPP);    /* do not free mbuf's */
     510:
     511:     default:
     512:         panic("idp_usrreq");
     513:     }
     514: release:
     515:     if (m != NULL)
     516:         m_freem(m);
     517:     return (error);
     518: }
     519: /*ARGSUSED*/
     520: idp_raw_usrreq(so, req, m, nam, rights)
     521:     struct socket *so;
     522:     int req;
     523:     struct mbuf *m, *nam, *rights;
     524: {
     525:     int error = 0;
     526:     struct nspcb *nsp = sotonspcb(so);
     527:     extern struct nspcb nsrawpcb;
     528:
     529:     switch (req) {
     530:
     531:     case PRU_ATTACH:
     532:
     533:         if (!suser() || (nsp != NULL)) {
     534:             error = EINVAL;
     535:             break;
     536:         }
     537:         error = ns_pcballoc(so, &nsrawpcb);
     538:         if (error)
     539:             break;
     540:         error = soreserve(so, 2048, 2048);
     541:         if (error)
     542:             break;
     543:         nsp = sotonspcb(so);
     544:         nsp->nsp_faddr.x_host = ns_broadhost;
     545:         nsp->nsp_flags = NSP_RAWIN | NSP_RAWOUT;
     546:         break;
     547:     default:
     548:         error = idp_usrreq(so, req, m, nam, rights);
     549:     }
     550:     return (error);
     551: }
     552: #endif

#### Defined functions

idp_abort defined in line 83; never used
idp_ctloutput defined in line 246; never used
idp_drop defined in line 95; never used
idp_input defined in line 44; never used
idp_output defined in line 117; used 1 times

- in line 467

idp_raw_usrreq defined in line 520; never used
idp_usrreq defined in line 360; used 1 times

- in line 548

#### Defined variables

idp_ns defined in line 39; used 3 times

- in line 57, 63, 74

noIdpRoute defined in line 116; used 1 times

- in line 242

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