X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/14bdc762d5cf6e45a412f366bde68d8356421fc4..7a30136fd00a6fa090c44ea6b79978e2abfca99c:/usr/src/sys/netns/idp_usrreq.c diff --git a/usr/src/sys/netns/idp_usrreq.c b/usr/src/sys/netns/idp_usrreq.c index 8b01bd469f..8cbb8f2f74 100644 --- a/usr/src/sys/netns/idp_usrreq.c +++ b/usr/src/sys/netns/idp_usrreq.c @@ -1,4 +1,16 @@ -/* idp_usrreq.c 6.2 85/05/31 */ +/* + * Copyright (c) 1984, 1985, 1986, 1987 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that this notice is preserved and that due credit is given + * to the University of California at Berkeley. The name of the University + * may not be used to endorse or promote products derived from this + * software without specific prior written permission. This software + * is provided ``as is'' without express or implied warranty. + * + * @(#)idp_usrreq.c 7.2 (Berkeley) %G% + */ #include "param.h" #include "dir.h" @@ -15,6 +27,7 @@ #include "ns.h" #include "ns_pcb.h" +#include "ns_if.h" #include "idp.h" #include "idp_var.h" #include "ns_error.h" @@ -25,19 +38,34 @@ struct sockaddr_ns idp_ns = { AF_NS }; -idp_input(m, nsp) +/* + * This may also be called for raw listeners. + */ +idp_input(m, nsp, ifp) struct mbuf *m; register struct nspcb *nsp; + struct ifnet *ifp; { register struct idp *idp = mtod(m, struct idp *); - if (nsp==0) - panic("Impossible idp_input"); + if (nsp==0) + panic("No nspcb"); /* * Construct sockaddr format source address. * Stuff source address and datagram in user buffer. */ idp_ns.sns_addr = idp->idp_sna; + if (ns_neteqnn(idp->idp_sna.x_net, ns_zeronet) && ifp) { + register struct ifaddr *ia; + + for (ia = ifp->if_addrlist; ia; ia = ia->ifa_next) { + if (ia->ifa_addr.sa_family == AF_NS) { + idp_ns.sns_addr.x_net = + IA_SNS(ia)->sns_addr.x_net; + break; + } + } + } nsp->nsp_rpt = idp->idp_pt; if ( ! (nsp->nsp_flags & NSP_RAWIN) ) { m->m_len -= sizeof (struct idp); @@ -60,7 +88,32 @@ idp_abort(nsp) ns_pcbdisconnect(nsp); soisdisconnected(so); } +/* + * Drop connection, reporting + * the specified error. + */ +struct nspcb * +idp_drop(nsp, errno) + register struct nspcb *nsp; + int errno; +{ + struct socket *so = nsp->nsp_socket; + + /* + * someday, in the xerox world + * we will generate error protocol packets + * announcing that the socket has gone away. + */ + /*if (TCPS_HAVERCVDSYN(tp->t_state)) { + tp->t_state = TCPS_CLOSED; + (void) tcp_output(tp); + }*/ + so->so_error = errno; + ns_pcbdisconnect(nsp); + soisdisconnected(so); +} +int noIdpRoute; idp_output(nsp, m0) struct nspcb *nsp; struct mbuf *m0; @@ -115,7 +168,9 @@ idp_output(nsp, m0) m_freem(m0); return (ENOBUFS); } - m->m_off = MMAXOFF - sizeof (struct idp); + m->m_off = MMAXOFF - sizeof (struct idp) - 2; + /* adjust to start on longword bdry + for NSIP on gould */ m->m_len = sizeof (struct idp); m->m_next = m0; idp = mtod(m, struct idp *); @@ -144,22 +199,50 @@ idp_output(nsp, m0) (so->so_options & SO_BROADCAST) | NS_ROUTETOIF)); /* * Use cached route for previous datagram if - * this is also to the same destination. + * possible. If the previous net was the same + * and the interface was a broadcast medium, or + * if the previous destination was identical, + * then we are ok. * * NB: We don't handle broadcasts because that * would require 3 subroutine calls. */ ro = &nsp->nsp_route; - if (ro->ro_rt && - ((*(long *)&nsp->nsp_lastnet)!=ns_netof(idp->idp_dna)) && - !(ns_hosteq(satons_addr(ro->ro_dst), idp->idp_dna))) { - RTFREE(ro->ro_rt); - ro->ro_rt = (struct rtentry *)0; - nsp->nsp_lastnet = idp->idp_dna.x_net; +#ifdef ancient_history + /* + * I think that this will all be handled in ns_pcbconnect! + */ + if (ro->ro_rt) { + if(ns_neteq(nsp->nsp_lastdst, idp->idp_dna)) { + /* + * This assumes we have no GH type routes + */ + if (ro->ro_rt->rt_flags & RTF_HOST) { + if (!ns_hosteq(nsp->nsp_lastdst, idp->idp_dna)) + goto re_route; + + } + if ((ro->ro_rt->rt_flags & RTF_GATEWAY) == 0) { + register struct ns_addr *dst = + &satons_addr(ro->ro_dst); + dst->x_host = idp->idp_dna.x_host; + } + /* + * Otherwise, we go through the same gateway + * and dst is already set up. + */ + } else { + re_route: + RTFREE(ro->ro_rt); + ro->ro_rt = (struct rtentry *)0; + } } + nsp->nsp_lastdst = idp->idp_dna; +#endif ancient_history + if (noIdpRoute) ro = 0; return (ns_output(m, ro, so->so_options & SO_BROADCAST)); } -/*ARGSUSED*/ +/* ARGSUSED */ idp_ctloutput(req, so, level, name, value) int req, level; struct socket *so; @@ -169,23 +252,29 @@ idp_ctloutput(req, so, level, name, value) register struct mbuf *m; struct nspcb *nsp = sotonspcb(so); int mask, error = 0; + extern long ns_pexseq; - if (nsp == NULL) { - error = EINVAL; - goto release; - } + if (nsp == NULL) + return (EINVAL); switch (req) { + case PRCO_GETOPT: - if (value==NULL) { - error = EINVAL; - goto release; - } + if (value==NULL) + return (EINVAL); m = m_get(M_DONTWAIT, MT_DATA); + if (m==NULL) + return (ENOBUFS); switch (name) { + + case SO_ALL_PACKETS: + mask = NSP_ALL_PACKETS; + goto get_flags; + case SO_HEADERS_ON_INPUT: mask = NSP_RAWIN; goto get_flags; + case SO_HEADERS_ON_OUTPUT: mask = NSP_RAWOUT; get_flags: @@ -193,6 +282,7 @@ idp_ctloutput(req, so, level, name, value) m->m_off = MMAXOFF - sizeof(short); *mtod(m, short *) = nsp->nsp_flags & mask; break; + case SO_DEFAULT_HEADERS: m->m_len = sizeof(struct idp); m->m_off = MMAXOFF - sizeof(struct idp); @@ -205,16 +295,32 @@ idp_ctloutput(req, so, level, name, value) idp->idp_dna = nsp->nsp_faddr; idp->idp_sna = nsp->nsp_laddr; } + break; + + case SO_SEQNO: + m->m_len = sizeof(long); + m->m_off = MMAXOFF - sizeof(long); + *mtod(m, long *) = ns_pexseq++; + break; + + default: + error = EINVAL; } *value = m; break; + case PRCO_SETOPT: switch (name) { - int mask, *ok; + int *ok; + + case SO_ALL_PACKETS: + mask = NSP_ALL_PACKETS; + goto set_head; case SO_HEADERS_ON_INPUT: mask = NSP_RAWIN; goto set_head; + case SO_HEADERS_ON_OUTPUT: mask = NSP_RAWOUT; set_head: @@ -226,25 +332,28 @@ idp_ctloutput(req, so, level, name, value) nsp->nsp_flags &= ~mask; } else error = EINVAL; break; + case SO_DEFAULT_HEADERS: { register struct idp *idp = mtod(*value, struct idp *); nsp->nsp_dpt = idp->idp_pt; } -#ifdef NSIP break; +#ifdef NSIP + case SO_NSIP_ROUTE: error = nsip_route(*value); break; #endif NSIP + default: + error = EINVAL; } if (value && *value) m_freem(*value); break; } - release: - return(error); + return (error); } /*ARGSUSED*/ @@ -438,6 +547,6 @@ idp_raw_usrreq(so, req, m, nam, rights) default: error = idp_usrreq(so, req, m, nam, rights); } - return(error); + return (error); }