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

##### Functions

    ns_pcballoc       X
    ns_pcbbind        X
    ns_pcbconnect     X
    ns_pcbdetach      X
    ns_pcbdisconnect  X
    ns_pcblookup      X
    ns_pcbnotify      X
    ns_rtchange       X
    ns_setpeeraddr    X
    ns_setsockaddr    X

##### Variables

    zerons_addr       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:  *      @(#)ns_pcb.c	7.3 (Berkeley) 1/20/88
      13:  */
      14:
      15: #include "param.h"
      16: #ifdef  NS
      17: #include "systm.h"
      18: #include "user.h"
      19: #include "mbuf.h"
      20: #include "socket.h"
      21: #include "socketvar.h"
      22: #include "../net/if.h"
      23: #include "../net/route.h"
      24: #include "protosw.h"
      25:
      26: #include "ns.h"
      27: #include "ns_if.h"
      28: #include "ns_pcb.h"
      29:
      30: struct  ns_addr zerons_addr;
      31:
      32: ns_pcballoc(so, head)
      33:     struct socket *so;
      34:     struct nspcb *head;
      35: {
      36:     struct mbuf *m;
      37:     register struct nspcb *nsp;
      38:
      39:     m = m_getclr(M_DONTWAIT, MT_PCB);
      40:     if (m == NULL)
      41:         return (ENOBUFS);
      42:     nsp = mtod(m, struct nspcb *);
      43:     nsp->nsp_socket = so;
      44:     insque(nsp, head);
      45:     so->so_pcb = (caddr_t)nsp;
      46:     return (0);
      47: }
      48:
      49: ns_pcbbind(nsp, nam)
      50:     register struct nspcb *nsp;
      51:     struct mbuf *nam;
      52: {
      53:     register struct sockaddr_ns *sns;
      54:     u_short lport = 0;
      55:
      56:     if(nsp->nsp_lport || !ns_nullhost(nsp->nsp_laddr))
      57:         return (EINVAL);
      58:     if (nam == 0)
      59:         goto noname;
      60:     sns = mtod(nam, struct sockaddr_ns *);
      61:     if (nam->m_len != sizeof (*sns))
      62:         return (EINVAL);
      63:     if (!ns_nullhost(sns->sns_addr)) {
      64:         int tport = sns->sns_port;
      65:
      66:         sns->sns_port = 0;      /* yech... */
      67:         if (ifa_ifwithaddr((struct sockaddr *)sns) == 0)
      68:             return (EADDRNOTAVAIL);
      69:         sns->sns_port = tport;
      70:     }
      71:     lport = sns->sns_port;
      72:     if (lport) {
      73:         u_short aport = ntohs(lport);
      74:
      75:         if (aport < NSPORT_RESERVED && u.u_uid != 0)
      76:             return (EACCES);
      77:         if (ns_pcblookup(&zerons_addr, lport, 0))
      78:             return (EADDRINUSE);
      79:     }
      80:     nsp->nsp_laddr = sns->sns_addr;
      81: noname:
      82:     if (lport == 0)
      83:         do {
      84:             if (nspcb.nsp_lport++ < NSPORT_RESERVED)
      85:                 nspcb.nsp_lport = NSPORT_RESERVED;
      86:             lport = htons(nspcb.nsp_lport);
      87:         } while (ns_pcblookup(&zerons_addr, lport, 0));
      88:     nsp->nsp_lport = lport;
      89:     return (0);
      90: }
      91:
      92: /*
      93:  * Connect from a socket to a specified address.
      94:  * Both address and port must be specified in argument sns.
      95:  * If don't have a local address for this socket yet,
      96:  * then pick one.
      97:  */
      98: ns_pcbconnect(nsp, nam)
      99:     struct nspcb *nsp;
     100:     struct mbuf *nam;
     101: {
     102:     struct ns_ifaddr *ia;
     103:     register struct sockaddr_ns *sns = mtod(nam, struct sockaddr_ns *);
     104:     struct sockaddr_ns *ifaddr;
     105:     register struct ns_addr *dst;
     106:
     107:     if (nam->m_len != sizeof (*sns))
     108:         return (EINVAL);
     109:     if (sns->sns_family != AF_NS)
     110:         return (EAFNOSUPPORT);
     111:     if (sns->sns_port==0 || ns_nullhost(sns->sns_addr))
     112:         return (EADDRNOTAVAIL);
     113:     if (ns_nullhost(nsp->nsp_laddr)) {
     114:         register struct route *ro;
     115:         struct ifnet *ifp;
     116:         /*
     117: 		 * If route is known or can be allocated now,
     118: 		 * our src addr is taken from the i/f, else punt.
     119: 		 */
     120:         ro = &nsp->nsp_route;
     121:         dst = &satons_addr(ro->ro_dst);
     122:
     123:         ia = (struct ns_ifaddr *)0;
     124:         if (ro->ro_rt) {
     125:             if ((!ns_neteq(nsp->nsp_lastdst, sns->sns_addr)) ||
     126:             ((ifp = ro->ro_rt->rt_ifp) &&
     127:              (ifp->if_flags & IFF_POINTOPOINT) &&
     128:              (!ns_hosteq(nsp->nsp_lastdst, sns->sns_addr))) ||
     129:             (nsp->nsp_socket->so_options & SO_DONTROUTE)) {
     130:                 RTFREE(ro->ro_rt);
     131:                 ro->ro_rt = (struct rtentry *)0;
     132:             }
     133:         }
     134:         if ((nsp->nsp_socket->so_options & SO_DONTROUTE) == 0 && /*XXX*/
     135:             (ro->ro_rt == (struct rtentry *)0 ||
     136:              ro->ro_rt->rt_ifp == (struct ifnet *)0)) {
     137:                 /* No route yet, so try to acquire one */
     138:                 ro->ro_dst.sa_family = AF_NS;
     139:                 *dst = sns->sns_addr;
     140:                 dst->x_port = 0;
     141:                 rtalloc(ro);
     142:         }
     143:         /*
     144: 		 * If we found a route, use the address
     145: 		 * corresponding to the outgoing interface
     146: 		 */
     147:         if (ro->ro_rt && (ifp = ro->ro_rt->rt_ifp))
     148:             for (ia = ns_ifaddr; ia; ia = ia->ia_next)
     149:                 if (ia->ia_ifp == ifp)
     150:                     break;
     151:         if (ia == 0) {
     152:             u_short fport = sns->sns_addr.x_port;
     153:             sns->sns_addr.x_port = 0;
     154:             ia = (struct ns_ifaddr *)
     155:                 ifa_ifwithdstaddr((struct sockaddr *)sns);
     156:             sns->sns_addr.x_port = fport;
     157:             if (ia == 0)
     158:                 ia = ns_iaonnetof(&sns->sns_addr);
     159:             if (ia == 0)
     160:                 ia = ns_ifaddr;
     161:             if (ia == 0)
     162:                 return (EADDRNOTAVAIL);
     163:         }
     164:         nsp->nsp_laddr.x_net = satons_addr(ia->ia_addr).x_net;
     165:         nsp->nsp_lastdst = sns->sns_addr;
     166:     }
     167:     if (ns_pcblookup(&sns->sns_addr, nsp->nsp_lport, 0))
     168:         return (EADDRINUSE);
     169:     if (ns_nullhost(nsp->nsp_laddr)) {
     170:         if (nsp->nsp_lport == 0)
     171:             (void) ns_pcbbind(nsp, (struct mbuf *)0);
     172:         nsp->nsp_laddr.x_host = ns_thishost;
     173:     }
     174:     nsp->nsp_faddr = sns->sns_addr;
     175:     /* Includes nsp->nsp_fport = sns->sns_port; */
     176:     return (0);
     177: }
     178:
     179: ns_pcbdisconnect(nsp)
     180:     struct nspcb *nsp;
     181: {
     182:
     183:     nsp->nsp_faddr = zerons_addr;
     184:     if (nsp->nsp_socket->so_state & SS_NOFDREF)
     185:         ns_pcbdetach(nsp);
     186: }
     187:
     188: ns_pcbdetach(nsp)
     189:     struct nspcb *nsp;
     190: {
     191:     struct socket *so = nsp->nsp_socket;
     192:
     193:     so->so_pcb = 0;
     194:     sofree(so);
     195:     if (nsp->nsp_route.ro_rt)
     196:         rtfree(nsp->nsp_route.ro_rt);
     197:     remque(nsp);
     198:     (void) m_free(dtom(nsp));
     199: }
     200:
     201: ns_setsockaddr(nsp, nam)
     202:     register struct nspcb *nsp;
     203:     struct mbuf *nam;
     204: {
     205:     register struct sockaddr_ns *sns = mtod(nam, struct sockaddr_ns *);
     206:
     207:     nam->m_len = sizeof (*sns);
     208:     sns = mtod(nam, struct sockaddr_ns *);
     209:     bzero((caddr_t)sns, sizeof (*sns));
     210:     sns->sns_family = AF_NS;
     211:     sns->sns_addr = nsp->nsp_laddr;
     212: }
     213:
     214: ns_setpeeraddr(nsp, nam)
     215:     register struct nspcb *nsp;
     216:     struct mbuf *nam;
     217: {
     218:     register struct sockaddr_ns *sns = mtod(nam, struct sockaddr_ns *);
     219:
     220:     nam->m_len = sizeof (*sns);
     221:     sns = mtod(nam, struct sockaddr_ns *);
     222:     bzero((caddr_t)sns, sizeof (*sns));
     223:     sns->sns_family = AF_NS;
     224:     sns->sns_addr  = nsp->nsp_faddr;
     225: }
     226:
     227: /*
     228:  * Pass some notification to all connections of a protocol
     229:  * associated with address dst.  Call the
     230:  * protocol specific routine to handle each connection.
     231:  * Also pass an extra paramter via the nspcb. (which may in fact
     232:  * be a parameter list!)
     233:  */
     234: ns_pcbnotify(dst, errno, notify, param)
     235:     register struct ns_addr *dst;
     236:     long param;
     237:     int errno, (*notify)();
     238: {
     239:     register struct nspcb *nsp, *oinp;
     240:     int s = splimp();
     241:
     242:     for (nsp = (&nspcb)->nsp_next; nsp != (&nspcb);) {
     243:         if (!ns_hosteq(*dst,nsp->nsp_faddr)) {
     244:     next:
     245:             nsp = nsp->nsp_next;
     246:             continue;
     247:         }
     248:         if (nsp->nsp_socket == 0)
     249:             goto next;
     250:         if (errno)
     251:             nsp->nsp_socket->so_error = errno;
     252:         oinp = nsp;
     253:         nsp = nsp->nsp_next;
     254:         oinp->nsp_notify_param = param;
     255:         (*notify)(oinp);
     256:     }
     257:     splx(s);
     258: }
     259:
     260: #ifdef notdef
     261: /*
     262:  * After a routing change, flush old routing
     263:  * and allocate a (hopefully) better one.
     264:  */
     265: ns_rtchange(nsp)
     266:     struct nspcb *nsp;
     267: {
     268:     if (nsp->nsp_route.ro_rt) {
     269:         rtfree(nsp->nsp_route.ro_rt);
     270:         nsp->nsp_route.ro_rt = 0;
     271:         /*
     272: 		 * A new route can be allocated the next time
     273: 		 * output is attempted.
     274: 		 */
     275:     }
     276:     /* SHOULD NOTIFY HIGHER-LEVEL PROTOCOLS */
     277: }
     278: #endif
     279:
     280: struct nspcb *
     281: ns_pcblookup(faddr, lport, wildp)
     282:     struct ns_addr *faddr;
     283:     u_short lport;
     284: {
     285:     register struct nspcb *nsp, *match = 0;
     286:     int matchwild = 3, wildcard;
     287:     u_short fport;
     288:
     289:     fport = faddr->x_port;
     290:     for (nsp = (&nspcb)->nsp_next; nsp != (&nspcb); nsp = nsp->nsp_next) {
     291:         if (nsp->nsp_lport != lport)
     292:             continue;
     293:         wildcard = 0;
     294:         if (ns_nullhost(nsp->nsp_faddr)) {
     295:             if (!ns_nullhost(*faddr))
     296:                 wildcard++;
     297:         } else {
     298:             if (ns_nullhost(*faddr))
     299:                 wildcard++;
     300:             else {
     301:                 if (!ns_hosteq(nsp->nsp_faddr, *faddr))
     302:                     continue;
     303:                 if( nsp->nsp_fport != fport) {
     304:                     if(nsp->nsp_fport != 0)
     305:                         continue;
     306:                     else
     307:                         wildcard++;
     308:                 }
     309:             }
     310:         }
     311:         if (wildcard && wildp==0)
     312:             continue;
     313:         if (wildcard < matchwild) {
     314:             match = nsp;
     315:             matchwild = wildcard;
     316:             if (wildcard == 0)
     317:                 break;
     318:         }
     319:     }
     320:     return (match);
     321: }
     322: #endif

#### Defined functions

ns_pcballoc defined in line 32; never used
ns_pcbbind defined in line 49; used 1 times

- in line 171

ns_pcbconnect defined in line 98; never used
ns_pcbdetach defined in line 188; used 1 times

- in line 185

ns_pcbdisconnect defined in line 179; never used
ns_pcblookup defined in line 280; used 3 times

- in line 77, 87, 167

ns_pcbnotify defined in line 234; never used
ns_rtchange defined in line 265; never used
ns_setpeeraddr defined in line 214; never used
ns_setsockaddr defined in line 201; never used

#### Defined variables

zerons_addr defined in line 30; used 3 times

- in line 77, 87, 183

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