From a50e2bc0330585d6e6933634e24e7e9d6b5ef924 Mon Sep 17 00:00:00 2001 From: Keith Sklower Date: Sat, 22 Apr 1989 18:55:51 -0800 Subject: [PATCH] Checkpoint as of first successful tp connection, before posix, & before mckusick starts incorporating gnodes SCCS-vsn: sys/netiso/argo_debug.h 7.2 SCCS-vsn: sys/netiso/clnl.h 7.2 SCCS-vsn: sys/netiso/clnp.h 7.4 SCCS-vsn: sys/netiso/clnp_debug.c 7.2 SCCS-vsn: sys/netiso/clnp_er.c 7.3 SCCS-vsn: sys/netiso/clnp_frag.c 7.3 SCCS-vsn: sys/netiso/clnp_input.c 7.4 SCCS-vsn: sys/netiso/clnp_options.c 7.3 SCCS-vsn: sys/netiso/clnp_output.c 7.3 SCCS-vsn: sys/netiso/clnp_raw.c 7.2 SCCS-vsn: sys/netiso/clnp_stat.h 7.2 SCCS-vsn: sys/netiso/clnp_subr.c 7.4 SCCS-vsn: sys/netiso/clnp_timer.c 7.2 SCCS-vsn: sys/netiso/cons.h 7.2 SCCS-vsn: sys/netiso/cons_pcb.h 7.2 SCCS-vsn: sys/netiso/eonvar.h 7.2 SCCS-vsn: sys/netiso/esis.c 7.2 SCCS-vsn: sys/netiso/esis.h 7.2 SCCS-vsn: sys/netiso/if_clnp.h 7.2 SCCS-vsn: sys/netiso/if_cons.c 7.2 SCCS-vsn: sys/netiso/if_eon.c 7.2 SCCS-vsn: sys/netiso/if_lpb.c 7.2 SCCS-vsn: sys/netiso/iso.c 7.2 SCCS-vsn: sys/netiso/iso.h 7.2 SCCS-vsn: sys/netiso/iso_addrs.c 7.2 SCCS-vsn: sys/netiso/iso_chksum.c 7.2 SCCS-vsn: sys/netiso/iso_errno.h 7.2 SCCS-vsn: sys/netiso/iso_map.h 7.2 SCCS-vsn: sys/netiso/iso_pcb.c 7.2 SCCS-vsn: sys/netiso/iso_pcb.h 7.2 SCCS-vsn: sys/netiso/iso_proto.c 7.2 SCCS-vsn: sys/netiso/iso_snpac.c 7.2 SCCS-vsn: sys/netiso/iso_snpac.h 7.2 SCCS-vsn: sys/netiso/iso_usrreq.c 7.2 SCCS-vsn: sys/netiso/iso_var.h 7.2 SCCS-vsn: sys/netiso/tp.trans 7.2 SCCS-vsn: sys/netiso/tp_astring.c 7.2 SCCS-vsn: sys/netiso/tp_clnp.h 7.2 SCCS-vsn: sys/netiso/tp_cons.c 7.2 SCCS-vsn: sys/netiso/tp_emit.c 7.2 SCCS-vsn: sys/netiso/tp_inet.c 7.2 SCCS-vsn: sys/netiso/tp_input.c 7.2 SCCS-vsn: sys/netiso/tp_ip.h 7.2 SCCS-vsn: sys/netiso/tp_iso.c 7.2 SCCS-vsn: sys/netiso/tp_meas.c 7.2 SCCS-vsn: sys/netiso/tp_meas.h 7.2 SCCS-vsn: sys/netiso/tp_output.c 7.2 SCCS-vsn: sys/netiso/tp_param.h 7.2 SCCS-vsn: sys/netiso/tp_pcb.c 7.2 SCCS-vsn: sys/netiso/tp_pcb.h 7.2 SCCS-vsn: sys/netiso/tp_seq.h 7.2 SCCS-vsn: sys/netiso/tp_sizes.c 7.2 SCCS-vsn: sys/netiso/tp_stat.h 7.2 SCCS-vsn: sys/netiso/tp_subr.c 7.2 SCCS-vsn: sys/netiso/tp_subr2.c 7.2 SCCS-vsn: sys/netiso/tp_timer.c 7.2 SCCS-vsn: sys/netiso/tp_timer.h 7.2 SCCS-vsn: sys/netiso/tp_tpdu.h 7.2 SCCS-vsn: sys/netiso/tp_trace.c 7.2 SCCS-vsn: sys/netiso/tp_trace.h 7.2 SCCS-vsn: sys/netiso/tp_user.h 7.2 SCCS-vsn: sys/netiso/tp_usrreq.c 7.2 --- usr/src/sys/netiso/argo_debug.h | 34 +- usr/src/sys/netiso/clnp.h | 54 ++- usr/src/sys/netiso/clnp_debug.c | 65 +-- usr/src/sys/netiso/clnp_er.c | 66 ++- usr/src/sys/netiso/clnp_frag.c | 41 +- usr/src/sys/netiso/clnp_input.c | 108 +++-- usr/src/sys/netiso/clnp_options.c | 8 +- usr/src/sys/netiso/clnp_output.c | 126 +++--- usr/src/sys/netiso/clnp_raw.c | 210 +++++----- usr/src/sys/netiso/clnp_stat.h | 6 +- usr/src/sys/netiso/clnp_subr.c | 179 ++++----- usr/src/sys/netiso/clnp_timer.c | 24 +- usr/src/sys/netiso/eonvar.h | 35 +- usr/src/sys/netiso/esis.c | 338 ++++++++-------- usr/src/sys/netiso/esis.h | 24 +- usr/src/sys/netiso/if_eon.c | 293 +++++++------- usr/src/sys/netiso/if_lpb.c | 4 +- usr/src/sys/netiso/iso.c | 642 ++++++++++++++---------------- usr/src/sys/netiso/iso.h | 27 +- usr/src/sys/netiso/iso_chksum.c | 35 +- usr/src/sys/netiso/iso_pcb.c | 359 ++++++++--------- usr/src/sys/netiso/iso_pcb.h | 36 +- usr/src/sys/netiso/iso_proto.c | 16 +- usr/src/sys/netiso/iso_snpac.c | 236 ++++++----- usr/src/sys/netiso/iso_snpac.h | 8 +- usr/src/sys/netiso/iso_usrreq.c | 27 +- usr/src/sys/netiso/iso_var.h | 97 ++++- usr/src/sys/netiso/tp.trans | 118 +++--- usr/src/sys/netiso/tp_cons.c | 24 +- usr/src/sys/netiso/tp_emit.c | 91 +++-- usr/src/sys/netiso/tp_inet.c | 180 +++++---- usr/src/sys/netiso/tp_input.c | 208 +++++----- usr/src/sys/netiso/tp_iso.c | 289 ++++++++------ usr/src/sys/netiso/tp_meas.c | 5 +- usr/src/sys/netiso/tp_meas.h | 5 + usr/src/sys/netiso/tp_output.c | 112 ++---- usr/src/sys/netiso/tp_param.h | 6 +- usr/src/sys/netiso/tp_pcb.c | 156 +++----- usr/src/sys/netiso/tp_pcb.h | 82 ++-- usr/src/sys/netiso/tp_sizes.c | 138 ++----- usr/src/sys/netiso/tp_stat.h | 3 +- usr/src/sys/netiso/tp_subr.c | 180 ++------- usr/src/sys/netiso/tp_subr2.c | 156 +++++--- usr/src/sys/netiso/tp_timer.c | 24 +- usr/src/sys/netiso/tp_tpdu.h | 13 +- usr/src/sys/netiso/tp_trace.c | 26 +- usr/src/sys/netiso/tp_user.h | 14 + usr/src/sys/netiso/tp_usrreq.c | 357 ++++++++--------- 48 files changed, 2589 insertions(+), 2696 deletions(-) diff --git a/usr/src/sys/netiso/argo_debug.h b/usr/src/sys/netiso/argo_debug.h index 95b7bcaeeb..1a2bdbd523 100644 --- a/usr/src/sys/netiso/argo_debug.h +++ b/usr/src/sys/netiso/argo_debug.h @@ -1,5 +1,4 @@ -/*********************************************************** - Copyright IBM Corporation 1987 +/*********************************************************** Copyright IBM Corporation 1987 All Rights Reserved @@ -27,10 +26,12 @@ SOFTWARE. /* * $Header: argo_debug.h,v 4.6 88/07/19 15:53:40 hagens Exp $ * $Source: /usr/argo/sys/netiso/RCS/argo_debug.h,v $ + * @(#)argo_debug.h 7.2 (Berkeley) %G% */ #ifndef __ARGO_DEBUG__ #define __ARGO_DEBUG__ +#define dump_buf(a, b) Dump_buf((caddr_t)(a), (int)(b)) /*********************************************** * Lint stuff @@ -40,21 +41,27 @@ SOFTWARE. * lint can't handle the flaky vacuous definitions * of IFDEBUG, ENDDEBUG, etc. */ -#ifndef TPPT -#define TPPT -#endif TPPT - -#ifndef ARGO_DEBUG -#define ARGO_DEBUG -#endif ARGO_DEBUG - #endif defined(lint) /*********************************************** * DEBUG ON: **********************************************/ +#ifndef ARGO_DEBUG +#define ARGO_DEBUG +#endif ARGO_DEBUG + #ifdef ARGO_DEBUG +/* + #ifndef TPPT + #define TPPT + #endif TPPT + + #ifndef TP_PERF_MEAS + #define TP_PERF_MEAS + #endif TP_PERF_MEAS +*/ + unsigned char argo_debug[128]; #define IFDEBUG(ascii) \ @@ -213,8 +220,10 @@ void dump_mbuf(); /*********************************************** * New mbuf types for debugging w/ netstat -m + * This messes up 4.4 malloc for now. need bigger + * mbtypes array for now. **********************************************/ -#ifdef ARGO_DEBUG +#ifdef notdef #define TPMT_DATA 0x21 #define TPMT_RCVRTC 0x42 @@ -236,8 +245,7 @@ void dump_mbuf(); #define TPMT_TPHDR MT_HEADER #define TPMT_SONAME MT_SONAME /* MT_EOT and MT_XPD are defined in tp_param.h */ -#define TPMT_EOT MT_EOT -#define TPMT_XPD MT_XPD +#define TPMT_XPD MT_OOBDATA #define TPMT_PCB MT_PCB #define TPMT_PERF MT_PCB diff --git a/usr/src/sys/netiso/clnp.h b/usr/src/sys/netiso/clnp.h index 2ebe420fd1..84a7e43a5d 100644 --- a/usr/src/sys/netiso/clnp.h +++ b/usr/src/sys/netiso/clnp.h @@ -26,7 +26,7 @@ SOFTWARE. */ /* $Header: /var/src/sys/netiso/RCS/clnp.h,v 5.1 89/02/09 16:17:22 hagens Exp $ */ /* $Source: /var/src/sys/netiso/RCS/clnp.h,v $ */ -/* @(#)clnp.h 7.3 (Berkeley) %G% */ +/* @(#)clnp.h 7.4 (Berkeley) %G% */ #ifndef BYTE_ORDER /* @@ -79,23 +79,18 @@ struct clnp_fixed { u_char cnf_hdr_len; /* length indicator (octets) */ u_char cnf_vers; /* version/protocol identifier extension */ u_char cnf_ttl; /* lifetime (500 milliseconds) */ -#if BYTE_ORDER == LITTLE_ENDIAN - u_char cnf_type:5, /* type code */ - cnf_err_ok:1, /* flag: error report */ - cnf_more_segs:1, /* flag: more segments */ - cnf_seg_ok:1; /* flag: segmentation permitted */ -#endif -#if BYTE_ORDER == BIG_ENDIAN - u_char cnf_seg_ok:1, /* flag: segmentation permitted */ - cnf_more_segs:1, /* flag: more segments */ - cnf_err_ok:1, /* flag: error report */ - cnf_type:5; /* type code */ -#endif + u_char cnf_type; /* type code */ + /* Includes err_ok, more_segs, and seg_ok */ u_char cnf_seglen_msb; /* pdu segment length (octets) high byte */ u_char cnf_seglen_lsb; /* pdu segment length (octets) low byte */ u_char cnf_cksum_msb; /* checksum high byte */ u_char cnf_cksum_lsb; /* checksum low byte */ }; +#define CNF_TYPE 0x1f +#define CNF_ERR_OK 0x20 +#define CNF_MORE_SEGS 0x40 +#define CNF_SEG_OK 0x80 + #define CLNP_CKSUM_OFF 0x07 /* offset of checksum */ #define clnl_fixed clnp_fixed @@ -177,13 +172,24 @@ struct clnp_optidx { char cni_qos_len; /* length of entire qos option */ u_char cni_er_reason; /* reason from ER pdu option */ + + /* ESIS options */ + + u_short cni_esct; /* value from ISH ESCT option */ + + u_short cni_netmaskp; /* ptr to beginning of netmask option */ + char cni_netmask_len; /* length of entire netmask option */ + + u_short cni_snpamaskp; /* ptr to beginning of snpamask option */ + char cni_snpamask_len; /* length of entire snpamask option */ + }; #define ER_INVALREAS 0xff /* code for invalid ER pdu discard reason */ /* given an mbuf and addr of option, return offset from data of mbuf */ #define CLNP_OPTTOOFF(m, opt)\ - ((u_short) (opts - mtod(m, caddr_t))) + ((u_short) (opt - mtod(m, caddr_t))) /* given an mbuf and offset of option, return address of option */ #define CLNP_OFFTOOPT(m, off)\ @@ -340,15 +346,19 @@ struct troll { }; #define SN_OUTPUT(clcp, m)\ - troll_output(clcp->clc_ifp, m, clcp->clc_firsthop) + troll_output(clcp->clc_ifa->ia_ifp, m, clcp->clc_firsthop) #define SN_MTU(ifp)\ (ifp->if_mtu - trollctl.tr_mtu_adj) +#ifdef KERNEL +extern float troll_random; +#endif + #else /* NO TROLL */ #define SN_OUTPUT(clcp, m)\ - (*clcp->clc_ifp->if_output)(clcp->clc_ifp, m, clcp->clc_firsthop) + (*clcp->clc_ifa->ia_ifp->if_output)(clcp->clc_ifa->ia_ifp, m, clcp->clc_firsthop) #define SN_MTU(ifp)\ (ifp->if_mtu) @@ -365,7 +375,7 @@ struct troll { (isoa.isoa_len > 20) || (isoa.isoa_len == 0)) {\ hoff = (caddr_t)0;\ } else {\ - (void) bcopy(hoff, (caddr_t)&isoa, isoa.isoa_len);\ + (void) bcopy(hoff, (caddr_t)isoa.isoa_genaddr, isoa.isoa_len);\ hoff += isoa.isoa_len;\ }\ } @@ -373,10 +383,10 @@ struct troll { /* * Macro to insert an address into a clnp header */ -#define CLNP_INSERT_ADDR(hoff, isoap)\ - *hoff++ = (isoap)->isoa_len;\ - (void) bcopy((caddr_t)(isoap), hoff, (isoap)->isoa_len);\ - hoff += (isoap)->isoa_len; +#define CLNP_INSERT_ADDR(hoff, isoa)\ + *hoff++ = (isoa).isoa_len;\ + (void) bcopy((caddr_t)((isoa).isoa_genaddr), hoff, (isoa).isoa_len);\ + hoff += (isoa).isoa_len; /* * Clnp hdr cache. Whenever a clnp packet is sent, a copy of the @@ -395,7 +405,7 @@ struct clnp_cache { int clc_segoff; /* offset of seg part of header */ struct sockaddr *clc_firsthop; /* first hop of packet (points into the route structure) */ - struct ifnet *clc_ifp; /* ptr to interface (points into + struct iso_ifaddr *clc_ifa; /* ptr to interface (points into the route structure) */ struct mbuf *clc_hdr; /* cached pkt hdr (finally)! */ }; diff --git a/usr/src/sys/netiso/clnp_debug.c b/usr/src/sys/netiso/clnp_debug.c index 2f47c47064..96c73eebed 100644 --- a/usr/src/sys/netiso/clnp_debug.c +++ b/usr/src/sys/netiso/clnp_debug.c @@ -43,10 +43,10 @@ static char *rcsid = "$Header: clnp_debug.c,v 4.2 88/06/29 14:58:34 hagens Exp $ #include "../net/if.h" #include "../net/route.h" -#include "../netiso/iso.h" -#include "../netiso/clnp.h" -#include "../netiso/clnp_stat.h" -#include "../netiso/argo_debug.h" +#include "iso.h" +#include "clnp.h" +#include "clnp_stat.h" +#include "argo_debug.h" #ifdef ARGO_DEBUG @@ -144,7 +144,8 @@ struct iso_addr *isoa; cp++; /* print afi */ - cp = clnp_hexp(&isoa->isoa_afi, 1, cp); + cp = clnp_hexp(isoa->isoa_genaddr, (int)isoa->isoa_len, cp); +#ifdef notdef *cp++ = DELIM; /* print type specific part */ @@ -205,46 +206,24 @@ struct iso_addr *isoa; *cp++ = '?'; break; } +#endif notdef *cp = (char)0; return(iso_addr_b); } -#define MAX_COLUMNS 8 -/* - * Dump the buffer to the screen in a readable format. Format is: - * - * hex/dec where hex is the hex format, dec is the decimal format. - * columns of hex/dec numbers will be printed, followed by the - * character representations (if printable). - */ -dump_buf(buf, len) -char *buf; -int len; +char * +clnp_saddr_isop(s) +register struct sockaddr_iso *s; { - int i,j; - - printf("Dump buf 0x%x len 0x%x\n", buf, len); - for (i = 0; i < len; i += MAX_COLUMNS) { - printf("+%d:\t", i); - for (j = 0; j < MAX_COLUMNS; j++) { - if (i + j < len) { - printf("%x/%d\t", buf[i+j]&0xff, buf[i+j]); - } else { - printf(" "); - } - } - - for (j = 0; j < MAX_COLUMNS; j++) { - if (i + j < len) { - if (((buf[i+j]) > 31) && ((buf[i+j]) < 128)) - printf("%c", buf[i+j]&0xff); - else - printf("."); - } - } - printf("\n"); - } + register char *cp = clnp_iso_addrp(&s->siso_addr); + + while (*cp) cp++; + *cp++ = '('; + cp = clnp_hexp(TSEL(s), (int)s->siso_tsuffixlen, cp); + *cp++ = ')'; + *cp++ = 0; + return (iso_addr_b); } @@ -252,18 +231,18 @@ int len; * The following hacks are a trimmed down version of sprintf. */ /*VARARGS1*/ +/*ARGSUSED*/ clnp_sprintf(buf, fmt, x1, x2) - register char *fmt; + register char *buf, *fmt; unsigned x1, x2; { - clnp_prf(buf, fmt, &x1, 0); + clnp_prf(buf, fmt, (unsigned int *)&x1); } -clnp_prf(buf, fmt, adx, dummy) +clnp_prf(buf, fmt, adx) register char *buf; register char *fmt; register unsigned int *adx; - int dummy; { register int b, c, i; char *s; diff --git a/usr/src/sys/netiso/clnp_er.c b/usr/src/sys/netiso/clnp_er.c index 58765d2136..93639e117a 100644 --- a/usr/src/sys/netiso/clnp_er.c +++ b/usr/src/sys/netiso/clnp_er.c @@ -33,40 +33,31 @@ static char *rcsid = "$Header: /var/src/sys/netiso/RCS/clnp_er.c,v 5.1 89/02/09 #ifdef ISO -#include "../h/types.h" -#include "../h/param.h" -#include "../h/mbuf.h" -#include "../h/domain.h" -#include "../h/protosw.h" -#include "../h/socket.h" -#include "../h/socketvar.h" -#include "../h/errno.h" +#include "types.h" +#include "param.h" +#include "mbuf.h" +#include "domain.h" +#include "protosw.h" +#include "socket.h" +#include "socketvar.h" +#include "errno.h" #include "../net/if.h" #include "../net/route.h" -#include "../netiso/iso.h" -#include "../netiso/clnp.h" -#include "../netiso/clnp_stat.h" -#include "../netiso/argo_debug.h" +#include "iso.h" +#include "iso_var.h" +#include "iso_pcb.h" +#include "clnp.h" +#include "clnp_stat.h" +#include "argo_debug.h" static struct clnp_fixed er_template = { ISO8473_CLNP, /* network identifier */ 0, /* length */ ISO8473_V1, /* version */ CLNP_TTL, /* ttl */ -#if BYTE_ORDER == LITTLE_ENDIAN CLNP_ER, /* type */ - 0, /* error report */ - 0, /* more segments */ - 0, /* segmentation permitted */ -#endif -#if BYTE_ORDER == BIG_ENDIAN - 0, /* segmentation permitted */ - 0, /* more segments */ - 0, /* error report */ - CLNP_ER, /* type */ -#endif 0, /* segment length */ 0 /* checksum */ }; @@ -85,7 +76,7 @@ static struct clnp_fixed er_template = { clnp_er_input(m, src, reason) struct mbuf *m; /* ptr to packet itself */ struct iso_addr *src; /* ptr to src of er */ -char reason; /* reason code of er */ +u_char reason; /* reason code of er */ { int cmd = -1; extern u_char clnp_protox[]; @@ -197,9 +188,10 @@ char reason; /* reason for discard */ if (m->m_len >= sizeof(struct clnp_fixed)) { register struct clnp_fixed *clnp = mtod(m, struct clnp_fixed *); - if ((clnp->cnf_type != CLNP_ER) && (clnp->cnf_err_ok)) { - clnp_emit_er(m, reason); - return; + if (((clnp->cnf_type & CNF_TYPE) != CLNP_ER) && + (clnp->cnf_type & CNF_ERR_OK)) { + clnp_emit_er(m, reason); + return; } } m_freem(m); @@ -229,13 +221,14 @@ char reason; /* reason for discard */ { register struct clnp_fixed *clnp = mtod(m, struct clnp_fixed *); register struct clnp_fixed *er; - struct route route; + struct route_iso route; struct ifnet *ifp; struct sockaddr *first_hop; struct iso_addr src, dst, *our_addr; caddr_t hoff, hend; int total_len; /* total len of dg */ struct mbuf *m0; /* contains er pdu hdr */ + struct iso_ifaddr *ia = 0; IFDEBUG(D_DISCARD) printf("clnp_emit_er: m x%x, hdr len %d\n", m, clnp->cnf_hdr_len); @@ -280,17 +273,18 @@ char reason; /* reason for discard */ } if (m->m_len > clnp->cnf_hdr_len) - m_adj(m, -(m->m_len - clnp->cnf_hdr_len)); + m_adj(m, (int)-(m->m_len - (int)clnp->cnf_hdr_len)); /* route er pdu: note we send pkt to src of original packet */ - if (clnp_route(&src, &route, /* flags */0, &first_hop, &ifp) != 0) + if (clnp_route(&src, &route, /* flags */0, &first_hop, &ia) != 0) goto bad; /* compute our address based upon firsthop/ifp */ - our_addr = - clnp_srcaddr(ifp, &((struct sockaddr_iso *)first_hop)->siso_addr); - if (our_addr == NULL) - goto bad; + if (ia) + our_addr = &ia->ia_addr.siso_addr; + else + goto bad; + ifp = ia->ia_ifp; IFDEBUG(D_DISCARD) printf("clnp_emit_er: to %s", clnp_iso_addrp(&src)); @@ -314,8 +308,8 @@ char reason; /* reason for discard */ /* setup src/dst on er pdu */ /* NOTE REVERSAL OF SRC/DST */ hoff = (caddr_t)er + sizeof(struct clnp_fixed); - CLNP_INSERT_ADDR(hoff, &src); - CLNP_INSERT_ADDR(hoff, our_addr); + CLNP_INSERT_ADDR(hoff, src); + CLNP_INSERT_ADDR(hoff, *our_addr); /* * TODO: if complete src rt was specified, then reverse path, and diff --git a/usr/src/sys/netiso/clnp_frag.c b/usr/src/sys/netiso/clnp_frag.c index 8855030576..6f71f4a471 100644 --- a/usr/src/sys/netiso/clnp_frag.c +++ b/usr/src/sys/netiso/clnp_frag.c @@ -45,22 +45,17 @@ static char *rcsid = "$Header: /var/src/sys/netiso/RCS/clnp_frag.c,v 5.1 89/02/0 #include "../net/if.h" #include "../net/route.h" -#include "../netiso/iso.h" -#include "../netiso/iso_var.h" -#include "../netiso/clnp.h" -#include "../netiso/clnp_stat.h" -#include "../netiso/argo_debug.h" +#include "iso.h" +#include "iso_var.h" +#include "clnp.h" +#include "clnp_stat.h" +#include "argo_debug.h" /* all fragments are hung off this list */ struct clnp_fragl *clnp_frags = NULL; struct mbuf *clnp_comp_pdu(); -#ifdef TROLL -float troll_random(); -static int troll_cnt = 0; -#endif TROLL - /* * FUNCTION: clnp_fragment @@ -93,7 +88,7 @@ int flags; /* flags passed to clnp_output */ clnp = mtod(m, struct clnp_fixed *); - if (clnp->cnf_seg_ok) { + if (clnp->cnf_type & CNF_SEG_OK) { struct mbuf *hdr = NULL; /* save copy of clnp hdr */ struct mbuf *frag_hdr = NULL; struct mbuf *frag_data = NULL; @@ -110,11 +105,11 @@ int flags; /* flags passed to clnp_output */ /* * Duplicate header, and remove from packet */ - if ((hdr = m_copy(m, 0, clnp->cnf_hdr_len)) == NULL) { + if ((hdr = m_copy(m, 0, (int)clnp->cnf_hdr_len)) == NULL) { clnp_discard(m, GEN_CONGEST); return(ENOBUFS); } - m_adj(m, clnp->cnf_hdr_len); + m_adj(m, (int)clnp->cnf_hdr_len); total_len -= clnp->cnf_hdr_len; while (total_len > 0) { @@ -162,7 +157,7 @@ int flags; /* flags passed to clnp_output */ frag_data = m; } else { /* duplicate header and data mbufs */ - if ((frag_hdr = m_copy(hdr, 0, M_COPYALL)) == NULL) { + if ((frag_hdr = m_copy(hdr, 0, (int)M_COPYALL)) == NULL) { clnp_discard(m, GEN_CONGEST); m_freem(hdr); return(ENOBUFS); @@ -177,7 +172,7 @@ int flags; /* flags passed to clnp_output */ clnp = mtod(frag_hdr, struct clnp_fixed *); if (!last_frag) - clnp->cnf_more_segs = 1; + clnp->cnf_type |= CNF_MORE_SEGS; /* link together */ m_cat(frag_hdr, frag_data); @@ -194,6 +189,9 @@ int flags; /* flags passed to clnp_output */ { int derived_len = clnp->cnf_hdr_len + frag_size; HTOC(clnp->cnf_seglen_msb, clnp->cnf_seglen_lsb, derived_len); + if ((frag_hdr->m_flags & M_PKTHDR) == 0) + panic("clnp_frag:lost header"); + frag_hdr->m_pkthdr.len = derived_len; } /* compute clnp checksum (on header only) */ if (flags & CLNP_NO_CKSUM) { @@ -369,7 +367,7 @@ struct clnp_segment *seg; /* segment part of fragment header */ * Duplicate the header of this fragment, and save in cfh. * Free m0 and return if m_copy does not succeed. */ - if ((cfh->cfl_orighdr = m_copy(m, 0, clnp->cnf_hdr_len)) == NULL) { + if ((cfh->cfl_orighdr = m_copy(m, 0, (int)clnp->cnf_hdr_len)) == NULL) { m_freem(m0); return (0); } @@ -485,7 +483,7 @@ struct clnp_segment *seg; /* segment part of fragment header */ /* Trim data off of end of previous fragment */ /* inc overlap to prevent duplication of last byte */ overlap++; - m_adj(cf_prev->cfr_data, -overlap); + m_adj(cf_prev->cfr_data, -(int)overlap); cf_prev->cfr_last -= overlap; } } @@ -519,7 +517,7 @@ struct clnp_segment *seg; /* segment part of fragment header */ /* Trim data off of end of new fragment */ /* inc overlap to prevent duplication of last byte */ overlap++; - m_adj(m, -overlap); + m_adj(m, -(int)overlap); last -= overlap; } } @@ -668,7 +666,7 @@ struct clnp_fragl *cfh; /* fragment header */ printf("clnp_comp_pdu: shaving off %d bytes\n", cf_next_hdr.cfr_bytes); ENDDEBUG - m_adj(cf_next_hdr.cfr_data, cf_next_hdr.cfr_bytes); + m_adj(cf_next_hdr.cfr_data, (int)cf_next_hdr.cfr_bytes); m_cat(cf->cfr_data, cf_next_hdr.cfr_data); cf->cfr_next = next_frag; } else { @@ -707,7 +705,7 @@ struct clnp_fragl *cfh; /* fragment header */ printf("clnp_comp_pdu: complete pdu!\n"); ENDDEBUG - m_adj(data, cf->cfr_bytes); + m_adj(data, (int)cf->cfr_bytes); m_cat(hdr, data); IFDEBUG(D_DUMPIN) @@ -743,6 +741,7 @@ struct clnp_fragl *cfh; /* fragment header */ return(NULL); } #ifdef TROLL +static int troll_cnt; #include "../h/time.h" /* * FUNCTION: troll_random @@ -796,7 +795,7 @@ struct sockaddr *dst; float f_freq = troll_cnt * trollctl.tr_dup_freq; int i_freq = troll_cnt * trollctl.tr_dup_freq; if (i_freq == f_freq) { - struct mbuf *dup = m_copy(m, 0, M_COPYALL); + struct mbuf *dup = m_copy(m, 0, (int)M_COPYALL); if (dup != NULL) err = (*ifp->if_output)(ifp, dup, dst); } diff --git a/usr/src/sys/netiso/clnp_input.c b/usr/src/sys/netiso/clnp_input.c index d3860e2715..342abd2136 100644 --- a/usr/src/sys/netiso/clnp_input.c +++ b/usr/src/sys/netiso/clnp_input.c @@ -26,7 +26,7 @@ SOFTWARE. */ /* $Header: /var/src/sys/netiso/RCS/clnp_input.c,v 5.1 89/02/09 16:20:32 hagens Exp $ */ /* $Source: /var/src/sys/netiso/RCS/clnp_input.c,v $ */ -/* @(#)clnp_input.c 7.3 (Berkeley) %G% */ +/* @(#)clnp_input.c 7.4 (Berkeley) %G% */ #ifndef lint static char *rcsid = "$Header: /var/src/sys/netiso/RCS/clnp_input.c,v 5.1 89/02/09 16:20:32 hagens Exp $"; @@ -43,16 +43,20 @@ static char *rcsid = "$Header: /var/src/sys/netiso/RCS/clnp_input.c,v 5.1 89/02/ #include "../h/time.h" #include "../net/if.h" +#include "../net/iftypes.h" #include "../net/route.h" -#include "../netiso/iso.h" -#include "../netiso/iso_var.h" -#include "../netiso/iso_snpac.h" -#include "../netiso/clnp.h" -#include "../netiso/clnl.h" -#include "../netiso/esis.h" -#include "../netiso/clnp_stat.h" -#include "../netiso/argo_debug.h" +#include "iso.h" +#include "iso_var.h" +#include "iso_snpac.h" +#include "clnp.h" +#include "clnl.h" +#include "../netinet/in_systm.h" +#include "../netinet/ip.h" +#include "eonvar.h" +#include "esis.h" +#include "clnp_stat.h" +#include "argo_debug.h" #ifdef ISO u_char clnp_protox[ISOPROTO_MAX]; @@ -120,7 +124,6 @@ clnlintr() { register struct mbuf *m; /* ptr to first mbuf of pkt */ register struct clnl_fixed *clnl; /* ptr to fixed part of clnl hdr */ - struct ifnet *ifp; /* ptr to interface pkt arrived on */ int s; /* save and restore priority */ struct clnl_protosw *clnlsw;/* ptr to protocol switch */ struct snpa_hdr sh; /* subnetwork hdr */ @@ -130,24 +133,41 @@ clnlintr() */ next: s = splimp(); - /* IF_DEQUEUESNPAHDR(&clnlintrq, m, sh);*/ IF_DEQUEUE(&clnlintrq, m); + splx(s); - splx(s); if (m == 0) /* nothing to do */ return; - if (m->m_flags & M_PKTHDR == 0) { + if ((m->m_flags & M_PKTHDR) == 0) { m_freem(m); goto next; } - bcopy((caddr_t)(mtod(m, struct llc_etherhdr *)->dst), - (caddr_t)sh.snh_dhost, 2*sizeof(sh.snh_dhost)); - m->m_data += sizeof (struct llc_etherhdr); - m->m_len -= sizeof (struct llc_etherhdr); - m->m_pkthdr.len -= sizeof (struct llc_etherhdr); - sh.snh_ifp = m->m_pkthdr.rcvif; + bzero((caddr_t)&sh, sizeof(sh)); + sh.snh_flags = m->m_flags & (M_MCAST|M_BCAST); + switch((sh.snh_ifp = m->m_pkthdr.rcvif)->if_type) { + extern int ether_output(); + case IFT_EON: + bcopy(mtod(m, caddr_t), (caddr_t)sh.snh_dhost, sizeof(u_long)); + bcopy(sizeof(u_long) + mtod(m, caddr_t), + (caddr_t)sh.snh_shost, sizeof(u_long)); + sh.snh_dhost[4] = mtod(m, u_char *)[sizeof(struct ip) + + _offsetof(struct eon_hdr, eonh_class)]; + m->m_data += EONIPLEN; + m->m_len -= EONIPLEN; + m->m_pkthdr.len -= EONIPLEN; + break; + + default: + if (sh.snh_ifp->if_output == ether_output) { + bcopy((caddr_t)(mtod(m, struct llc_etherhdr *)->dst), + (caddr_t)sh.snh_dhost, 2*sizeof(sh.snh_dhost)); + m->m_data += sizeof (struct llc_etherhdr); + m->m_len -= sizeof (struct llc_etherhdr); + m->m_pkthdr.len -= sizeof (struct llc_etherhdr); + } + } IFDEBUG(D_INPUT) int i; printf("clnlintr: src:"); @@ -189,7 +209,7 @@ next: * Note: m_pullup will allocate a cluster mbuf if necessary */ if (clnl->cnf_hdr_len > m->m_len) { - if ((m = m_pullup(m, clnl->cnf_hdr_len)) == 0) { + if ((m = m_pullup(m, (int)clnl->cnf_hdr_len)) == 0) { INCSTAT(cns_badhlen); /* TODO: use clnl stats */ goto next; /* m_pullup discards mbuf */ } @@ -220,7 +240,7 @@ next: * TODO: I would like to make seg_part a pointer into the mbuf, but * will it be correctly aligned? */ -int clnp_input(m, shp) +clnp_input(m, shp) struct mbuf *m; /* ptr to first mbuf of pkt */ struct snpa_hdr *shp; /* subnetwork header */ { @@ -275,23 +295,23 @@ struct snpa_hdr *shp; /* subnetwork header */ * Compute checksum (if necessary) and drop packet if * checksum does not match */ - if (CKSUM_REQUIRED(clnp) && iso_check_csum(m, clnp->cnf_hdr_len)) { + if (CKSUM_REQUIRED(clnp) && iso_check_csum(m, (int)clnp->cnf_hdr_len)) { INCSTAT(cns_badcsum); clnp_discard(m, GEN_BADCSUM); - return 0; + return; } if (clnp->cnf_vers != ISO8473_V1) { INCSTAT(cns_badvers); clnp_discard(m, DISC_UNSUPPVERS); - return 0; + return; } /* check mbuf data length: clnp_data_ck will free mbuf upon error */ CTOH(clnp->cnf_seglen_msb, clnp->cnf_seglen_lsb, seg_len); if ((m = clnp_data_ck(m, seg_len)) == 0) - return 0; + return; clnp = mtod(m, struct clnp_fixed *); hend = (caddr_t)clnp + clnp->cnf_hdr_len; @@ -308,13 +328,13 @@ struct snpa_hdr *shp; /* subnetwork header */ if (hoff == (caddr_t)0) { INCSTAT(cns_badaddr); clnp_discard(m, GEN_INCOMPLETE); - return 0; + return; } CLNP_EXTRACT_ADDR(src, hoff, hend); if (hoff == (caddr_t)0) { INCSTAT(cns_badaddr); clnp_discard(m, GEN_INCOMPLETE); - return 0; + return; } IFDEBUG(D_INPUT) @@ -326,11 +346,12 @@ struct snpa_hdr *shp; /* subnetwork header */ * extract the segmentation information, if it is present. * drop packet on failure */ - if ((clnp->cnf_type != CLNP_ER) && (clnp->cnf_seg_ok)) { + if (((clnp->cnf_type & CNF_TYPE) != CLNP_ER) && + (clnp->cnf_type & CNF_SEG_OK)) { if (hoff + sizeof(struct clnp_segment) > hend) { INCSTAT(cns_noseg); clnp_discard(m, GEN_INCOMPLETE); - return 0; + return; } else { (void) bcopy(hoff, (caddr_t)&seg_part, sizeof(struct clnp_segment)); /* make sure segmentation fields are in host order */ @@ -360,7 +381,7 @@ struct snpa_hdr *shp; /* subnetwork header */ /* the er option is valid with ER pdus only */ if ((errcode == 0) && (oidxp->cni_er_reason != ER_INVALREAS) && - (clnp->cnf_type != CLNP_ER)) + ((clnp->cnf_type & CNF_TYPE) != CLNP_ER)) errcode = DISC_UNSUPPOPT; #ifdef DECBIT @@ -382,7 +403,7 @@ struct snpa_hdr *shp; /* subnetwork header */ printf("clnp_input: dropped (err x%x) due to bad options\n", errcode); ENDDEBUG - return 0; + return; } } @@ -394,7 +415,7 @@ struct snpa_hdr *shp; /* subnetwork header */ printf("clnp_input: forwarding packet not for us\n"); ENDDEBUG clnp_forward(m, seg_len, &dst, oidxp, seg_off, shp); - return 0; + return; } /* @@ -403,7 +424,7 @@ struct snpa_hdr *shp; /* subnetwork header */ * If the packet received was sent to the multicast address * all end systems, then send an esh to the source */ - if ((IS_MULTICAST(shp->snh_dhost)) && (iso_systype == SNPA_ES)) { + if ((shp->snh_flags & M_MCAST) && (iso_systype == SNPA_ES)) { extern short esis_holding_time; esis_shoutput(shp->snh_ifp, ESIS_ESH, esis_holding_time, @@ -417,7 +438,8 @@ struct snpa_hdr *shp; /* subnetwork header */ * by the reassembly code (either stored or deleted). In either case * we should have nothing more to do with it. */ - if ((clnp->cnf_type != CLNP_ER) && (clnp->cnf_seg_ok) && + if (((clnp->cnf_type & CNF_TYPE) != CLNP_ER) && + (clnp->cnf_type & CNF_SEG_OK) && (seg_len != seg_part.cng_tot_len)) { struct mbuf *m0; @@ -425,7 +447,7 @@ struct snpa_hdr *shp; /* subnetwork header */ m = m0; clnp = mtod(m, struct clnp_fixed *); } else { - return 0; + return; } } @@ -437,7 +459,7 @@ struct snpa_hdr *shp; /* subnetwork header */ * or, if absent, the segment length field of the * header. */ - switch (clnp->cnf_type) { + switch (clnp->cnf_type & CNF_TYPE) { case CLNP_ER: /* * This ER must have the er option. @@ -467,7 +489,7 @@ struct snpa_hdr *shp; /* subnetwork header */ case CLNP_ECR: IFDEBUG(D_INPUT) printf("clnp_input: raw input of %d bytes\n", - clnp->cnf_seg_ok ? seg_part.cng_tot_len : seg_len); + clnp->cnf_type & CNF_SEG_OK ? seg_part.cng_tot_len : seg_len); ENDDEBUG (*isosw[clnp_protox[ISOPROTO_RAW]].pr_input)(m, &src, &dst, clnp->cnf_hdr_len); @@ -481,19 +503,21 @@ struct snpa_hdr *shp; /* subnetwork header */ * Switch the source and destination address, */ hoff = (caddr_t)clnp + sizeof(struct clnp_fixed); - CLNP_INSERT_ADDR(hoff, &src); - CLNP_INSERT_ADDR(hoff, &dst); - clnp->cnf_type = CLNP_ECR; + CLNP_INSERT_ADDR(hoff, src); + CLNP_INSERT_ADDR(hoff, dst); + clnp->cnf_type &= ~CNF_TYPE; + clnp->cnf_type |= CLNP_ECR; /* * Forward back to sender */ - clnp_forward(m, clnp->cnf_seg_ok ? seg_part.cng_tot_len : seg_len, + clnp_forward(m, (int)(clnp->cnf_type & CNF_SEG_OK?seg_part.cng_tot_len : seg_len), &src, oidxp, seg_off, shp); break; default: - printf("clnp_input: unknown clnp pkt type %d\n", clnp->cnf_type); + printf("clnp_input: unknown clnp pkt type %d\n", + clnp->cnf_type & CNF_TYPE); clnp_discard(m, GEN_HDRSYNTAX); break; } diff --git a/usr/src/sys/netiso/clnp_options.c b/usr/src/sys/netiso/clnp_options.c index 78484010ff..91fadb5f84 100644 --- a/usr/src/sys/netiso/clnp_options.c +++ b/usr/src/sys/netiso/clnp_options.c @@ -45,10 +45,10 @@ static char *rcsid = "$Header: /var/src/sys/netiso/RCS/clnp_options.c,v 5.1 89/0 #include "../net/if.h" #include "../net/route.h" -#include "../netiso/iso.h" -#include "../netiso/clnp.h" -#include "../netiso/clnp_stat.h" -#include "../netiso/argo_debug.h" +#include "iso.h" +#include "clnp.h" +#include "clnp_stat.h" +#include "argo_debug.h" /* * FUNCTION: clnp_update_srcrt diff --git a/usr/src/sys/netiso/clnp_output.c b/usr/src/sys/netiso/clnp_output.c index 8eb3d06da5..293774ffc6 100644 --- a/usr/src/sys/netiso/clnp_output.c +++ b/usr/src/sys/netiso/clnp_output.c @@ -32,42 +32,32 @@ static char *rcsid = "$Header: /var/src/sys/netiso/RCS/clnp_output.c,v 5.0 89/02 #endif lint #ifdef ISO -#include "../h/types.h" -#include "../h/param.h" -#include "../h/mbuf.h" -#include "../h/domain.h" -#include "../h/protosw.h" -#include "../h/socket.h" -#include "../h/socketvar.h" -#include "../h/errno.h" -#include "../h/time.h" +#include "types.h" +#include "param.h" +#include "mbuf.h" +#include "domain.h" +#include "protosw.h" +#include "socket.h" +#include "socketvar.h" +#include "errno.h" +#include "time.h" #include "../net/if.h" #include "../net/route.h" -#include "../netiso/iso.h" -#include "../netiso/iso_pcb.h" -#include "../netiso/clnp.h" -#include "../netiso/clnp_stat.h" -#include "../netiso/argo_debug.h" +#include "iso.h" +#include "iso_var.h" +#include "iso_pcb.h" +#include "clnp.h" +#include "clnp_stat.h" +#include "argo_debug.h" static struct clnp_fixed dt_template = { ISO8473_CLNP, /* network identifier */ 0, /* length */ ISO8473_V1, /* version */ CLNP_TTL, /* ttl */ -#if BYTE_ORDER == LITTLE_ENDIAN - CLNP_DT, /* type */ - 1, /* error report */ - 0, /* more segments */ - 1, /* segmentation permitted */ -#endif -#if BYTE_ORDER == BIG_ENDIAN - 1, /* segmentation permitted */ - 0, /* more segments */ - 1, /* error report */ - CLNP_DT, /* type */ -#endif + CLNP_DT|CNF_SEG_OK|CNF_ERR_OK, /* type */ 0, /* segment length */ 0 /* checksum */ }; @@ -77,18 +67,7 @@ static struct clnp_fixed raw_template = { 0, /* length */ ISO8473_V1, /* version */ CLNP_TTL, /* ttl */ -#if BYTE_ORDER == LITTLE_ENDIAN - CLNP_RAW, /* type */ - 1, /* error report */ - 0, /* more segments */ - 1, /* segmentation permitted */ -#endif -#if BYTE_ORDER == BIG_ENDIAN - 1, /* segmentation permitted */ - 0, /* more segments */ - 1, /* error report */ - CLNP_RAW, /* type */ -#endif + CLNP_RAW|CNF_SEG_OK|CNF_ERR_OK, /* type */ 0, /* segment length */ 0 /* checksum */ }; @@ -98,18 +77,7 @@ static struct clnp_fixed echo_template = { 0, /* length */ ISO8473_V1, /* version */ CLNP_TTL, /* ttl */ -#if BYTE_ORDER == LITTLE_ENDIAN - CLNP_EC, /* type */ - 1, /* error report */ - 0, /* more segments */ - 1, /* segmentation permitted */ -#endif -#if BYTE_ORDER == BIG_ENDIAN - 1, /* segmentation permitted */ - 0, /* more segments */ - 1, /* error report */ - CLNP_EC, /* type */ -#endif + CLNP_EC|CNF_SEG_OK|CNF_ERR_OK, /* type */ 0, /* segment length */ 0 /* checksum */ }; @@ -168,14 +136,14 @@ int clnp_id = 0; /* id for segmented dgrams */ * to have clnp check that the route has the same dest, but * by avoiding this check, we save a call to iso_addrmatch1. */ -clnp_output(m0, isop, datalen, flags) +clnp_output(m0, isop, flags) struct mbuf *m0; /* data for the packet */ struct isopcb *isop; /* iso pcb */ -int datalen; /* number of bytes of data in m */ int flags; /* flags */ { int error = 0; /* return value of function */ - register struct mbuf *m; /* mbuf for clnp header chain */ + register struct mbuf *m = m0; /* mbuf for clnp header chain */ + int datalen; /* number of bytes of data in m */ register struct clnp_fixed *clnp; /* ptr to fixed part of hdr */ register caddr_t hoff; /* offset into header */ int total_len; /* total length of packet */ @@ -185,9 +153,14 @@ int flags; /* flags */ struct clnp_cache *clcp = NULL; /* ptr to clc */ int hdrlen = 0; - src = &isop->isop_laddr.siso_addr; - dst = &isop->isop_faddr.siso_addr; + src = &isop->isop_laddr->siso_addr; + dst = &isop->isop_faddr->siso_addr; + if ((m->m_flags & M_PKTHDR) == 0) { + m_freem(m); + return EINVAL; + } + datalen = m->m_pkthdr.len; IFDEBUG(D_OUTPUT) printf("clnp_output: to %s", clnp_iso_addrp(dst)); printf(" from %s of %d bytes\n", clnp_iso_addrp(src), datalen); @@ -230,7 +203,7 @@ int flags; /* flags */ printf("clnp_output: using cache\n"); ENDDEBUG - m = m_copy(clcp->clc_hdr, 0, M_COPYALL); + m = m_copy(clcp->clc_hdr, 0, (int)M_COPYALL); if (m == NULL) { /* * No buffers left to copy cached packet header. Use @@ -346,7 +319,7 @@ int flags; /* flags */ /* * Grab mbuf to contain header */ - MGET(m, M_DONTWAIT, MT_HEADER); + MGETHDR(m, M_DONTWAIT, MT_HEADER); if (m == 0) { m_freem(m0); return(ENOBUFS); @@ -367,9 +340,9 @@ int flags; /* flags */ *clnp = dt_template; } if (flags & CLNP_NO_SEG) - clnp->cnf_seg_ok = 0; + clnp->cnf_type &= ~CNF_SEG_OK; if (flags & CLNP_NO_ER) - clnp->cnf_err_ok = 0; + clnp->cnf_type &= ~CNF_ERR_OK; /* * Route packet; special case for source rt @@ -379,14 +352,14 @@ int flags; /* flags */ printf("clnp_output: calling clnp_srcroute\n"); ENDDEBUG error = clnp_srcroute(isop->isop_options, oidx, &isop->isop_route, - &clcp->clc_firsthop, &clcp->clc_ifp, dst); + &clcp->clc_firsthop, &clcp->clc_ifa, dst); } else { IFDEBUG(D_OUTPUT) ENDDEBUG error = clnp_route(dst, &isop->isop_route, flags, - &clcp->clc_firsthop, &clcp->clc_ifp); + &clcp->clc_firsthop, &clcp->clc_ifa); } - if (error != 0) { + if (error || (clcp->clc_ifa == 0)) { IFDEBUG(D_OUTPUT) printf("clnp_output: route failed, errno %d\n", error); printf("@clcp:\n"); @@ -407,12 +380,7 @@ int flags; /* flags */ * the isopcb. Is this desirable? RAH? */ if (src->isoa_len == 0) { - src = clnp_srcaddr(clcp->clc_ifp, - &((struct sockaddr_iso *)clcp->clc_firsthop)->siso_addr); - if (src == NULL) { - error = ENETDOWN; - goto bad; - } + src = &(clcp->clc_ifa->ia_addr.siso_addr); IFDEBUG(D_OUTPUT) printf("clnp_output: new src %s\n", clnp_iso_addrp(src)); ENDDEBUG @@ -422,13 +390,13 @@ int flags; /* flags */ * Insert the source and destination address, */ hoff = (caddr_t)clnp + sizeof(struct clnp_fixed); - CLNP_INSERT_ADDR(hoff, dst); - CLNP_INSERT_ADDR(hoff, src); + CLNP_INSERT_ADDR(hoff, *dst); + CLNP_INSERT_ADDR(hoff, *src); /* * Leave room for the segment part, if segmenting is selected */ - if (clnp->cnf_seg_ok) { + if (clnp->cnf_type & CNF_SEG_OK) { clcp->clc_segoff = hoff - (caddr_t)clnp; hoff += sizeof(struct clnp_segment); } @@ -455,7 +423,7 @@ int flags; /* flags */ * If an options mbuf is present, concatenate a copy to the hdr mbuf. */ if (isop->isop_options) { - struct mbuf *opt_copy = m_copy(isop->isop_options, 0, M_COPYALL); + struct mbuf *opt_copy = m_copy(isop->isop_options, 0, (int)M_COPYALL); if (opt_copy == NULL) { error = ENOBUFS; goto bad; @@ -478,9 +446,8 @@ int flags; /* flags */ * Now set up the cache entry in the pcb */ if ((flags & CLNP_NOCACHE) == 0) { - if ((clcp->clc_hdr = m_copy(m, 0, clnp->cnf_hdr_len)) != NULL) { - bcopy((caddr_t)dst, (caddr_t)&clcp->clc_dst, - sizeof(struct iso_addr)); + if (clcp->clc_hdr = m_copy(m, 0, (int)clnp->cnf_hdr_len)) { + clcp->clc_dst = *dst; clcp->clc_flags = flags; clcp->clc_options = isop->isop_options; } @@ -491,8 +458,9 @@ int flags; /* flags */ * If small enough for interface, send directly * Fill in segmentation part of hdr if using the full protocol */ - if ((total_len = clnp->cnf_hdr_len + datalen) <= SN_MTU(clcp->clc_ifp)) { - if (clnp->cnf_seg_ok) { + if ((total_len = clnp->cnf_hdr_len + datalen) + <= SN_MTU(clcp->clc_ifa->ia_ifp)) { + if (clnp->cnf_type & CNF_SEG_OK) { struct clnp_segment seg_part; /* segment part of hdr */ seg_part.cng_id = htons(clnp_id++); seg_part.cng_off = htons(0); @@ -501,7 +469,7 @@ int flags; /* flags */ sizeof(seg_part)); } HTOC(clnp->cnf_seglen_msb, clnp->cnf_seglen_lsb, total_len); - + m->m_pkthdr.len = total_len; /* * Compute clnp checksum (on header only) */ @@ -526,7 +494,7 @@ int flags; /* flags */ /* * Too large for interface; fragment if possible. */ - error = clnp_fragment(clcp->clc_ifp, m, clcp->clc_firsthop, total_len, + error = clnp_fragment(clcp->clc_ifa->ia_ifp, m, clcp->clc_firsthop, total_len, clcp->clc_segoff, flags); goto done; } diff --git a/usr/src/sys/netiso/clnp_raw.c b/usr/src/sys/netiso/clnp_raw.c index 44e92e41b9..465a61f386 100644 --- a/usr/src/sys/netiso/clnp_raw.c +++ b/usr/src/sys/netiso/clnp_raw.c @@ -1,5 +1,4 @@ -/*********************************************************** - Copyright IBM Corporation 1987 +/*********************************************************** Copyright IBM Corporation 1987 All Rights Reserved @@ -46,14 +45,16 @@ static char *rcsid = "$Header: clnp_raw.c,v 4.2 88/06/29 14:58:56 hagens Exp $"; #include "../net/route.h" #include "../net/raw_cb.h" -#include "../netiso/iso.h" -#include "../netiso/iso_pcb.h" -#include "../netiso/clnp.h" -#include "../netiso/clnp_stat.h" -#include "../netiso/argo_debug.h" +#include "iso.h" +#include "iso_pcb.h" +#include "clnp.h" +#include "clnp_stat.h" +#include "argo_debug.h" -struct sockaddr_iso rclnp_src = { AF_ISO }; -struct sockaddr_iso rclnp_dst = { AF_ISO }; +#include "tp_user.h"/* XXX -- defines SOL_NETWORK */ + +struct sockaddr_iso rclnp_src = { sizeof(rclnp_src), AF_ISO }; +struct sockaddr_iso rclnp_dst = { sizeof(rclnp_src), AF_ISO }; struct sockproto rclnp_proto = { PF_ISO, 0 }; /* * FUNCTION: rclnp_input @@ -108,103 +109,32 @@ struct socket *so; /* socket to send from */ { register struct mbuf *m; /* used to scan a chain */ int len = 0; /* store length of chain here */ - struct rawcb *rp = sotorawcb(so); /* ptr to raw cb */ + struct rawisopcb *rp = sotorawisopcb(so); /* ptr to raw cb */ int error; /* return value of function */ - u_int flags; /* flags for clnp_output */ - struct isopcb isopcb; /* isopcb used to interface w/clnp */ - - /* Calculate length of data */ - for (m = m0; m; m = m->m_next) - len += m->m_len; - - bzero((caddr_t)&isopcb, sizeof(isopcb)); + int flags; /* flags for clnp_output */ /* * Set up src address. If user has bound socket to an address, use it. * Otherwise, do not specify src (clnp_output will fill it in). */ - if (rp->rcb_flags & RAW_LADDR) { - if (rp->rcb_laddr.sa_family != AF_ISO) { + if (rp->risop_rcb.rcb_laddr) { + if (rp->risop_isop.isop_sladdr.siso_family != AF_ISO) { +bad: m_freem(m0); return(EAFNOSUPPORT); } - bcopy((caddr_t)&rp->rcb_laddr, &isopcb.isop_laddr, - sizeof(struct sockaddr_iso)); } - - /* set up route structure, if route is present */ - if (rp->rcb_route.ro_rt != NULL) - bcopy((caddr_t)&rp->rcb_route, (caddr_t)&isopcb.isop_route, - sizeof(struct route)); - /* set up dest address */ - bcopy((caddr_t)&rp->rcb_faddr, &isopcb.isop_faddr, - sizeof(struct sockaddr_iso)); - - /* - * setup option index - this was done when option was set, but raw - * cb has no place to put it. - */ - if (rp->rcb_options != NULL) { - isopcb.isop_options = rp->rcb_options; - isopcb.isop_optindex = m_get(M_WAIT, MT_SOOPTS); - (void) clnp_opt_sanity(isopcb.isop_options, - mtod(isopcb.isop_options, caddr_t), isopcb.isop_options->m_len, - mtod(isopcb.isop_optindex, struct clnp_optidx *)); - } + if (rp->risop_rcb.rcb_faddr == 0) + goto bad; + rp->risop_isop.isop_sfaddr = + *(struct sockaddr_iso *)rp->risop_rcb.rcb_faddr; + rp->risop_isop.isop_faddr = &rp->risop_isop.isop_sfaddr; /* get flags and ship it off */ - flags = rp->rcb_flags & CLNP_VFLAGS; - -#ifdef TROLL - if (trollctl.tr_ops & TR_BLAST) { - register int i; - struct timeval start, stop; - extern struct timeval time; - struct mbuf *mbuf_orig; - - mbuf_orig = m0; - start = time; - for (i=0; irisop_flags & CLNP_VFLAGS; - if (isopcb.isop_route.ro_rt) - RTFREE(isopcb.isop_route.ro_rt); - - /* free clnp cached hdr if necessary */ - if (isopcb.isop_clnpcache != NULL) { - struct clnp_cache *clcp = - mtod(isopcb.isop_clnpcache, struct clnp_cache *); - if (clcp->clc_hdr != NULL) { - m_free(clcp->clc_hdr); - } - m_free(isopcb.isop_clnpcache); - } - - if (isopcb.isop_optindex != NULL) - m_free(isopcb.isop_optindex); + error = clnp_output(m0, &rp->risop_isop, flags|CLNP_NOCACHE); return (error); } @@ -231,7 +161,7 @@ int optname; /* name of option */ struct mbuf **m; /* ptr to ptr to option data */ { int error = 0; - register struct rawcb *rp = sotorawcb(so);/* raw cb ptr */ + register struct rawisopcb *rp = sotorawisopcb(so);/* raw cb ptr */ IFDEBUG(D_CTLOUTPUT) printf("rclnp_ctloutput: op = x%x, level = x%x, name = x%x\n", @@ -269,12 +199,19 @@ struct mbuf **m; /* ptr to ptr to option data */ if ((usr_flags & (CLNP_VFLAGS)) != usr_flags) { error = EINVAL; } else - rp->rcb_flags |= usr_flags; + rp->risop_flags |= usr_flags; } break; case CLNPOPT_OPTS: - error = clnp_set_opts(&rp->rcb_options, m); + if (error = clnp_set_opts(&rp->risop_isop.isop_options, m)) + break; + rp->risop_isop.isop_optindex = m_get(M_WAIT, MT_SOOPTS); + (void) clnp_opt_sanity(rp->risop_isop.isop_options, + mtod(rp->risop_isop.isop_options, caddr_t), + rp->risop_isop.isop_options->m_len, + mtod(rp->risop_isop.isop_optindex, + struct clnp_optidx *)); break; } break; @@ -303,11 +240,86 @@ struct mbuf **m; /* ptr to ptr to option data */ } /*ARGSUSED*/ -clnp_usrreq(so, req, m, nam, rights) - struct socket *so; +clnp_usrreq(so, req, m, nam, rights, control) + register struct socket *so; int req; - struct mbuf *m, *nam, *rights; + struct mbuf *m, *nam, *rights, *control; { - return EPROTOTYPE; + register int error = 0; + register struct rawisopcb *rp = sotorawisopcb(so); + + rp = sotorawisopcb(so); + switch (req) { + + case PRU_ATTACH: + if (rp) + panic("rip_attach"); + MALLOC(rp, struct rawisopcb *, sizeof *rp, M_PCB, M_WAITOK); + if (rp == 0) + return (ENOBUFS); + bzero((caddr_t)rp, sizeof *rp); + so->so_pcb = (caddr_t)rp; + break; + + case PRU_DETACH: + if (rp == 0) + panic("rip_detach"); + if (rp->risop_isop.isop_options) + m_freem(rp->risop_isop.isop_options); + if (rp->risop_isop.isop_route.ro_rt) + RTFREE(rp->risop_isop.isop_route.ro_rt); + if (rp->risop_rcb.rcb_laddr) + rp->risop_rcb.rcb_laddr = 0; + /* free clnp cached hdr if necessary */ + if (rp->risop_isop.isop_clnpcache != NULL) { + struct clnp_cache *clcp = + mtod(rp->risop_isop.isop_clnpcache, struct clnp_cache *); + if (clcp->clc_hdr != NULL) { + m_free(clcp->clc_hdr); + } + m_free(rp->risop_isop.isop_clnpcache); + } + if (rp->risop_isop.isop_optindex != NULL) + m_free(rp->risop_isop.isop_optindex); + + break; + + case PRU_BIND: + { + struct sockaddr_iso *addr = mtod(nam, struct sockaddr_iso *); + + if (nam->m_len != sizeof(*addr)) + return (EINVAL); + if ((ifnet == 0) || + (addr->siso_family != AF_ISO) || + (addr->siso_addr.isoa_len && + ifa_ifwithaddr((struct sockaddr *)addr) == 0)) + return (EADDRNOTAVAIL); + rp->risop_isop.isop_sladdr = *addr; + rp->risop_rcb.rcb_laddr = (struct sockaddr *) + (rp->risop_isop.isop_laddr = &rp->risop_isop.isop_sladdr); + return (0); + } + case PRU_CONNECT: + { + struct sockaddr_iso *addr = mtod(nam, struct sockaddr_iso *); + + if ((nam->m_len > sizeof(*addr)) || (addr->siso_len > sizeof(*addr))) + return (EINVAL); + if (ifnet == 0) + return (EADDRNOTAVAIL); + if (addr->siso_family != AF_ISO) + rp->risop_isop.isop_sfaddr = *addr; + rp->risop_rcb.rcb_faddr = (struct sockaddr *) + (rp->risop_isop.isop_faddr = &rp->risop_isop.isop_sfaddr); + soisconnected(so); + return (0); + } + } + error = raw_usrreq(so, req, m, nam, rights, control); + + if (error && req == PRU_ATTACH && so->so_pcb) + free((caddr_t)rp, M_PCB); + return (error); } #endif ISO diff --git a/usr/src/sys/netiso/clnp_stat.h b/usr/src/sys/netiso/clnp_stat.h index 27e2a7764e..b620c952b6 100644 --- a/usr/src/sys/netiso/clnp_stat.h +++ b/usr/src/sys/netiso/clnp_stat.h @@ -24,8 +24,8 @@ SOFTWARE. /* * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison */ -/* $Header: clnp_stat.h,v 4.3 88/09/10 18:31:38 hagens Exp $ */ -/* $Source: /usr/argo/sys/netiso/RCS/clnp_stat.h,v $ */ +/* $Header: /var/src/sys/netiso/RCS/clnp_stat.h,v 5.1 89/02/09 16:20:42 hagens Exp $ */ +/* $Source: /var/src/sys/netiso/RCS/clnp_stat.h,v $ */ #ifndef __CLNP_STAT__ @@ -46,6 +46,8 @@ struct clnp_stat { u_short cns_frag; /* fragments generated */ u_short cns_sent; /* total packets sent */ u_short cns_cachemiss; /* cache misses */ + u_short cns_congest_set; /* congestion experienced bit set */ + u_short cns_congest_rcvd; /* congestion experienced bit received */ u_short er_protoerr; /* GEN_NOREAS GEN_PROTOERR GEN_HDRSYNTAX diff --git a/usr/src/sys/netiso/clnp_subr.c b/usr/src/sys/netiso/clnp_subr.c index e628547f4c..d9cb147aa0 100644 --- a/usr/src/sys/netiso/clnp_subr.c +++ b/usr/src/sys/netiso/clnp_subr.c @@ -33,25 +33,26 @@ static char *rcsid = "$Header: /var/src/sys/netiso/RCS/clnp_subr.c,v 5.1 89/02/0 #ifdef ISO -#include "../h/types.h" -#include "../h/param.h" -#include "../h/mbuf.h" -#include "../h/domain.h" -#include "../h/protosw.h" -#include "../h/socket.h" -#include "../h/socketvar.h" -#include "../h/errno.h" -#include "../h/time.h" +#include "types.h" +#include "param.h" +#include "mbuf.h" +#include "domain.h" +#include "protosw.h" +#include "socket.h" +#include "socketvar.h" +#include "errno.h" +#include "time.h" #include "../net/if.h" #include "../net/route.h" -#include "../netiso/iso.h" -#include "../netiso/iso_var.h" -#include "../netiso/clnp.h" -#include "../netiso/clnp_stat.h" -#include "../netiso/argo_debug.h" -#include "../netiso/iso_snpac.h" +#include "iso.h" +#include "iso_var.h" +#include "iso_pcb.h" +#include "iso_snpac.h" +#include "clnp.h" +#include "clnp_stat.h" +#include "argo_debug.h" /* * FUNCTION: clnp_data_ck @@ -214,6 +215,7 @@ struct snpa_hdr *inbound_shp; /* subnetwork header of inbound packet */ int error; /* return value of route function */ struct sockaddr *next_hop; /* next hop for dgram */ struct ifnet *ifp; /* ptr to outgoing interface */ + struct iso_ifaddr *ia = 0;/* ptr to iso name for ifp */ struct route_iso route; /* filled in by clnp_route */ extern int iso_systype; @@ -227,7 +229,7 @@ struct snpa_hdr *inbound_shp; /* subnetwork header of inbound packet */ IFDEBUG(D_FORWARD) printf("clnp_forward: dropping multicast packet\n"); ENDDEBUG - clnp->cnf_err_ok = 0; /* so we don't generate an ER */ + clnp->cnf_type &= ~CNF_ERR_OK; /* so we don't generate an ER */ clnp_discard(m, 0); goto done; } @@ -249,7 +251,6 @@ struct snpa_hdr *inbound_shp; /* subnetwork header of inbound packet */ clnp_discard(m, TTL_EXPTRANSIT); goto done; } - /* * Route packet; special case for source rt */ @@ -258,17 +259,18 @@ struct snpa_hdr *inbound_shp; /* subnetwork header of inbound packet */ * Update src route first */ clnp_update_srcrt(m, oidx); - error = clnp_srcroute(m, oidx, &route, &next_hop, &ifp, dst); + error = clnp_srcroute(m, oidx, &route, &next_hop, &ia, dst); } else { - error = clnp_route(dst, &route, 0, &next_hop, &ifp); + error = clnp_route(dst, &route, 0, &next_hop, &ia); } - if (error) { + if (error || ia == 0) { IFDEBUG(D_FORWARD) printf("clnp_forward: can't route packet (errno %d)\n", error); ENDDEBUG clnp_discard(m, ADDR_DESTUNREACH); goto done; } + ifp = ia->ia_ifp; IFDEBUG(D_FORWARD) printf("clnp_forward: packet routed to %s\n", @@ -297,8 +299,7 @@ struct snpa_hdr *inbound_shp; /* subnetwork header of inbound packet */ * If options are present, update them */ if (oidx) { - struct iso_addr *mysrc = - clnp_srcaddr(ifp, &((struct sockaddr_iso *)next_hop)->siso_addr); + struct iso_addr *mysrc = &ia->ia_addr.siso_addr; if (mysrc == NULL) { clnp_discard(m, ADDR_DESTUNREACH); goto done; @@ -399,23 +400,35 @@ register struct iso_addr *dstp; /* ptr to dst addr */ * NOTES: It is up to the caller to free the routing entry * allocated in route. */ -clnp_route(dst, ro, flags, first_hop, ifp) -struct iso_addr *dst; /* ptr to datagram destination */ -struct route_iso *ro; /* existing route structure */ -int flags; /* flags for routing */ -struct sockaddr **first_hop; /* result: fill in with ptr to firsthop */ -struct ifnet **ifp; /* result: fill in with ptr to interface */ +clnp_route(dst, ro, flags, first_hop, ifa) + struct iso_addr *dst; /* ptr to datagram destination */ + register struct route_iso *ro; /* existing route structure */ + int flags; /* flags for routing */ + struct sockaddr **first_hop; /* result: fill in with ptr to firsthop */ + struct iso_ifaddr **ifa; /* result: fill in with ptr to interface */ { - register struct sockaddr_iso *ro_dst; /* ptr to route's destination */ - - ro_dst = (struct sockaddr_iso *)&ro->ro_dst; - + if (flags & SO_DONTROUTE) { + struct sockaddr_iso dest; + struct iso_ifaddr *ia; + + bzero((caddr_t)&dest, sizeof(dest)); + bcopy((caddr_t)dst, (caddr_t)&dest.siso_addr, + 1 + (unsigned)dst->isoa_len); + dest.siso_family = AF_ISO; + dest.siso_len = sizeof(dest); + ia = iso_localifa(&dest); + if (ia == 0) + return EADDRNOTAVAIL; + if (ifa) + *ifa = (struct iso_ifaddr *)ia; + return 0; + } /* * If there is a cached route, check that it is still up and to * the same destination. If not, free it and try again. */ if (ro->ro_rt && ((ro->ro_rt->rt_flags & RTF_UP) == 0 || - (!iso_addrmatch1(&ro_dst->siso_addr, dst)))) { + (Bcmp(ro->ro_dst.siso_data, dst->isoa_genaddr, dst->isoa_len)))) { IFDEBUG(D_ROUTE) printf("clnp_route: freeing old route: ro->ro_rt 0x%x\n", ro->ro_rt); @@ -434,27 +447,29 @@ struct ifnet **ifp; /* result: fill in with ptr to interface */ if (ro->ro_rt == 0) { /* set up new route structure */ - ro_dst->siso_family = AF_ISO; - ro_dst->siso_addr = *dst; - + bzero((caddr_t)&ro->ro_dst, sizeof(ro->ro_dst)); + ro->ro_dst.siso_len = sizeof(ro->ro_dst); + ro->ro_dst.siso_family = AF_ISO; + Bcopy(dst, &ro->ro_dst.siso_addr, 1 + dst->isoa_len); /* allocate new route */ IFDEBUG(D_ROUTE) printf("clnp_route: allocating new route to %s\n", clnp_iso_addrp(dst)); ENDDEBUG - rtalloc(ro); + rtalloc((struct route *)ro); } - - if ((ro->ro_rt == 0) || ((*ifp = ro->ro_rt->rt_ifp) == 0)) { + if (ro->ro_rt == 0) return(ENETUNREACH); /* rtalloc failed */ - } - ro->ro_rt->rt_use++; - if (ro->ro_rt->rt_flags & (RTF_GATEWAY|RTF_HOST)) - *first_hop = &ro->ro_rt->rt_gateway; - else - *first_hop = (struct sockaddr *)ro_dst; - + if (ifa) + if ((*ifa = (struct iso_ifaddr *)ro->ro_rt->rt_ifa) == 0) + panic("clnp_route"); + if (first_hop) { + if (ro->ro_rt->rt_flags & (RTF_GATEWAY|RTF_HOST)) + *first_hop = ro->ro_rt->rt_gateway; + else + *first_hop = (struct sockaddr *)&ro->ro_dst; + } return(0); } @@ -475,12 +490,12 @@ struct ifnet **ifp; /* result: fill in with ptr to interface */ * NOTES: Remember that option index pointers are really * offsets from the beginning of the mbuf. */ -clnp_srcroute(options, oidx, route, first_hop, ifp, final_dst) +clnp_srcroute(options, oidx, route, first_hop, ifa, final_dst) struct mbuf *options; /* ptr to options */ struct clnp_optidx *oidx; /* index to options */ -struct route *route; /* route structure */ +struct route_iso *route; /* route structure */ struct sockaddr **first_hop; /* RETURN: fill in with ptr to firsthop */ -struct ifnet **ifp; /* RETURN: fill in with ptr to interface */ +struct iso_ifaddr **ifa; /* RETURN: fill in with ptr to interface */ struct iso_addr *final_dst; /* final destination */ { struct iso_addr dst; /* first hop specified by src rt */ @@ -492,19 +507,19 @@ struct iso_addr *final_dst; /* final destination */ */ if CLNPSRCRT_TERM(oidx, options) { dst.isoa_len = final_dst->isoa_len; - bcopy((caddr_t)final_dst, (caddr_t)&dst, dst.isoa_len); + bcopy(final_dst->isoa_genaddr, dst.isoa_genaddr, dst.isoa_len); } else { /* * setup dst based on src rt specified */ dst.isoa_len = CLNPSRCRT_CLEN(oidx, options); - bcopy(CLNPSRCRT_CADDR(oidx, options), (caddr_t)&dst, dst.isoa_len); + bcopy(CLNPSRCRT_CADDR(oidx, options), dst.isoa_genaddr, dst.isoa_len); } /* * try to route it */ - error = clnp_route(&dst, route, 0, first_hop, ifp); + error = clnp_route(&dst, route, 0, first_hop, ifa); if (error != 0) return error; @@ -522,66 +537,6 @@ struct iso_addr *final_dst; /* final destination */ return error; } -/* - * FUNCTION: clnp_srcaddr - * - * PURPOSE: Build the correct source address for a datagram based on the - * outgoing interface and firsthop. The firsthop information - * is needed inorder to decide which addr to use if - * >1 ISO addr is present for an ifp. - * - * RETURNS: a ptr to a static copy of the source address. - * or NULL - * - * SIDE EFFECTS: - * - * NOTES: The ifp must be valid, or we will return NULL - */ -static struct iso_addr mysrc; -struct iso_addr * -clnp_srcaddr(ifp, firsthop) -struct ifnet *ifp; /* ptr to interface to send packet on */ -struct iso_addr *firsthop; /* ptr to first hop for packet */ -{ - register struct iso_ifaddr *ia; /* scan through interface addresses */ - struct iso_addr *maybe = NULL; - - for (ia = iso_ifaddr; ia; ia = ia->ia_next) { - if (ia->ia_ifp == ifp) { - struct iso_addr *isoa = &IA_SIS(ia)->siso_addr; - - IFDEBUG(D_ROUTE) - printf("clnp_srcaddr: isoa is %s\n", clnp_iso_addrp(isoa)); - ENDDEBUG - - if (iso_eqtype(isoa, firsthop)) { - mysrc.isoa_len = isoa->isoa_len; - bcopy((caddr_t)isoa, (caddr_t)&mysrc, mysrc.isoa_len); - return(&mysrc); - } else - maybe = isoa; - } - } - - if (maybe != NULL) { - mysrc.isoa_len = maybe->isoa_len; - bcopy((caddr_t)maybe, (caddr_t)&mysrc, mysrc.isoa_len); - return(&mysrc); - } else { - /* - * This will only happen if there are routes involving - * an interface that has just had all iso addresses deleted - * from it. This will happen if esisd has added a default - * route to an interface, and then the interface was - * marked down. As soon as esisd tries to send a pdu on that - * interface, it will discover it is down, and remove the - * route. Nonetheless, there is a window for this discrepancy, - * so we will return null here rather than panicing. - */ - return(NULL); - } -} - /* * FUNCTION: clnp_ypocb - backwards bcopy * diff --git a/usr/src/sys/netiso/clnp_timer.c b/usr/src/sys/netiso/clnp_timer.c index a1651a71a4..e21fe7c882 100644 --- a/usr/src/sys/netiso/clnp_timer.c +++ b/usr/src/sys/netiso/clnp_timer.c @@ -33,22 +33,22 @@ static char *rcsid = "$Header: clnp_timer.c,v 4.2 88/06/29 14:59:05 hagens Exp $ #ifdef ISO -#include "../h/types.h" -#include "../h/param.h" -#include "../h/mbuf.h" -#include "../h/domain.h" -#include "../h/protosw.h" -#include "../h/socket.h" -#include "../h/socketvar.h" -#include "../h/errno.h" +#include "types.h" +#include "param.h" +#include "mbuf.h" +#include "domain.h" +#include "protosw.h" +#include "socket.h" +#include "socketvar.h" +#include "errno.h" #include "../net/if.h" #include "../net/route.h" -#include "../netiso/iso.h" -#include "../netiso/clnp.h" -#include "../netiso/clnp_stat.h" -#include "../netiso/argo_debug.h" +#include "iso.h" +#include "clnp.h" +#include "clnp_stat.h" +#include "argo_debug.h" extern struct clnp_fragl *clnp_frags; diff --git a/usr/src/sys/netiso/eonvar.h b/usr/src/sys/netiso/eonvar.h index 06d80f7c90..9cb56f099b 100644 --- a/usr/src/sys/netiso/eonvar.h +++ b/usr/src/sys/netiso/eonvar.h @@ -23,6 +23,7 @@ SOFTWARE. /* * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison + * @(#)eonvar.h 7.2 (Berkeley) %G% */ #define EON_986_VERSION 0x3 @@ -41,37 +42,44 @@ SOFTWARE. */ struct sockaddr_eon { - short seon_family; /* AF_ISO */ - u_short seon_status; /* overlays transport suffix */ + u_char seon_len; /* Length */ + u_char seon_family; /* AF_ISO */ + u_char seon_status; /* overlays session suffixlen */ #define EON_ESLINK_UP 0x1 #define EON_ESLINK_DOWN 0x2 #define EON_ISLINK_UP 0x10 #define EON_ISLINK_DOWN 0x20 /* no change is neither up or down */ - + u_char seon_pad1; /* 0, overlays tsfxlen */ + u_char seon_adrlen; u_char seon_afi; /* 47 */ u_char seon_idi[2]; /* 0006 */ u_char seon_vers; /* 03 */ + u_char seon_glbnum[2]; /* see RFC 1069 */ + u_char seon_RDN[2]; /* see RFC 1070 */ + u_char seon_pad2[3]; /* see RFC 1070 */ + u_char seon_LAREA[2]; /* see RFC 1070 */ + u_char seon_pad3[2]; /* see RFC 1070 */ /* right now ip addr is aligned -- be careful -- * future revisions may have it u_char[4] */ u_int seon_ipaddr; /* a.b.c.d */ - u_char seon_protoid[1]; /* */ - u_char seon_adrlen; - u_short seon_netype[2]; + u_char seon_protoid; /* NSEL */ }; +#ifdef EON_TEMPLATE struct sockaddr_eon eon_template = { - AF_ISO, 0, 0x47, 0x0, 0x6, 0x3, - 0, - 0, - 0xa, - 0 + sizeof (eon_template), AF_ISO, 0, 0, 0x14, + 0x47, 0x0, 0x6, 0x3, 0 }; +#endif #define DOWNBITS ( EON_ESLINK_DOWN | EON_ISLINK_DOWN ) #define UPBITS ( EON_ESLINK_UP | EON_ISLINK_UP ) +#define SIOCSEONCORE _IOWR('i',10, struct iso_ifreq) /* EON core member */ +#define SIOCGEONCORE _IOWR('i',11, struct iso_ifreq) /* EON core member */ + struct eon_hdr { u_char eonh_vers; /* value 1 */ u_char eonh_class; /* address multicast class, below */ @@ -81,6 +89,7 @@ struct eon_hdr { #define EON_BROADCAST 0x3 u_short eonh_csum; /* osi checksum (choke)*/ }; +#define EONIPLEN (sizeof(struct eon_hdr) + sizeof(struct ip)) /* stole these 2 fields of the flags for I-am-ES and I-am-IS */ #define IFF_ES 0x400 @@ -105,3 +114,7 @@ struct eon_stat { #undef IncStat #define IncStat(xxx) eonstat.xxx++ + +typedef struct qhdr { + struct qhdr *link, *rlink; +} *queue_t; diff --git a/usr/src/sys/netiso/esis.c b/usr/src/sys/netiso/esis.c index e40417d43a..13c4a15909 100644 --- a/usr/src/sys/netiso/esis.c +++ b/usr/src/sys/netiso/esis.c @@ -30,30 +30,30 @@ static char *rcsid = "$Header: esis.c,v 4.10 88/09/15 18:57:03 hagens Exp $"; #ifdef ISO -#include "../h/types.h" -#include "../h/param.h" -#include "../h/mbuf.h" -#include "../h/domain.h" -#include "../h/protosw.h" -#include "../h/dir.h" -#include "../h/user.h" -#include "../h/socket.h" -#include "../h/socketvar.h" -#include "../h/errno.h" -#include "../h/kernel.h" +#include "types.h" +#include "param.h" +#include "mbuf.h" +#include "domain.h" +#include "protosw.h" +#include "dir.h" +#include "user.h" +#include "socket.h" +#include "socketvar.h" +#include "errno.h" +#include "kernel.h" #include "../net/if.h" #include "../net/route.h" -#include "../netiso/iso.h" -#include "../netiso/iso_pcb.h" -#include "../netiso/iso_var.h" -#include "../netiso/iso_snpac.h" -#include "../netiso/clnl.h" -#include "../netiso/clnp.h" -#include "../netiso/clnp_stat.h" -#include "../netiso/argo_debug.h" -#include "../netiso/esis.h" +#include "iso.h" +#include "iso_pcb.h" +#include "iso_var.h" +#include "iso_snpac.h" +#include "clnl.h" +#include "clnp.h" +#include "clnp_stat.h" +#include "argo_debug.h" +#include "esis.h" /* * Global variables to esis implementation @@ -70,15 +70,13 @@ short esis_config_time = ESIS_CONFIG; extern int iso_systype; extern struct snpa_cache all_es, all_is; -#define EXTEND_PACKET(m, mhdr, len, cp)\ +#define EXTEND_PACKET(m, mhdr, cp)\ if (((m)->m_next = m_getclr(M_DONTWAIT, MT_HEADER)) == NULL) {\ esis_stat.es_nomem++;\ m_freem(mhdr);\ return;\ } else {\ - (m)->m_len = (len);\ (m) = (m)->m_next;\ - (len) = 0;\ (cp) = mtod((m), caddr_t);\ } /* @@ -124,6 +122,7 @@ esis_init() * * NOTES: This is here only so esis gets initialized. */ +/*ARGSUSED*/ esis_usrreq(so, req, m, nam, rights) struct socket *so; /* socket: used only to get to this code */ int req; /* request */ @@ -152,8 +151,8 @@ esis_input(m0, shp) struct mbuf *m0; /* ptr to first mbuf of pkt */ struct snpa_hdr *shp; /* subnetwork header */ { - struct isopcb *isop; struct esis_fixed *pdu = mtod(m0, struct esis_fixed *); + register int type; IFDEBUG(D_ESISINPUT) int i; @@ -171,7 +170,7 @@ struct snpa_hdr *shp; /* subnetwork header */ /* * check checksum if necessary */ - if (ESIS_CKSUM_REQUIRED(pdu) && iso_check_csum(m0, pdu->esis_hdr_len)) { + if (ESIS_CKSUM_REQUIRED(pdu) && iso_check_csum(m0, (int)pdu->esis_hdr_len)) { esis_stat.es_badcsum++; goto bad; } @@ -182,7 +181,8 @@ struct snpa_hdr *shp; /* subnetwork header */ goto bad; } - switch(pdu->esis_type) { + type = pdu->esis_type & 0x1f; + switch (type) { case ESIS_ESH: esis_eshinput(m0, shp); return; @@ -235,7 +235,6 @@ struct snpa_cache *nhop_sc; /* snpa cache info regarding next hop of esis_stat.es_rdsent++; IFDEBUG(D_ESISOUTPUT) - int i; printf("esis_rdoutput: ifp x%x (%s%d), ht %d, m x%x, oidx x%x\n", ifp, ifp->if_name, ifp->if_unit, esis_holding_time, inbound_m, inbound_oidx); @@ -243,13 +242,14 @@ struct snpa_cache *nhop_sc; /* snpa cache info regarding next hop of printf("\tredirected toward:%s\n", clnp_iso_addrp(&nhop_sc->sc_nsap)); ENDDEBUG - if ((m0 = m = m_getclr(M_DONTWAIT, MT_HEADER)) == NULL) { + if ((m0 = m = m_gethdr(M_DONTWAIT, MT_HEADER)) == NULL) { esis_stat.es_nomem++; return; } + bzero(mtod(m, caddr_t), MHLEN); pdu = mtod(m, struct esis_fixed *); - cp = (caddr_t)pdu + sizeof(struct esis_fixed); + cp = (caddr_t)(pdu + 1); /*pointer arith.; 1st byte after header */ len = sizeof(struct esis_fixed); /* @@ -261,11 +261,11 @@ struct snpa_cache *nhop_sc; /* snpa cache info regarding next hop of HTOC(pdu->esis_ht_msb, pdu->esis_ht_lsb, esis_holding_time); /* Insert destination address */ - (void) esis_insert_addr(&cp, &len, rd_dstnsap, MLEN - len); + (void) esis_insert_addr(&cp, &len, rd_dstnsap, m); /* Insert the snpa of better next hop */ *cp++ = nhop_sc->sc_len; - bcopy(nhop_sc->sc_snpa, cp, nhop_sc->sc_len); + bcopy((caddr_t)nhop_sc->sc_snpa, cp, nhop_sc->sc_len); len += (nhop_sc->sc_len + 1); /* @@ -281,11 +281,12 @@ struct snpa_cache *nhop_sc; /* snpa cache info regarding next hop of m_freem(m0); return; } - (void) esis_insert_addr(&cp, &len, &nhop_sc->sc_nsap, MLEN - len); + (void) esis_insert_addr(&cp, &len, &nhop_sc->sc_nsap, m); } else { *cp++ = 0; /* NETL */ len++; } + m->m_len = len; /* * PHASE2 @@ -306,9 +307,9 @@ struct snpa_cache *nhop_sc; /* snpa cache info regarding next hop of optlen += 3; if (inbound_oidx->cni_securep) optlen += (inbound_oidx->cni_secure_len + 2); - if (MLEN-len < optlen) { - total_len += len; - EXTEND_PACKET(m, m0, len, cp); + if (M_TRAILINGSPACE(m) < optlen) { + EXTEND_PACKET(m, m0, cp); + m->m_len = 0; /* assumes MLEN > optlen */ } /* assume MLEN-len > optlen */ @@ -317,69 +318,35 @@ struct snpa_cache *nhop_sc; /* snpa cache info regarding next hop of * the option code and length */ if (inbound_oidx->cni_qos_formatp) { - bcopy(inbound_m + inbound_oidx->cni_qos_formatp - 2, cp, - inbound_oidx->cni_qos_len + 2); + bcopy((caddr_t)(inbound_m + inbound_oidx->cni_qos_formatp - 2), cp, + (unsigned)(inbound_oidx->cni_qos_len + 2)); len += inbound_oidx->cni_qos_len + 2; } if (inbound_oidx->cni_priorp) { - bcopy(inbound_m + inbound_oidx->cni_priorp - 2, cp, 3); + bcopy((caddr_t)(inbound_m + inbound_oidx->cni_priorp - 2), cp, 3); len += 3; } if (inbound_oidx->cni_securep) { - bcopy(inbound_m + inbound_oidx->cni_securep - 2, cp, - inbound_oidx->cni_secure_len + 2); + bcopy((caddr_t)(inbound_m + inbound_oidx->cni_securep - 2), cp, + (unsigned)(inbound_oidx->cni_secure_len + 2)); len += inbound_oidx->cni_secure_len + 2; } + m->m_len += optlen; } - m->m_len = len; - total_len += len; - pdu->esis_hdr_len = total_len; + pdu->esis_hdr_len = m0->m_pkthdr.len = len; iso_gen_csum(m0, ESIS_CKSUM_OFF, (int)pdu->esis_hdr_len); + bzero((caddr_t)&siso, sizeof(siso)); + siso.siso_len = 12; siso.siso_family = AF_ISO; - siso.siso_addr.isoa_afi = AFI_SNA; - siso.siso_addr.isoa_len = 6 + 1; /* should be taken from snpa_hdr */ + siso.siso_data[0] = AFI_SNA; + siso.siso_nlen = 6 + 1; /* should be taken from snpa_hdr */ /* +1 is for AFI */ - bcopy(inbound_shp->snh_shost, siso.siso_addr.sna_idi, 6); + bcopy(inbound_shp->snh_shost, siso.siso_data + 1, 6); (ifp->if_output)(ifp, m0, &siso); } -/* - * FUNCTION: esis_extract_addr - * - * PURPOSE: Remove an addr from a buffer, and stuff in iso_addr - * - * RETURNS: true if the address was complete, else false - * - * SIDE EFFECTS: Increment buf and decrement len according to the - * size of the iso_addr - * - * NOTES: - */ -esis_extract_addr(buf, isoa, len) -caddr_t *buf; /* ptr to buffer to put address into */ -struct iso_addr *isoa; /* ptr to address */ -int *len; /* ptr to length of buffer */ -{ - caddr_t bp = *buf; - - if (*len <= 0) - return(0); - - bzero((caddr_t)isoa, sizeof (struct iso_addr)); - isoa->isoa_len = *bp++; - *len -= 1; - if (isoa->isoa_len > *len) - return(0); /* too big */ - bcopy(bp, (caddr_t)isoa, isoa->isoa_len); - *len -= isoa->isoa_len; - bp += isoa->isoa_len; - *buf = bp; - - return(1); -} - /* * FUNCTION: esis_insert_addr * @@ -391,22 +358,20 @@ int *len; /* ptr to length of buffer */ * * NOTES: Plus 1 here is for length byte */ -esis_insert_addr(buf, len, isoa, remaining) +esis_insert_addr(buf, len, isoa, m) caddr_t *buf; /* ptr to buffer to put address into */ int *len; /* ptr to length of buffer so far */ struct iso_addr *isoa; /* ptr to address */ -int remaining; /* length of buffer */ +register struct mbuf *m; /* determine if there remains space */ { - caddr_t bp = *buf; + register int newlen = isoa->isoa_len + 1; - if ((isoa->isoa_len+1) > remaining) + if (newlen > M_TRAILINGSPACE(m)) return(0); - *bp++ = isoa->isoa_len; - *len += 1; - bcopy((caddr_t)isoa, bp, isoa->isoa_len); - bp += isoa->isoa_len; - *len += isoa->isoa_len; - *buf = bp; + bcopy((caddr_t)isoa, *buf, newlen); + *len += newlen; + *buf += newlen; + m->m_len += newlen; return(1); } @@ -429,10 +394,11 @@ struct snpa_hdr *shp; /* subnetwork header */ { struct esis_fixed *pdu = mtod(m, struct esis_fixed *); u_short ht; /* holding time */ - struct iso_addr nsap; - int naddr; - caddr_t buf = (caddr_t)pdu + sizeof(struct esis_fixed); + struct iso_addr *nsap; + int naddr = 0; + u_char *buf = (u_char *)(pdu + 1); int len = pdu->esis_hdr_len - sizeof(struct esis_fixed); + int optlen, new_entry; esis_stat.es_eshrcvd++; @@ -449,26 +415,28 @@ struct snpa_hdr *shp; /* subnetwork header */ ENDDEBUG while (naddr-- > 0) { - if (esis_extract_addr(&buf, &nsap, &len)) { - int new_entry = (snpac_look(&nsap) == NULL); + nsap = (struct iso_addr *)buf; + if ((len -= (optlen = *buf++)) >= 0) { + buf += optlen; + new_entry = (snpac_look(nsap) == NULL); IFDEBUG(D_ESISINPUT) printf("esis_eshinput: nsap %s is %s\n", - clnp_iso_addrp(&nsap), new_entry ? "new" : "old"); + clnp_iso_addrp(nsap), new_entry ? "new" : "old"); ENDDEBUG - snpac_add(shp->snh_ifp, &nsap, shp->snh_shost, 6, SNPA_ES, ht); + snpac_add(shp->snh_ifp, nsap, shp->snh_shost, 6, SNPA_ES, ht); if (new_entry) esis_shoutput(shp->snh_ifp, iso_systype & SNPA_ES ? ESIS_ESH : ESIS_ISH, esis_holding_time, shp->snh_shost, 6); } else { +bad: esis_stat.es_toosmall++; break; } } -bad: m_freem(m); } @@ -489,9 +457,10 @@ struct snpa_hdr *shp; /* subnetwork header */ { struct esis_fixed *pdu = mtod(m, struct esis_fixed *); u_short ht; /* holding time */ - struct iso_addr nsap; + struct iso_addr *nsap; caddr_t buf = (caddr_t)pdu + sizeof(struct esis_fixed); int len = pdu->esis_hdr_len - sizeof(struct esis_fixed); + int optlen, new_entry; esis_stat.es_ishrcvd++; CTOH(pdu->esis_ht_msb, pdu->esis_ht_lsb, ht); @@ -500,22 +469,39 @@ struct snpa_hdr *shp; /* subnetwork header */ printf("esis_ishinput: ish: ht %d\n", ht); ENDDEBUG - if (esis_extract_addr(&buf, &nsap, &len)) { - int new_entry = (snpac_look(&nsap) == NULL); + nsap = (struct iso_addr *)buf; + if ((len -= (optlen = *buf++)) < 0) + goto bad; + buf += optlen; + + /* process options */ + while (len > 0) { + switch (*buf++) { + case ESISOVAL_ESCT: + if (*buf != 2) + goto bad; + CTOH(buf[0], buf[1], esis_config_time); + } + if ((len -= (optlen = *buf)) < 0) { + bad: + esis_stat.es_toosmall++; + m_freem(m); + return; + } + buf += 1 + optlen; + } + new_entry = (snpac_look(nsap) == NULL); - IFDEBUG(D_ESISINPUT) - printf("esis_ishinput: nsap %s is %s\n", - clnp_iso_addrp(&nsap), new_entry ? "new" : "old"); - ENDDEBUG + IFDEBUG(D_ESISINPUT) + printf("esis_ishinput: nsap %s is %s\n", + clnp_iso_addrp(nsap), new_entry ? "new" : "old"); + ENDDEBUG - snpac_add(shp->snh_ifp, &nsap, shp->snh_shost, 6, SNPA_IS, ht); - if (new_entry) - esis_shoutput(shp->snh_ifp, - iso_systype & SNPA_ES ? ESIS_ESH : ESIS_ISH, - esis_holding_time, shp->snh_shost, 6); - } else { - esis_stat.es_toosmall++; - } + snpac_add(shp->snh_ifp, nsap, shp->snh_shost, 6, SNPA_IS, ht); + if (new_entry) + esis_shoutput(shp->snh_ifp, + iso_systype & SNPA_ES ? ESIS_ESH : ESIS_ISH, + esis_holding_time, shp->snh_shost, 6); m_freem(m); } @@ -536,13 +522,11 @@ struct snpa_hdr *shp; /* subnetwork header */ { struct esis_fixed *pdu = mtod(m0, struct esis_fixed *); u_short ht; /* holding time */ - struct iso_addr da; - caddr_t bsnpa; - int bsnpalen; - struct iso_addr net; - int netl; - caddr_t buf = (caddr_t)pdu + sizeof(struct esis_fixed); + register struct iso_addr *da, *net = 0, *netmask = 0, *snpamask = 0; + u_char *buf = (u_char *)(pdu + 1); int len = pdu->esis_hdr_len - sizeof(struct esis_fixed); + int optlen, bsnpalen; + caddr_t bsnpa; esis_stat.es_rdrcvd++; @@ -551,38 +535,53 @@ struct snpa_hdr *shp; /* subnetwork header */ goto bad; CTOH(pdu->esis_ht_msb, pdu->esis_ht_lsb, ht); + if (len <= 0) + goto bad; /* Extract DA */ - if (!esis_extract_addr(&buf, &da, &len)) { - esis_stat.es_toosmall++; + da = (struct iso_addr *)buf; + if ((len -= (optlen = *buf++)) <= 0) goto bad; - } - + buf += optlen; + /* Extract better snpa */ - bsnpalen = *buf++; - if (bsnpalen > len) { - esis_stat.es_toosmall++; + if ((len -= (bsnpalen = *buf++)) < 0) goto bad; - } else { - bsnpa = buf; - buf += bsnpalen; - len -= bsnpalen; - } - + bsnpa = (caddr_t)buf; + buf += optlen; + /* Extract NET if present */ - if ((netl = *buf) > 0) { - if (!esis_extract_addr(&buf, &net, &len)) { - esis_stat.es_toosmall++; + if (len) { + net = (struct iso_addr *)buf; + if ((len -= (optlen = *buf++)) < 0) goto bad; + buf += optlen; + } + + /* process options */ + while (len > 0) { + switch (*buf++) { + case ESISOVAL_SNPAMASK: + if (snpamask) /* duplicate */ + goto bad; + snpamask = (struct iso_addr *)buf; + break; + + case ESISOVAL_NETMASK: + if (netmask) /* duplicate */ + goto bad; + netmask = (struct iso_addr *)buf; } + if ((len -= (optlen = *buf)) < 0) + goto bad; + buf += 1 + optlen; } IFDEBUG(D_ESISINPUT) - printf("esis_rdinput: rd: ht %d, da %s\n", ht, clnp_iso_addrp(&da)); - if (netl) - printf("\t: net %s\n", clnp_iso_addrp(&net)); + printf("esis_rdinput: rd: ht %d, da %s\n", ht, clnp_iso_addrp(da)); + if (net) + printf("\t: net %s\n", clnp_iso_addrp(net)); ENDDEBUG - /* * If netl is zero, then redirect is to an ES. We need to add an entry * to the snpa cache for (destination, better snpa). @@ -592,12 +591,16 @@ struct snpa_hdr *shp; /* subnetwork header */ * If the redirect is to an IS, add a route entry towards that * IS. */ - if (netl == 0) { + if ((net == 0) || (snpamask)) { /* redirect to an ES */ - snpac_add(shp->snh_ifp, &da, bsnpa, bsnpalen, SNPA_ES, ht); + snpac_add(shp->snh_ifp, da, bsnpa, bsnpalen, SNPA_ES, ht); } else { - snpac_add(shp->snh_ifp, &net, bsnpa, bsnpalen, SNPA_IS, ht); - snpac_addrt(&da, &net); + struct iso_addr bsnpa_ia; + + snpac_add(shp->snh_ifp, net, bsnpa, bsnpalen, SNPA_IS, ht); + bcopy(bsnpa, bsnpa_ia.isoa_genaddr, bsnpa_ia.isoa_len = 1 + bsnpalen); + bsnpa_ia.isoa_genaddr[0] = AFI_SNA; + snpac_addrt(da, &bsnpa_ia, net, netmask); } bad: m_freem(m0); @@ -636,12 +639,12 @@ esis_config() struct ifaddr *ia; for (ia = ifp->if_addrlist; ia; ia = ia->ifa_next) { - if (ia->ifa_addr.sa_family == AF_ISO) { + if (ia->ifa_addr->sa_family == AF_ISO) { esis_shoutput(ifp, iso_systype & SNPA_ES ? ESIS_ESH : ESIS_ISH, esis_holding_time, - iso_systype & SNPA_ES ? all_is.sc_snpa : - all_es.sc_snpa, 6); + (caddr_t)(iso_systype & SNPA_ES ? all_is.sc_snpa : + all_es.sc_snpa), 6); break; } } @@ -672,7 +675,7 @@ int sn_len; int naddr = 0; struct esis_fixed *pdu; struct ifaddr *ifa; - int len, total_len = 0; + int len; struct sockaddr_iso siso; if (type == ESIS_ESH) @@ -694,13 +697,14 @@ int sn_len; printf("\n"); ENDDEBUG - if ((m0 = m = m_getclr(M_DONTWAIT, MT_HEADER)) == NULL) { + if ((m0 = m = m_gethdr(M_DONTWAIT, MT_HEADER)) == NULL) { esis_stat.es_nomem++; return; } + bzero(mtod(m, caddr_t), MHLEN); pdu = mtod(m, struct esis_fixed *); - naddrp = cp = (caddr_t)pdu + sizeof(struct esis_fixed); + naddrp = cp = (caddr_t)(pdu + 1); len = sizeof(struct esis_fixed); /* @@ -716,18 +720,16 @@ int sn_len; len++; } + m->m_len = len; for (ifa = ifp->if_addrlist; ifa; ifa=ifa->ifa_next) { - if (ifa->ifa_addr.sa_family == AF_ISO) { + if (ifa->ifa_addr->sa_family == AF_ISO) { IFDEBUG(D_ESISOUTPUT) printf("esis_shoutput: adding nsap %s\n", clnp_iso_addrp(&IA_SIS(ifa)->siso_addr)); ENDDEBUG - if (!esis_insert_addr(&cp, &len, &IA_SIS(ifa)->siso_addr, - MLEN - len)) { - total_len += len; - EXTEND_PACKET(m, m0, len, cp); - (void) esis_insert_addr(&cp, &len, &IA_SIS(ifa)->siso_addr, - MLEN - len); + if (!esis_insert_addr(&cp, &len, &IA_SIS(ifa)->siso_addr, m)) { + EXTEND_PACKET(m, m0, cp); + (void) esis_insert_addr(&cp, &len, &IA_SIS(ifa)->siso_addr, m); } naddr++; if (type == ESIS_ISH) @@ -738,15 +740,16 @@ int sn_len; if (type == ESIS_ESH) *naddrp = naddr; - m->m_len = len; - total_len += len; - pdu->esis_hdr_len = total_len; + m0->m_pkthdr.len = len; + pdu->esis_hdr_len = len; iso_gen_csum(m0, ESIS_CKSUM_OFF, (int)pdu->esis_hdr_len); + bzero((caddr_t)&siso, sizeof(siso)); siso.siso_family = AF_ISO; - siso.siso_addr.isoa_afi = AFI_SNA; - siso.siso_addr.isoa_len = sn_len + 1; - bcopy(sn_addr, siso.siso_addr.sna_idi, sn_len); + siso.siso_data[0] = AFI_SNA; + siso.siso_nlen = sn_len + 1; + siso.siso_len = sn_len + 6; + bcopy(sn_addr, siso.siso_data + 1, (unsigned)sn_len); (ifp->if_output)(ifp, m0, &siso); } @@ -769,10 +772,11 @@ struct sockaddr_iso *siso; /* address of ifp */ { register struct iso_ifaddr *ia; /* scan through interface addresses */ - for (ia = iso_ifaddr; ia; ia = ia->ia_next) { - if (iso_addrmatch(IA_SIS(ia), siso)) - snpac_flushifp(ia->ia_ifp); - } + if (req == PRC_IFDOWN) + for (ia = iso_ifaddr; ia; ia = ia->ia_next) { + if (iso_addrmatch(IA_SIS(ia), siso)) + snpac_flushifp(ia->ia_ifp); + } } #endif ISO diff --git a/usr/src/sys/netiso/esis.h b/usr/src/sys/netiso/esis.h index 570f406394..f50c60796e 100644 --- a/usr/src/sys/netiso/esis.h +++ b/usr/src/sys/netiso/esis.h @@ -57,29 +57,23 @@ struct esis_fixed { u_char esis_hdr_len; /* length indicator (octets) */ u_char esis_vers; /* version/protocol identifier extension */ u_char esis_res1; /* reserved */ -#if BYTE_ORDER == LITTLE_ENDIAN - u_char esis_type:5, /* type code */ - esis_res4:1, /* reserved */ - esis_res3:1, /* reserved */ - esis_res2:1; /* reserved */ + u_char esis_type; /* type code */ +/* technically, type should be &='d 0x1f */ #define ESIS_ESH 0x02 /* End System Hello */ #define ESIS_ISH 0x04 /* Intermediate System Hello */ #define ESIS_RD 0x06 /* Redirect */ -#endif -#if BYTE_ORDER == BIG_ENDIAN - u_char esis_res2:1, /* reserved */ - esis_res3:1, /* reserved */ - esis_res4:1, /* reserved */ - esis_type:5; /* type code */ -#define ESIS_ESH 0x02 /* End System Hello */ -#define ESIS_ISH 0x04 /* Intermediate System Hello */ -#define ESIS_RD 0x06 /* Redirect */ -#endif u_char esis_ht_msb; /* holding time (seconds) high byte */ u_char esis_ht_lsb; /* holding time (seconds) low byte */ u_char esis_cksum_msb; /* checksum high byte */ u_char esis_cksum_lsb; /* checksum low byte */ }; +/* + * Values for ESIS datagram options + */ +#define ESISOVAL_NETMASK 0xe1 /* address mask option, RD PDU only */ +#define ESISOVAL_SNPAMASK 0xe2 /* snpa mask option, RD PDU only */ +#define ESISOVAL_ESCT 0xc6 /* end system conf. timer, ISH PDU only */ + #define ESIS_CKSUM_OFF 0x07 #define ESIS_CKSUM_REQUIRED(pdu)\ diff --git a/usr/src/sys/netiso/if_eon.c b/usr/src/sys/netiso/if_eon.c index 7cf9c2dcbc..53265b033c 100644 --- a/usr/src/sys/netiso/if_eon.c +++ b/usr/src/sys/netiso/if_eon.c @@ -35,14 +35,14 @@ SOFTWARE. * Put together a current rfc986 address format and get the right offset * for the nsel */ -#define RFC986_NSEL_OFFSET 5 #ifndef lint static char *rcsid = "$Header: if_eon.c,v 1.4 88/07/19 15:53:59 hagens Exp $"; #endif lint -#include "eon.h" -#if NEON>0 +#ifdef EON +#define NEON 1 + #include "param.h" #include "systm.h" @@ -55,12 +55,11 @@ static char *rcsid = "$Header: if_eon.c,v 1.4 88/07/19 15:53:59 hagens Exp $"; #include "errno.h" #include "types.h" -#include "../machine/io.h" -#include "../machineio/ioccvar.h" - #include "../net/if.h" +#include "../net/iftypes.h" #include "../net/netisr.h" #include "../net/route.h" +#include "../machine/mtpr.h" #include "../netinet/in.h" #include "../netinet/in_systm.h" @@ -68,10 +67,13 @@ static char *rcsid = "$Header: if_eon.c,v 1.4 88/07/19 15:53:59 hagens Exp $"; #include "../netinet/ip_var.h" #include "../netinet/if_ether.h" -#include "../netiso/iso.h" -#include "../netiso/argo_debug.h" -#include "../netiso/iso_errno.h" -#include "../netiso/eonvar.h" +#include "iso.h" +#include "iso_var.h" +#include "iso_snpac.h" +extern struct snpa_cache all_es, all_is; +#include "argo_debug.h" +#include "iso_errno.h" +#include "eonvar.h" #define EOK 0 @@ -85,6 +87,10 @@ int eoninit(); extern int ip_output(); struct ifnet eonif[NEON]; +#ifdef FAKEIOCCDEV +#include "../machine/io.h" +#include "../machineio/ioccvar.h" + #define EON_FAKE_CSR 0 int eon_fakeautoconf[2]; /* need at least 2 ints */ @@ -106,6 +112,17 @@ struct iocc_driver eondriver = { EON_FAKE_CSR, /* idr_chanrelse */ 0, /* idr_flags */ }; +#else +struct iocc_device { + int iod_unit; +} bsd_iocc_fakeout; + +eonprotoinit() { + (void) eonprobe(); + (void) eonattach(&bsd_iocc_fakeout); +} +#define PROBE_OK 0; +#endif /* @@ -265,6 +282,7 @@ eon_initcache() * RETURNS: PROBE_OK */ +int int_level, int_irq; eonprobe() { extern int int_level, int_irq; @@ -296,9 +314,11 @@ eonattach(iod) /* since everything will go out over ether or token ring */ ifp->if_init = eoninit; - ifp->if_ioctl = eonioctl; /* needed? */ + ifp->if_ioctl = eonioctl; ifp->if_output = eonoutput; - ifp->if_reset = 0; + ifp->if_type = IFT_EON; + ifp->if_addrlen = 5; + ifp->if_hdrlen = EONIPLEN; ifp->if_flags = IFF_BROADCAST; if_attach(ifp); @@ -317,8 +337,9 @@ find_oldent( ea ) { register int offset = _offsetof( struct eon_centry, eonc_q_LINK); - register struct eon_centry *ent = qtocentry(eon_LINK_hdr.link, offset); + register struct eon_centry *ent, *oent; + oent = ent = qtocentry(eon_LINK_hdr.link, offset); IFDEBUG(D_EON) printf("eon: find_oldent() ipaddr: %d.%d.%d.%d\n", (ea->seon_ipaddr>>24)&0xff, @@ -326,10 +347,11 @@ find_oldent( ea ) (ea->seon_ipaddr>>8)&0xff, (ea->seon_ipaddr)&0xff ); ENDDEBUG - for (; ent; ent = qtocentry(ent->eonc_nextLINK, offset) ) { + do { if( ent->eonc_addr.s_addr == ea->seon_ipaddr ) return ent; - } + ent = qtocentry(ent->eonc_nextLINK, offset); + } while (ent != oent); return (struct eon_centry *)0; } @@ -349,9 +371,9 @@ eonioctl(ifp, cmd, data) register int cmd; register caddr_t data; { - struct ifreq *ifr = (struct ifreq *)data; + struct iso_ifreq *ifr = (struct iso_ifreq *)data; register struct sockaddr_eon *eoa = - (struct sockaddr_eon *)&(ifr->ifr_addr); + (struct sockaddr_eon *)&(ifr->ifr_Addr); register int s = splimp(); register int error = 0; @@ -360,7 +382,7 @@ eonioctl(ifp, cmd, data) ENDDEBUG switch (cmd){ - case SIOCSIFDSTADDR: { + case SIOCSEONCORE: { /* add pt-pt link to the set of core addrs */ register struct eon_centry *ent, *oldent; register u_short which; @@ -369,13 +391,9 @@ eonioctl(ifp, cmd, data) * want to insert something in a list if it's already there */ #define LEGIT_EONADDR(a)\ - ((a->seon_family == AF_ISO) && (a->seon_afi == 0x47) &&\ + ((a->seon_family == AF_ISO) && (a->seon_afi == AFI_RFC986) &&\ (a->seon_idi[0] == 0) && (a->seon_idi[1] == 6) \ - ) -#ifdef notdef - /* GET THESE RIGHT AND ADD THEM */ - && (a->seon_vers == 3) && (a->seon_adrlen == 0xa) -#endif notdef + && (a->seon_vers == EON_986_VERSION) && (a->seon_adrlen == 0x14)) if( ! LEGIT_EONADDR(eoa) ) { error = EADDRNOTAVAIL; @@ -391,12 +409,13 @@ eonioctl(ifp, cmd, data) if( eoa->seon_status & UPBITS ) { if (!oldent) { /* doesn't exist - need to create one */ - /* TODO : check for null free list */ + if (eon_FREE_hdr.link == eon_FREE_hdr.rlink) + return ENOBUFS; ent = qtocentry(eon_FREE_hdr.link, _offsetof( struct eon_centry, eonc_q_LINK)); remque( &(ent->eonc_q_LINK) ); ent->eonc_addr.s_addr = eoa->seon_ipaddr; - insque( &oldent->eonc_q_LINK, (&eon_LINK_hdr)); + insque( &(ent->eonc_q_LINK), (&eon_LINK_hdr)); oldent = ent; } @@ -432,7 +451,7 @@ eonioctl(ifp, cmd, data) break; } - case SIOCGIFDSTADDR: + case SIOCGEONCORE: { register struct eon_centry *oldent; @@ -474,7 +493,7 @@ eonioctl(ifp, cmd, data) eoninit(unit) int unit; { - printf("eoninit ecn%d\n", unit); + printf("eon driver-init eon%d\n", unit); } @@ -511,7 +530,7 @@ eonint() * */ eonoutput(ifp, morig, dst) - register struct ifnet *ifp; + struct ifnet *ifp; register struct mbuf *morig; /* packet */ struct sockaddr_iso *dst; /* destination addr */ { @@ -522,33 +541,58 @@ eonoutput(ifp, morig, dst) int error = 0; register int datalen; caddr_t dstipaddrloc; - int single=0; - int qoffset=0; + int single = 0, class, qoffset = 0, snpalen; register struct eon_centry *ent; + register struct sockaddr_eon *eoa; struct qhdr *q; + char edst[6]; IFDEBUG(D_EON) printf("eonoutput \n" ); ENDDEBUG - if( dst->siso_family != AF_ISO ) - return EINVAL; - if( dst->siso_addr.isoa_afi != AFI_RFC986 ) - return EINVAL; - - s = splnet(); - - /* Nsel tells what type of multicast address, if multicast */ - switch( dst->siso_addr.rfc986_dsp[RFC986_NSEL_OFFSET]) { + if( dst->siso_family != AF_ISO ) { + einval: + error = EINVAL; + goto flush; + } + if ((morig->m_flags & M_PKTHDR) == 0) { + printf("eon: got non headered packet\n"); + goto einval; + } + eoa = (struct sockaddr_eon *)dst; + if (LEGIT_EONADDR(eoa)) { + class = eoa->seon_protoid; + dstipaddrloc = (caddr_t)&(eoa->seon_ipaddr); + } else if (eoa->seon_afi == AFI_SNA) { + dstipaddrloc = (caddr_t)&(dst->siso_data[1]); + if (dst->siso_nlen == 6) { + class = dst->siso_data[5]; + } else if (dst->siso_nlen == 7) { + if (bcmp(dstipaddrloc, all_is.sc_snpa, 6)) + class = EON_MULTICAST_ES; + else if (bcmp(dstipaddrloc, all_es.sc_snpa, 6)) + class = EON_MULTICAST_IS; + else + goto einval; + } else + goto einval; + } else if (0 == iso_snparesolve(ifp, dst, edst, &snpalen)) { + dstipaddrloc = (caddr_t)edst; + class = edst[4]; + } else { + error = EINVAL; + goto flush; + } + switch (class) { case EON_NORMAL_ADDR: IncStat(es_out_normal); - dstipaddrloc = (caddr_t)&(dst->siso_addr.rfc986_dsp[1]); single = 1; break; case EON_BROADCAST: IncStat(es_out_broad); - if( eon_LINK_hdr.link == (struct qhdr *)0 ) { + if(eon_LINK_hdr.link == eon_LINK_hdr.rlink) { error = EADDRNOTAVAIL; } else { qoffset = _offsetof( struct eon_centry, eonc_q_LINK); @@ -558,7 +602,7 @@ eonoutput(ifp, morig, dst) break; case EON_MULTICAST_ES: IncStat(es_out_multi_es); - if( eon_ES_hdr.link == (struct qhdr *)0 ) { + if (eon_ES_hdr.link == eon_ES_hdr.rlink) { error = EADDRNOTAVAIL; } else { qoffset = _offsetof( struct eon_centry, eonc_q_ES); @@ -568,7 +612,7 @@ eonoutput(ifp, morig, dst) break; case EON_MULTICAST_IS: IncStat(es_out_multi_is); - if( eon_IS_hdr.link == (struct qhdr *)0 ) { + if (eon_IS_hdr.link == eon_IS_hdr.rlink) { error = EADDRNOTAVAIL; } else { qoffset = _offsetof( struct eon_centry, eonc_q_LINK); @@ -577,8 +621,8 @@ eonoutput(ifp, morig, dst) } break; default: - printf("NSEL bad value; treated as EON_NORMAL_ADDR\n"); - dst->siso_addr.rfc986_dsp[RFC986_NSEL_OFFSET] = EON_NORMAL_ADDR; + printf("bad class value; treated as EON_NORMAL_ADDR\n"); + class = EON_NORMAL_ADDR; single = 1; break; } @@ -586,25 +630,23 @@ eonoutput(ifp, morig, dst) goto done; /* get data length -- needed later */ - datalen = m_datalen( morig ); + datalen = morig->m_pkthdr.len; IFDEBUG(D_EON) printf("eonoutput : m_datalen returns %d\n", datalen); ENDDEBUG - mh = m_getclr( M_DONTWAIT, MT_HEADER); - if(mh == (struct mbuf *)0) { + MGETHDR(mh, M_DONTWAIT, MT_HEADER); + if(mh == (struct mbuf *)0) goto done; - } /* put an eon_hdr in the buffer, prepended by an ip header */ - mh->m_act = (struct mbuf *)0; mh->m_len = sizeof(struct eon_hdr); - mh->m_off = MMAXOFF - sizeof(struct eon_hdr); + MH_ALIGN(mh, sizeof(struct eon_hdr)); mh->m_next = morig; eonhdr = mtod(mh, struct eon_hdr *); - eonhdr->eonh_class = - dst->siso_addr.rfc986_dsp[RFC986_NSEL_OFFSET]; + eonhdr->eonh_class = class; eonhdr->eonh_vers = EON_VERSION; + eonhdr->eonh_csum = 0; IFDEBUG(D_EON) printf("eonoutput : gen csum (0x%x, offset %d, datalen %d)\n", @@ -613,20 +655,19 @@ eonoutput(ifp, morig, dst) iso_gen_csum(mh, _offsetof(struct eon_hdr, eonh_csum), sizeof(struct eon_hdr)); - mh->m_len += sizeof(struct ip); - mh->m_off -= sizeof(struct ip); + mh->m_data -= sizeof(*iphdr); + mh->m_len += sizeof(*iphdr); iphdr = mtod(mh, struct ip *); + bzero((caddr_t)iphdr, sizeof (*iphdr)); iphdr->ip_p = IPPROTO_EON; - iphdr->ip_len = (sizeof(struct eon_hdr) + sizeof(struct ip) + datalen); + iphdr->ip_len = (u_short)(mh->m_pkthdr.len = EONIPLEN + datalen); iphdr->ip_ttl = MAXTTL; iphdr->ip_src.s_addr = INADDR_ANY; IFDEBUG(D_EON) printf("eonoutput : after gen csum: ip_len %d/0x%x\n", - (sizeof(struct eon_hdr) + sizeof(struct ip) + datalen), - (sizeof(struct eon_hdr) + sizeof(struct ip) + datalen) - ); + mh->m_pkthdr.len, mh->m_pkthdr.len); ENDDEBUG morig = mh; @@ -639,8 +680,11 @@ eonoutput(ifp, morig, dst) printf("eonoutput : m_copy (0x%x, 0, 0x%x)\n", morig, iphdr->ip_len); ENDDEBUG - mh = m_copy(morig, 0, iphdr->ip_len); - mh = m_pullup(mh, sizeof(struct ip)); + if (((mh = m_copy(morig, 0, morig->m_pkthdr.len)) == 0) || + ((mh = m_pullup(mh, sizeof(struct ip))) == 0)) { + error = ENOBUFS; + goto done; + } iphdr = mtod(mh, struct ip *); } IFDEBUG(D_EON) @@ -649,9 +693,8 @@ eonoutput(ifp, morig, dst) (caddr_t)&(iphdr->ip_dst.s_addr), sizeof(iphdr->ip_dst.s_addr)); ENDDEBUG - bcopy( - dstipaddrloc, - (caddr_t)&(iphdr->ip_dst.s_addr), sizeof(iphdr->ip_dst.s_addr)); + bcopy(dstipaddrloc, (caddr_t)&(iphdr->ip_dst.s_addr), + sizeof(iphdr->ip_dst.s_addr)); IFDEBUG(D_EON) printf("eonoutput : dst ip addr : %d.%d.%d.%d", (iphdr->ip_dst.s_addr>>24)&0xff, @@ -697,57 +740,63 @@ done: IFDEBUG(D_EON) printf("eonoutput : freeing morig 0x%x\n", morig); ENDDEBUG +flush: m_freem(morig); } - splx(s); return error; } -eoninput(m, ifp) +eoninput(m, iphlen) register struct mbuf *m; - struct ifnet *ifp; /* real ifp */ + int iphlen; { - int s; register struct eon_hdr *eonhdr; register struct ip *iphdr; struct ifnet *eonifp; - register int datalen; - - s = splnet(); + int s; eonifp = &eonif[0]; /* kludge - really want to give CLNP * the ifp for eon, not for the real device */ IFDEBUG(D_EON) - printf("eoninput() 0x%x m_off 0x%x m_len 0x%x dequeued\n", - m, m?m->m_off:0, m?m->m_len:0); + printf("eoninput() 0x%x m_data 0x%x m_len 0x%x dequeued\n", + m, m?m->m_data:0, m?m->m_len:0); ENDDEBUG - if (m == 0) { - goto drop; - } - m = m_pullup(m, (sizeof(struct eon_hdr)+sizeof(struct ip))); - if (m == 0) { - IncStat(es_badhdr); - goto drop; + if (m == 0) + return; + if (iphlen > sizeof (struct ip)) + ip_stripoptions(m, (struct mbuf *)0); + if (m->m_len < EONIPLEN) { + if ((m = m_pullup(m, EONIPLEN)) == 0) { + IncStat(es_badhdr); +drop: + IFDEBUG(D_EON) + printf("eoninput: DROP \n" ); + ENDDEBUG + eonifp->if_ierrors ++; + m_freem(m); + return; + } } - iphdr = mtod(m, struct ip *); - /* do a few checks for debugging */ if( iphdr->ip_p != IPPROTO_EON ) { IncStat(es_badhdr); goto drop; } - - /* drop ip header from the mbuf */ - m->m_len -= sizeof(struct ip); - m->m_off += sizeof(struct ip); - + /* temporarily drop ip header from the mbuf */ + m->m_data += sizeof(struct ip); eonhdr = mtod(m, struct eon_hdr *); - + if( iso_check_csum( m, sizeof(struct eon_hdr) ) != EOK ) { + IncStat(es_badcsum); + goto drop; + } + m->m_data -= sizeof(struct ip); + IFDEBUG(D_EON) + printf("eoninput csum ok class 0x%x\n", eonhdr->eonh_class ); printf("eoninput: eon header:\n"); dump_buf(eonhdr, sizeof(struct eon_hdr)); ENDDEBUG @@ -757,94 +806,54 @@ eoninput(m, ifp) IncStat(es_badhdr); goto drop; } - - datalen = m_datalen( m ); - if( iso_check_csum( m, sizeof(struct eon_hdr) ) != EOK ) { - IncStat(es_badcsum); - goto drop; - } - - IFDEBUG(D_EON) - printf("eoninput csum ok class 0x%x\n", eonhdr->eonh_class ); - ENDDEBUG + m->m_flags &= ~(M_BCAST|M_MCAST); switch( eonhdr->eonh_class) { case EON_BROADCAST: IncStat(es_in_broad); + m->m_flags |= M_BCAST; break; case EON_NORMAL_ADDR: IncStat(es_in_normal); break; case EON_MULTICAST_ES: - if( ( eonifp->if_flags & IFF_ES) == 0 ) - goto drop; IncStat(es_in_multi_es); + m->m_flags |= M_MCAST; break; case EON_MULTICAST_IS: - if( ( eonifp->if_flags & IFF_IS) == 0 ) - goto drop; IncStat(es_in_multi_is); + m->m_flags |= M_MCAST; break; } eonifp->if_ipackets ++; - /* drop eonhdr from the mbuf */ - m->m_len -= sizeof(struct eon_hdr); - m->m_off += sizeof(struct eon_hdr); - { /* put it on the CLNP queue and set soft interrupt */ struct ifqueue *ifq; extern struct ifqueue clnlintrq; - int len; - - /* when acting as a subnet service, have to prepend a - * pointer to the ifnet before handing this to clnp (GAG) - */ - len = sizeof(struct snpa_hdr); - if( ( m->m_off > MMINOFF + len) && - ( m->m_off <= MMAXOFF )) { - m->m_off -= len; - m->m_len += len; - } - ( mtod(m, struct snpa_hdr *) )->snh_ifp = eonifp; /* KLUDGE */ - - /* this is cutting it close */ - bcopy( &iphdr->ip_src, ( mtod(m, struct snpa_hdr *))->snh_shost, - sizeof(struct in_addr)); - bcopy( &iphdr->ip_dst, ( mtod(m, struct snpa_hdr *))->snh_dhost, - sizeof(struct in_addr)); + m->m_pkthdr.rcvif = eonifp; /* KLUDGE */ IFDEBUG(D_EON) printf("eoninput to clnl IFQ\n"); ENDDEBUG ifq = &clnlintrq; - splimp(); + s = splimp(); if (IF_QFULL(ifq)) { IF_DROP(ifq); m_freem(m); - splx(s); eonifp->if_ierrors ++; + splx(s); return; } IF_ENQUEUE(ifq, m); IFDEBUG(D_EON) printf( - "0x%x enqueued on clnp Q: m_len 0x%x m_type 0x%x m_off 0x%x\n", - m, m->m_len, m->m_type, m->m_off); + "0x%x enqueued on clnp Q: m_len 0x%x m_type 0x%x m_data 0x%x\n", + m, m->m_len, m->m_type, m->m_data); dump_buf(mtod(m, caddr_t), m->m_len); ENDDEBUG - schednetisr(NETISR_CLNP); + schednetisr(NETISR_ISO); + splx(s); } -done: - splx(s); - return 0; -drop: - IFDEBUG(D_EON) - printf("eoninput: DROP \n" ); - ENDDEBUG - eonifp->if_ierrors ++; - m_freem(m); - goto done; } int @@ -866,8 +875,8 @@ eonctlinput(cmd, sin) IncStat(es_icmp[cmd]); switch (cmd) { - case PRC_QUENCH2: case PRC_QUENCH: + case PRC_QUENCH2: /* TODO: set the dec bit */ break; case PRC_TIMXCEED_REASS: @@ -897,4 +906,4 @@ eonctlinput(cmd, sin) return 0; } -#endif NEON>0 +#endif diff --git a/usr/src/sys/netiso/if_lpb.c b/usr/src/sys/netiso/if_lpb.c index a34917d9a8..2347671a7c 100644 --- a/usr/src/sys/netiso/if_lpb.c +++ b/usr/src/sys/netiso/if_lpb.c @@ -54,8 +54,8 @@ static char *rcsid = "$Header: if_lpb.c,v 4.2 88/06/29 14:59:38 hagens Exp $"; #include "../machineio/ioccvar.h" #include "ecn.h" -#include "../netiso/iso.h" -#include "../netiso/argo_debug.h" +#include "iso.h" +#include "argo_debug.h" #include "../caif/eicon.h" #include "iso_errno.h" diff --git a/usr/src/sys/netiso/iso.c b/usr/src/sys/netiso/iso.c index 9ffb7dde2b..38ea738cd1 100644 --- a/usr/src/sys/netiso/iso.c +++ b/usr/src/sys/netiso/iso.c @@ -27,6 +27,7 @@ SOFTWARE. /* * $Header: iso.c,v 4.11 88/09/19 14:58:35 root Exp $ * $Source: /usr/argo/sys/netiso/RCS/iso.c,v $ + * @(#)iso.c 7.2 (Berkeley) %G% * * iso.c: miscellaneous routines to support the iso address family */ @@ -36,31 +37,32 @@ static char *rcsid = "$Header: iso.c,v 4.11 88/09/19 14:58:35 root Exp $"; #endif -#include "../h/types.h" -#include "../h/param.h" -#include "../h/ioctl.h" -#include "../h/mbuf.h" -#include "../h/domain.h" -#include "../h/protosw.h" -#include "../h/socket.h" -#include "../h/socketvar.h" -#include "../h/uio.h" -#include "../h/dir.h" -#include "../h/user.h" -#include "../h/errno.h" +#include "types.h" +#include "param.h" +#include "ioctl.h" +#include "mbuf.h" +#include "domain.h" +#include "protosw.h" +#include "socket.h" +#include "socketvar.h" +#include "uio.h" +#include "dir.h" +#include "user.h" +#include "errno.h" #include "../net/if.h" #include "../net/route.h" #include "../net/af.h" -#include "../netiso/iso.h" -#include "../netiso/iso_var.h" -#include "../netiso/iso_snpac.h" -#include "../netiso/iso_pcb.h" -#include "../netiso/clnp.h" -#include "../netiso/argo_debug.h" +#include "iso.h" +#include "iso_var.h" +#include "iso_snpac.h" +#include "iso_pcb.h" +#include "clnp.h" +#include "argo_debug.h" #ifdef ISO +#include "argoxtwentyfive.h" int iso_interfaces = 0; /* number of external interfaces */ extern struct ifnet loif; /* loopback interface */ @@ -74,15 +76,22 @@ extern struct ifnet loif; /* loopback interface */ * RETURNS: nothing * * SIDE EFFECTS: 1) zeros the maptab table. + * 2) initializes the routing table. * * NOTES: */ +struct radix_node_head *iso_rnhead; iso_init() { - extern struct maptab iso_snpac[]; - extern int iso_snpac_size; - - bzero((caddr_t)iso_snpac, iso_snpac_size * sizeof(struct snpa_cache)); + extern struct spna_cache iso_snpac[]; + extern u_int iso_snpac_size; + static iso_init_done; + + if (iso_init_done == 0) { + iso_init_done++; + bzero((caddr_t)iso_snpac, iso_snpac_size * sizeof(struct snpa_cache)); + rn_inithead(&iso_rnhead, 40, AF_ISO); + } } /* @@ -97,17 +106,17 @@ iso_init() * NOTES: */ iso_addrmatch1(isoaa, isoab) -struct iso_addr *isoaa, *isoab; /* addresses to check */ +register struct iso_addr *isoaa, *isoab; /* addresses to check */ { - int compare_len; + u_int compare_len; IFDEBUG(D_ROUTE) printf("iso_addrmatch1: comparing lengths: %d to %d\n", isoaa->isoa_len, isoab->isoa_len); printf("a:\n"); - dump_buf((caddr_t)isoaa, isoaa->isoa_len); + dump_buf(isoaa->isoa_genaddr, isoaa->isoa_len); printf("b:\n"); - dump_buf((caddr_t)isoab, isoab->isoa_len); + dump_buf(isoab->isoa_genaddr, isoab->isoa_len); ENDDEBUG if ((compare_len = isoaa->isoa_len) != isoab->isoa_len) { @@ -117,6 +126,7 @@ struct iso_addr *isoaa, *isoab; /* addresses to check */ return 0; } +#ifdef notdef /* TODO : generalize this to all afis with masks */ if( isoaa->isoa_afi == AFI_37 ) { /* must not compare 2 least significant digits, or for @@ -124,13 +134,14 @@ struct iso_addr *isoaa, *isoab; /* addresses to check */ */ compare_len = ADDR37_IDI_LEN - 1; } +#endif IFDEBUG(D_ROUTE) int i; char *a, *b; - a = (char *) isoaa; - b = (char *) isoab; + a = isoaa->isoa_genaddr; + b = isoab->isoa_genaddr; for (i=0; i", a[i]&0xff, b[i]&0xff); @@ -143,7 +154,7 @@ struct iso_addr *isoaa, *isoab; /* addresses to check */ printf("addrs are equal\n"); return (1); ENDDEBUG - return (!bcmp((caddr_t)isoaa, (caddr_t)isoab, compare_len)); + return (!bcmp(isoaa->isoa_genaddr, isoab->isoa_genaddr, compare_len)); } /* @@ -162,7 +173,7 @@ struct sockaddr_iso *sisoa, *sisob; /* addresses to check */ { return(iso_addrmatch1(&sisoa->siso_addr, &sisob->siso_addr)); } - +#ifdef notdef /* * FUNCTION: iso_netmatch * @@ -195,6 +206,7 @@ struct sockaddr_iso *sisoa, *sisob; return ((lena == lenb) && (!bcmp(bufa, bufb, lena))); } +#endif notdef /* * FUNCTION: iso_hashchar @@ -248,7 +260,7 @@ register int len; /* length of buffer */ return(h); } - +#ifdef notdef /* * FUNCTION: iso_hash * @@ -286,7 +298,6 @@ struct afhash *hp; /* RETURN: hash info here */ hp->afh_hosthash); ENDDEBUG } - /* * FUNCTION: iso_netof * @@ -392,130 +403,233 @@ caddr_t buf; /* RESULT: network portion of address here */ ENDDEBUG return len; } - +#endif notdef /* - * The following is a kludge until I figure something out. Since AFISO - * allows >1 addr/ifp, SIOCGIFADDR can possibly return more than one - * address. Rather than changing the ifreq structure, I have set up - * the ioctl so it will return the address in sequential calls. When - * all addresses have been read, EADDRNOTAVAIL will be returned. - * - * A call to delete or set an addr will cause a subsequent get to - * retrieve the first addr, even if the first had already been read. - * - * The static pointer iso_ia keeps track of which addrs have been read. - */ -static struct iso_ifaddr *iso_iap = NULL; - -/* - * FUNCTION: iso_control - * - * PURPOSE: Generic iso control operations (ioctl's). - * Ifp is 0 if this is not an interface-specific ioctl. - * - * RETURNS: unix error code - * - * SIDE EFFECTS: - * - * NOTES: The iso address family will allow more than one - * iso address per interface as long as they are different - * iso address types. The three types currently supported - * are rfc986, t37, and osinet. + * Generic iso control operations (ioctl's). + * Ifp is 0 if not an interface-specific ioctl. */ +/* ARGSUSED */ iso_control(so, cmd, data, ifp) -struct socket *so; /* socket ioctl arrived on */ -int cmd; /* ioctl to perform */ -caddr_t data; /* data for the ioctl */ -struct ifnet *ifp; /* optional interface ptr */ + struct socket *so; + int cmd; + caddr_t data; + register struct ifnet *ifp; { - register struct ifreq *ifr = (struct ifreq *)data; - register struct iso_ifaddr *ia = 0; - struct ifaddr *ifa; - struct mbuf *m; + register struct iso_ifreq *ifr = (struct iso_ifreq *)data; + register struct iso_ifaddr *ia = 0; + register struct ifaddr *ifa; + struct iso_ifaddr *oia; + struct iso_aliasreq *ifra = (struct iso_aliasreq *)data; + int error, hostIsNew, maskIsNew; + /* + * Find address for this interface, if it exists. + */ + if (ifp) + for (ia = iso_ifaddr; ia; ia = ia->ia_next) + if (ia->ia_ifp == ifp) + break; switch (cmd) { - case SIOCSIFADDR: + + case SIOCAIFADDR_ISO: + case SIOCDIFADDR_ISO: + if (ifra->ifra_addr.siso_family == AF_ISO) + for (oia = ia; ia; ia = ia->ia_next) { + if (ia->ia_ifp == ifp && + SAME_ISOADDR(&ia->ia_addr, &ifra->ifra_addr)) + break; + } if (!suser()) return (u.u_error); - if (ifp == 0) - panic("iso_control: SIOCSIFADDR"); + panic("iso_control"); + if (ia == (struct iso_ifaddr *)0) { + struct iso_ifaddr *nia; + if (cmd == SIOCDIFADDR_ISO) + return (EADDRNOTAVAIL); + MALLOC(nia, struct iso_ifaddr *, sizeof(*nia), + M_IFADDR, M_WAITOK); + if (nia == (struct iso_ifaddr *)0) + return (ENOBUFS); + bzero((caddr_t)nia, sizeof(*nia)); + if (ia = iso_ifaddr) { + for ( ; ia->ia_next; ia = ia->ia_next) + ; + ia->ia_next = nia; + } else + iso_ifaddr = nia; + ia = nia; + if (ifa = ifp->if_addrlist) { + for ( ; ifa->ifa_next; ifa = ifa->ifa_next) + ; + ifa->ifa_next = (struct ifaddr *) ia; + } else + ifp->if_addrlist = (struct ifaddr *) ia; + ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr; + ia->ia_ifa.ifa_dstaddr + = (struct sockaddr *)&ia->ia_dstaddr; + ia->ia_ifa.ifa_netmask + = (struct sockaddr *)&ia->ia_sockmask; + ia->ia_ifp = ifp; + if (ifp != &loif) + iso_interfaces++; + } + break; - /* - * Check if a iso address of same type exists for ifp - * If it does, then return an error. - */ - for (ia = iso_ifaddr; ia; ia = ia->ia_next) { - if (ia->ia_ifp == ifp) { - struct sockaddr_iso *siso; +#define cmdbyte(x) (((x) >> 8) & 0xff) + default: + if (cmdbyte(cmd) == 'a') + return (snpac_ioctl(cmd, data)); + if (ia == (struct iso_ifaddr *)0) + return (EADDRNOTAVAIL); + break; + } + switch (cmd) { - siso = (struct sockaddr_iso *)&ifr->ifr_addr; - if (iso_eqtype(&IA_SIS(ia)->siso_addr, &siso->siso_addr)) - return(EADDRNOTAVAIL); - } + case SIOCGIFADDR_ISO: + ifr->ifr_Addr = ia->ia_addr; + break; + + case SIOCGIFDSTADDR_ISO: + if ((ifp->if_flags & IFF_POINTOPOINT) == 0) + return (EINVAL); + ifr->ifr_Addr = ia->ia_dstaddr; + break; + + case SIOCGIFNETMASK_ISO: + ifr->ifr_Addr = ia->ia_sockmask; + break; + + case SIOCAIFADDR_ISO: + maskIsNew = 0; hostIsNew = 1; error = u.u_error; + if (ia->ia_addr.siso_family == AF_ISO) { + if (ifra->ifra_addr.siso_len == 0) { + ifra->ifra_addr = ia->ia_addr; + hostIsNew = 0; + } else if (SAME_ISOADDR(&ia->ia_addr, &ifra->ifra_addr)) + hostIsNew = 0; + } + if (ifra->ifra_mask.siso_len) { + iso_ifscrub(ifp, ia); + ia->ia_sockmask = ifra->ifra_mask; + maskIsNew = 1; + } + if ((ifp->if_flags & IFF_POINTOPOINT) && + (ifra->ifra_dstaddr.siso_family == AF_ISO)) { + iso_ifscrub(ifp, ia); + ia->ia_dstaddr = ifra->ifra_dstaddr; + maskIsNew = 1; /* We lie; but the effect's the same */ } + if (ifra->ifra_addr.siso_family == AF_ISO && + (hostIsNew || maskIsNew)) { + error = iso_ifinit(ifp, ia, &ifra->ifra_addr, 0); + } + if (ifra->ifra_snpaoffset) + ia->ia_snpaoffset = ifra->ifra_snpaoffset; + return (error); - /* - * Go ahead and create new ifaddr - * - * Link addr into list of iso addresses - */ - m = m_getclr(M_WAIT, MT_IFADDR); - if (m == (struct mbuf *)NULL) - return (ENOBUFS); - if (ia = iso_ifaddr) { - for ( ; ia->ia_next; ia = ia->ia_next) - ; - ia->ia_next = mtod(m, struct iso_ifaddr *); - } else - iso_ifaddr = mtod(m, struct iso_ifaddr *); - iso_iap = iso_ifaddr; - - /* - * Link addr into list on interface - */ - ia = mtod(m, struct iso_ifaddr *); - if (ifa = ifp->if_addrlist) { - for ( ; ifa->ifa_next; ifa = ifa->ifa_next) - ; - ifa->ifa_next = (struct ifaddr *) ia; - } else - ifp->if_addrlist = (struct ifaddr *) ia; - - ia->ia_ifp = ifp; - IA_SIS(ia)->siso_family = AF_ISO; - if (ifp != &loif) - iso_interfaces++; - return (iso_ifinit(ifp, ia, &ifr->ifr_addr)); - - case SIOCGIFADDR: - for (ia = iso_iap; ia; ia = ia->ia_next) { - if (ia->ia_ifp == ifp) { - ifr->ifr_addr = ia->ia_addr; - iso_iap = ia->ia_next; - return (0); + case SIOCDIFADDR_ISO: + iso_ifscrub(ifp, ia); + if ((ifa = ifp->if_addrlist) == (struct ifaddr *)ia) + ifp->if_addrlist = ifa->ifa_next; + else { + while (ifa->ifa_next && + (ifa->ifa_next != (struct ifaddr *)ia)) + ifa = ifa->ifa_next; + if (ifa->ifa_next) + ifa->ifa_next = ((struct ifaddr *)ia)->ifa_next; + else + printf("Couldn't unlink isoifaddr from ifp\n"); + } + oia = ia; + if (oia == (ia = iso_ifaddr)) { + iso_ifaddr = ia->ia_next; + } else { + while (ia->ia_next && (ia->ia_next != oia)) { + ia = ia->ia_next; } + if (ia->ia_next) + ia->ia_next = oia->ia_next; + else + printf("Didn't unlink isoifadr from list\n"); } - iso_iap = iso_ifaddr; - return(EADDRNOTAVAIL); - - case SIOCDIFADDR: /* TODO: what about this ioctl on other families */ - if (!suser()) - return (u.u_error); - iso_iap = iso_ifaddr; - - if (ifp == 0) - panic("iso_control: SIOCDIFADDR"); - - return (iso_ifdelete(ifp, &ifr->ifr_addr)); + free((caddr_t)oia, M_IFADDR); + break; default: if (ifp == 0 || ifp->if_ioctl == 0) return (EOPNOTSUPP); return ((*ifp->if_ioctl)(ifp, cmd, data)); } + return (0); +} + +/* + * Delete any existing route for an interface. + */ +iso_ifscrub(ifp, ia) + register struct ifnet *ifp; + register struct iso_ifaddr *ia; +{ + if ((ia->ia_flags & IFA_ROUTE) == 0) + return; + if (ifp->if_flags & IFF_LOOPBACK) + rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST); + else if (ifp->if_flags & IFF_POINTOPOINT) + rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST); + else { + rtinit(&(ia->ia_ifa), (int)RTM_DELETE, 0); + } + ia->ia_flags &= ~IFA_ROUTE; +} + +/* + * Initialize an interface's internet address + * and routing table entry. + */ +iso_ifinit(ifp, ia, siso, scrub) + register struct ifnet *ifp; + register struct iso_ifaddr *ia; + struct sockaddr_iso *siso; +{ + struct sockaddr_iso oldaddr; + int s = splimp(), error; + + oldaddr = ia->ia_addr; + ia->ia_addr = *siso; + /* + * Give the interface a chance to initialize + * if this is its first address, + * and to validate the address if necessary. + */ + if (ifp->if_ioctl && (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, ia))) { + splx(s); + ia->ia_addr = oldaddr; + return (error); + } + if (scrub) { + ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr; + iso_ifscrub(ifp, ia); + ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr; + } + /* + * Add route for the network. + */ + if (ifp->if_flags & IFF_LOOPBACK) { + ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr; + rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP); + } else if (ifp->if_flags & IFF_POINTOPOINT && + ia->ia_dstaddr.siso_family == AF_ISO) + rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP); + else { + rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_UP); + } + ia->ia_flags |= IFA_ROUTE; + splx(s); + return (0); } +#ifdef notdef struct ifaddr * iso_ifwithidi(addr) @@ -539,13 +653,13 @@ iso_ifwithidi(addr) for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) { IFDEBUG(D_ROUTE) printf("iso_ifwithidi address "); - dump_isoaddr( (struct sockaddr_iso *)(&ifa->ifa_addr)); + dump_isoaddr( (struct sockaddr_iso *)(ifa->ifa_addr)); ENDDEBUG - if (ifa->ifa_addr.sa_family != addr->sa_family) + if (ifa->ifa_addr->sa_family != addr->sa_family) continue; #define IFA_SIS(ifa)\ - ((struct sockaddr_iso *)&((ifa)->ifa_addr)) + ((struct sockaddr_iso *)((ifa)->ifa_addr)) IFDEBUG(D_ROUTE) printf(" af same, args to iso_eqtype:\n"); @@ -569,162 +683,7 @@ iso_ifwithidi(addr) return ((struct ifaddr *)0); } -/* - * FUNCTION: iso_ifinit - * - * PURPOSE: Initialize an interface's iso address and - * routing table entry. - * - * RETURNS: unix error code - * - * SIDE EFFECTS: - * - * NOTES: - */ -iso_ifinit(ifp, ia, siso) -register struct ifnet *ifp; /* interface to initialize */ -register struct iso_ifaddr *ia; /* addr on ifnet list */ -struct sockaddr_iso *siso; /* address to use */ -{ - struct sockaddr oldaddr; - struct sockaddr_iso netaddr; - int s = splimp(), error; - - /* - * Make sure the address make sense - */ - if (!iso_ck_addr(&siso->siso_addr)) - return(EINVAL); - IFDEBUG(D_ROUTE) - int i; - char *ptr; - - ptr = (char *) siso; - printf("The size of sockaddr_iso is %d\n", - sizeof(struct sockaddr_iso)); - for(i=0; i< sizeof(struct sockaddr_iso); i++) { - printf("sockaddr[%d] = 0x%x\n", i, *ptr++ & 0xff); - } - ENDDEBUG - - oldaddr = ia->ia_addr; - ia->ia_addr = *(struct sockaddr *)siso; - bzero((caddr_t)&netaddr, sizeof (netaddr)); - netaddr.siso_family = AF_ISO; - - /* - * Give the interface a chance to initialize - */ - if (ifp->if_ioctl && (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, ia))) { - splx(s); - ia->ia_addr = oldaddr; - return (error); - } - splx(s); - - /* - * Add route for the network. - */ - if (ifp->if_flags & IFF_LOOPBACK) - rtinit(&ia->ia_addr, &ia->ia_addr, (int)SIOCADDRT, RTF_HOST|RTF_UP); - else { - int len; - - len = iso_netof(&siso->siso_addr, (caddr_t)&netaddr.siso_addr); - netaddr.siso_addr.isoa_len = len; - rtinit((struct sockaddr *)&netaddr, &ia->ia_addr, - (int)SIOCADDRT, RTF_UP); - } - ia->ia_flags |= IFA_ROUTE; - return (0); -} - - -/* - * FUNCTION: iso_ifdelete - * - * PURPOSE: Delete an iso address from an interface. - * - * RETURNS: 0 or unix error code - * - * SIDE EFFECTS: - * - * NOTES: - */ -iso_ifdelete(ifp, siso) -struct ifnet *ifp; /* interface to delete addr from */ -struct sockaddr_iso *siso; /* address to delete */ -{ - struct iso_addr *isoa = &siso->siso_addr; - register struct iso_ifaddr *ia, *prev = 0; - register struct ifaddr *ifa; - int s; - struct sockaddr_iso netaddr; - - /* - * Find the iso address of same type as specified and delete it. - */ - for (ia = iso_ifaddr; ia; prev = ia, ia = ia->ia_next) { - if (ia->ia_ifp == ifp) { - if (iso_eqtype(&IA_SIS(ia)->siso_addr, isoa)) { - /* - * Delete any previous route for the address. - */ - IFDEBUG(D_IOCTL) - printf("iso_ifdelete: delete %s\n", clnp_iso_addrp(isoa)) - ENDDEBUG - s = splimp(); - bzero((caddr_t)&netaddr, sizeof (netaddr)); - netaddr.siso_family = AF_ISO; - if (ia->ia_flags & IFA_ROUTE) { - if (ifp->if_flags & IFF_LOOPBACK) - rtinit(&ia->ia_addr, &ia->ia_addr, (int)SIOCDELRT, - RTF_HOST); - else { - (void) iso_netof(&siso->siso_addr, - (caddr_t)&netaddr.siso_addr); - rtinit((struct sockaddr *)&netaddr, &ia->ia_addr, - (int)SIOCDELRT, 0); - } - ia->ia_flags &= ~IFA_ROUTE; - } - splx(s); - - /* - * Remove from list of iso addresses - */ - if (prev == 0) - iso_ifaddr = ia->ia_next; - else - prev->ia_next = ia->ia_next; - if (ifp != &loif) - iso_interfaces--; - - /* - * Remove from list of addrs on ifnet structure - */ - if ((ifa = ifp->if_addrlist) == (struct ifaddr *)ia) - ifp->if_addrlist = ia->ia_ifa.ifa_next; - else { - for (; ifa; ifa = ifa->ifa_next) { - if (ifa->ifa_next == (struct ifaddr *)ia) { - ifa->ifa_next = ia->ia_ifa.ifa_next; - break; - } - } - } - - /* - * Free the iso_ifaddr mbuf - */ - m_free(dtom(ia)); - return (0); - } - } - } - return(EADDRNOTAVAIL); -} - +#endif notdef /* * FUNCTION: iso_ck_addr * @@ -743,7 +702,7 @@ struct iso_addr *isoa; /* address to check */ } - +#ifdef notdef /* * FUNCTION: iso_eqtype * @@ -773,12 +732,12 @@ struct iso_addr *isoab; /* other addr to check */ } return(0); } - +#endif notdef /* - * FUNCTION: iso_iaonnetof() + * FUNCTION: iso_localifa() * - * PURPOSE: Find and interface addresss based on the network - * portion of an address. + * PURPOSE: Find an interface addresss having a given destination + * or at least matching the net. * * RETURNS: ptr to an interface address * @@ -787,15 +746,44 @@ struct iso_addr *isoab; /* other addr to check */ * NOTES: */ struct iso_ifaddr * -iso_iaonnetof(siso) - struct sockaddr_iso *siso; +iso_localifa(siso) + register struct sockaddr_iso *siso; { register struct iso_ifaddr *ia; - - for (ia = iso_ifaddr; ia; ia = ia->ia_next) - if (iso_netmatch( (struct sockaddr_iso *)(&ia->ia_ifa.ifa_addr), siso) ) - return (ia); - return ((struct iso_ifaddr *)0); + register char *cp1, *cp2, *cp3; + register struct ifnet *ifp; + struct iso_ifaddr *ia_maybe = 0; + /* + * We make one pass looking for both net matches and an exact + * dst addr. + */ + for (ia = iso_ifaddr; ia; ia = ia->ia_next) { + if ((ifp = ia->ia_ifp) == 0 || ((ifp->if_flags & IFF_UP) == 0)) + continue; + if (ifp->if_flags & IFF_POINTOPOINT) { + if ((ia->ia_dstaddr.siso_family == AF_ISO) && + SAME_ISOADDR(&ia->ia_dstaddr, siso)) + return (ia); + else + if (SAME_ISOADDR(&ia->ia_addr, siso)) + ia_maybe = ia; + continue; + } + if (ia->ia_sockmask.siso_len) { + char *cplim = ia->ia_sockmask.siso_len + (char *)&ia->ia_sockmask; + cp1 = ia->ia_sockmask.siso_data; + cp2 = siso->siso_data; + cp3 = ia->ia_addr.siso_data; + while (cp2 < cplim) + if (*cp1++ & (*cp2++ ^ *cp3++)) + goto next; + ia_maybe = ia; + } + if (SAME_ISOADDR(&ia->ia_addr, siso)) + return ia; + next:; + } + return ia_maybe; } #ifdef NARGOXTWENTYFIVE > 0 @@ -858,7 +846,7 @@ struct mbuf *m; /* data for set, buffer for get */ printf("iso_nlctloutput: setting x25 crud\n"); ENDDEBUG - bcopy(data, (caddr_t)&isop->isop_x25crud, data_len); + bcopy(data, (caddr_t)isop->isop_x25crud, (unsigned)data_len); isop->isop_x25crud_len = data_len; break; #endif NARGOXTWENTYFIVE > 0 @@ -881,37 +869,37 @@ struct mbuf *m; /* data for set, buffer for get */ * * NOTES: */ -struct ifnet * -iso_routeifp(dst) +struct iso_ifaddr * +iso_routeifa(dst) struct sockaddr *dst; /* destination to route to */ { - struct route ro; - struct ifnet *ifp = NULL; + struct rtentry *rt; + struct ifaddr *ifa = 0; + struct ifnet *ifp = 0; - ro.ro_dst = *dst; - ro.ro_rt = NULL; IFDEBUG(D_ROUTE) printf("iso_routeifp: dst:"); - dump_isoaddr(dst); + dump_isoaddr((struct sockaddr_iso *)dst); ENDDEBUG - rtalloc(&ro); + rt = rtalloc1(dst, 0); - if (ro.ro_rt) { - ifp = ro.ro_rt->rt_ifp; - RTFREE(ro.ro_rt); + if (rt) { + ifa = rt->rt_ifa; + ifp = rt->rt_ifp; + RTFREE(rt); } IFDEBUG(D_ROUTE) - printf("iso_routeifp: ifp x%x", ifp); + printf("iso_routeifp: ifa x%x", ifa); if (ifp) printf(" (%s%d)\n", ifp->if_name, ifp->if_unit); else printf("\n"); ENDDEBUG - return(ifp); + return((struct iso_ifaddr *)ifa); } #endif ISO @@ -928,24 +916,12 @@ struct sockaddr *dst; /* destination to route to */ dump_isoaddr(s) struct sockaddr_iso *s; { - caddr_t c = (caddr_t)&(s->siso_addr.isoa_u); + char *clnp_saddr_isop(); register int i; if( s->siso_family == AF_ISO) { - printf("len %d family: 0x%x suffix 0x%x, afi 0x%x,", - (int)s->siso_addr.isoa_len, - (int)s->siso_family, - s->siso_tsuffix, (int)s->siso_addr.isoa_afi); - if( s->siso_addr.isoa_len > sizeof(struct sockaddr) ) - printf("ERROR-ADDR TOO BIG %d\n", s->siso_addr.isoa_len); - else { - if (s->siso_addr.isoa_len != 0) { - /* -2 because we already skipped the afi */ - for (i=0; isiso_addr.isoa_len-2; i++) - printf("0x%x.", *(c+i)&0xff); - printf("0x%x\n", *(c+i)&0xff); - } - } + printf("ISO address: suffixlen %d, %s\n", + s->siso_tsuffixlen, clnp_saddr_isop(s)); } else if( s->siso_family == AF_INET) { /* hack */ struct sockaddr_in *sin = (struct sockaddr_in *)s; diff --git a/usr/src/sys/netiso/iso.h b/usr/src/sys/netiso/iso.h index f209e4d8ea..ec870c6f54 100644 --- a/usr/src/sys/netiso/iso.h +++ b/usr/src/sys/netiso/iso.h @@ -26,6 +26,7 @@ SOFTWARE. */ /* $Header: iso.h,v 4.9 88/09/11 18:06:38 hagens Exp $ */ /* $Source: /usr/argo/sys/netiso/RCS/iso.h,v $ */ +/* @(#)iso.h 7.2 (Berkeley) %G% */ #ifndef __ISO__ #define __ISO__ @@ -106,6 +107,7 @@ SOFTWARE. * This means that you can't have multihoming in the x.25 environment. * Makes loopback a bear. */ +#define BIGSOCKADDRS #ifdef BIGSOCKADDRS #define ADDR37_IDI_LEN 7 /* 14 bcd digits == 7 octets */ #define ADDR37_DSP_LEN 9 @@ -228,7 +230,7 @@ struct addr_sn { * Type 47 is the biggest address: 11 bytes. The length of iso_addr * is 13 bytes. */ -struct iso_addr { +struct old_iso_addr { u_char isoa_afi; /* authority and format id */ union { struct addr_37 addr_37; /* type 37 */ @@ -239,6 +241,13 @@ struct iso_addr { u_char isoa_len; /* length (in bytes) */ }; +/* The following looks like a sockaddr + * in case we decide to use tree routines */ +struct iso_addr { + u_char isoa_len; /* length (in bytes) */ + char isoa_genaddr[20]; /* general opaque address */ +}; + #define t37_idi isoa_u.addr_37.a37_idi #define t37_dsp isoa_u.addr_37.a37_dsp #define osinet_idi isoa_u.addr_osinet.aosi_idi @@ -256,11 +265,22 @@ struct iso_addr { * t37 and osinet addresses so that they were only 10 bytes long */ struct sockaddr_iso { - u_short siso_family; /* family */ - u_short siso_tsuffix; /* transport suffix */ + u_char siso_len; /* length */ + u_char siso_family; /* family */ + u_char siso_ssuffixlen; /* session suffix len */ + u_char siso_tsuffixlen; /* transport suffix len */ +/* u_char siso_nsaptype; /* someday?? */ struct iso_addr siso_addr; /* network address */ + u_char siso_pad[3]; /* make multiple of sizeof long */ }; +#define siso_data siso_addr.isoa_genaddr +#define siso_nlen siso_addr.isoa_len +#define TSEL(s) ((caddr_t)((s)->siso_data + (s)->siso_nlen)) + +#define SAME_ISOADDR(a, b) \ + (bcmp((a)->siso_data, (b)->siso_data, (unsigned)(a)->siso_nlen)==0) + #define NSAPTYPE_UNKNOWN -1 #define NSAPTYPE_INET 0 #define NSAPTYPE_X121BCD 1 @@ -288,3 +308,4 @@ struct hostent *iso_gethostbyname(), *iso_gethostbyaddr(); #endif KERNEL #endif __ISO__ +#define _offsetof(t, m) ((int)((caddr_t)&((t *)0)->m)) diff --git a/usr/src/sys/netiso/iso_chksum.c b/usr/src/sys/netiso/iso_chksum.c index a8a2a58e83..5668f93590 100644 --- a/usr/src/sys/netiso/iso_chksum.c +++ b/usr/src/sys/netiso/iso_chksum.c @@ -47,13 +47,15 @@ SOFTWARE. * logically adjacent, but may be physically located in separate mbufs. */ +#ifdef ISO #ifndef lint static char *rcsid = "$Header: iso_chksum.c,v 4.7 88/07/29 15:31:26 nhall Exp $"; #endif -#include "../netiso/argo_debug.h" -#include "../h/param.h" -#include "../h/mbuf.h" +#include "argo_debug.h" +#include "param.h" +#include "mbuf.h" +#endif ISO #ifndef MNULL #define MNULL (struct mbuf *)0 @@ -108,8 +110,8 @@ iso_check_csum(m, len) printf("iso_check_csum: new mbuf\n"); if(l-i < m->m_len) printf( - "bad mbuf chain in check csum l 0x%x i 0x%x m_off 0x%x", - l,i,m->m_off); + "bad mbuf chain in check csum l 0x%x i 0x%x m_data 0x%x", + l,i,m->m_data); ENDDEBUG ASSERT( m != MNULL); len = MIN( m->m_len, l-i); @@ -151,11 +153,7 @@ iso_gen_csum(m,n,l) int n; /* offset of 2 checksum bytes */ int l; { -#ifdef lint - register u_char *p = (u_char *)((int)m + m->m_off); -#else register u_char *p = mtod(m, u_char *); -#endif register int c0=0, c1=0; register int i=0; int loc = n++, len=0; /* n is position, loc is offset */ @@ -177,21 +175,21 @@ iso_gen_csum(m,n,l) if(loc>=0) { if (loc < len) { - xloc = ((u_char *)((int)(m) + (m)->m_off + loc)); + xloc = loc + mtod(m, u_char *); IFDEBUG(D_CHKSUM) printf("1: zeroing xloc 0x%x loc 0x%x\n",xloc, loc ); ENDDEBUG *xloc = (u_char)0; if (loc+1 < len) { /* both xloc and yloc are in same mbuf */ - yloc = ((u_char *)((int)(m) + (m)->m_off + loc + 1)); + yloc = 1 + xloc; IFDEBUG(D_CHKSUM) printf("2: zeroing yloc 0x%x loc 0x%x\n",yloc, loc ); ENDDEBUG *yloc = (u_char)0; } else { /* crosses boundary of mbufs */ - yloc = ((u_char *)((int)(m->m_next) + (m->m_next)->m_off)); + yloc = mtod(m->m_next, u_char *); IFDEBUG(D_CHKSUM) printf("3: zeroing yloc 0x%x \n",yloc ); ENDDEBUG @@ -304,28 +302,29 @@ m_compress(in, out) while (in) { IFDEBUG(D_REQUEST) printf("m_compress in 0x%x *out 0x%x\n", in, *out); - printf("m_compress in: len 0x%x, off 0x%x\n", in->m_len, in->m_off); + printf("m_compress in: len 0x%x, off 0x%x\n", in->m_len, in->m_data); printf("m_compress *out: len 0x%x, off 0x%x\n", (*out)->m_len, - (*out)->m_off); + (*out)->m_data); ENDDEBUG - if ( in->m_off >= MMAXOFF) { + if (in->m_flags & M_EXT) { ASSERT(in->m_len == 0); } if ( in->m_len == 0) { in = in->m_next; continue; } - if ((*out)->m_off < MMAXOFF) { + if (((*out)->m_flags & M_EXT) == 0) { int len; - len = MMAXOFF - ((*out)->m_off + (*out)->m_len); + len = M_TRAILINGSPACE(*out); len = MIN(len, in->m_len); datalen += len; IFDEBUG(D_REQUEST) printf("m_compress copying len %d\n", len); ENDDEBUG - bcopy(mtod(in, caddr_t), mtod((*out), caddr_t) + (*out)->m_len, len); + bcopy(mtod(in, caddr_t), mtod((*out), caddr_t) + (*out)->m_len, + (unsigned)len); (*out)->m_len += len; in->m_len -= len; diff --git a/usr/src/sys/netiso/iso_pcb.c b/usr/src/sys/netiso/iso_pcb.c index 51deb61992..b95dee98f6 100644 --- a/usr/src/sys/netiso/iso_pcb.c +++ b/usr/src/sys/netiso/iso_pcb.c @@ -41,16 +41,16 @@ static char *rcsid = "$Header: iso_pcb.c,v 4.5 88/06/29 14:59:56 hagens Exp $"; #include "dir.h" #include "user.h" #include "mbuf.h" -#include "../h/socket.h" -#include "../h/socketvar.h" -#include "../netiso/argo_debug.h" -#include "../netiso/iso.h" -#include "../netiso/clnp.h" +#include "socket.h" +#include "socketvar.h" +#include "argo_debug.h" +#include "iso.h" +#include "clnp.h" #include "../netinet/in_systm.h" #include "../net/if.h" #include "../net/route.h" -#include "../netiso/iso_pcb.h" -#include "../netiso/iso_var.h" +#include "iso_pcb.h" +#include "iso_var.h" #include "protosw.h" #define PCBNULL (struct isopcb *)0 @@ -73,16 +73,15 @@ iso_pcballoc(so, head) struct socket *so; struct isopcb *head; { - struct mbuf *m; register struct isopcb *isop; IFDEBUG(D_ISO) printf("iso_pcballoc(so 0x%x)\n", so); ENDDEBUG - m = m_getclr(M_DONTWAIT, MT_PCB); - if (m == NULL) + MALLOC(isop, struct isopcb *, sizeof(*isop), M_PCB, M_NOWAIT); + if (isop == NULL) return ENOBUFS; - isop = mtod(m, struct isopcb *); + bzero((caddr_t)isop, sizeof(*isop)); isop->isop_head = head; isop->isop_socket = so; insque(isop, head); @@ -107,6 +106,7 @@ iso_pcballoc(so, head) * * NOTES: */ +#define satosiso(sa) ((struct sockaddr_iso *)(sa)) int iso_pcbbind(isop, nam) register struct isopcb *isop; @@ -114,18 +114,28 @@ iso_pcbbind(isop, nam) { register struct isopcb *head = isop->isop_head; register struct sockaddr_iso *siso; - struct ifaddr *ia; - u_short suf = 0; + struct iso_ifaddr *ia; + union { + char data[2]; + u_short s; + } suf; IFDEBUG(D_ISO) printf("iso_pcbbind(isop 0x%x, nam 0x%x)\n", isop, nam); ENDDEBUG + suf.s = 0; if (iso_ifaddr == 0) /* any interfaces attached? */ return EADDRNOTAVAIL; - if (isop->isop_lport) /* already bound */ + if (isop->isop_laddr) /* already bound */ return EADDRINUSE; - if(nam == (struct mbuf *)0) + if(nam == (struct mbuf *)0) { + isop->isop_laddr = &isop->isop_sladdr; + isop->isop_sladdr.siso_tsuffixlen = 2; + isop->isop_sladdr.siso_nlen = 0; + isop->isop_sladdr.siso_family = AF_ISO; + isop->isop_sladdr.siso_len = sizeof(struct sockaddr_iso); goto noname; + } siso = mtod(nam, struct sockaddr_iso *); IFDEBUG(D_ISO) printf("iso_pcbbind(name len 0x%x)\n", nam->m_len); @@ -140,57 +150,61 @@ iso_pcbbind(isop, nam) * However, in fact the size of the whole thing is a struct * sockaddr_iso, so probably this is what we should check for. */ - if( (nam->m_len < 2) || (nam->m_len > sizeof(struct sockaddr_iso))) { + if( (nam->m_len < 2) || (nam->m_len < siso->siso_len)) { return ENAMETOOLONG; } - suf = siso->siso_tsuffix; - - if (bcmp(&siso->siso_addr,&zeroiso_addr, 1)) { + if (siso->siso_tsuffixlen) { + register char *cp = TSEL(siso); + suf.data[0] = cp[0]; + suf.data[1] = cp[1]; + } + if (siso->siso_nlen) { /* non-zero net addr- better match one of our interfaces */ IFDEBUG(D_ISO) printf("iso_pcbbind: bind to NOT zeroisoaddr\n"); ENDDEBUG - siso->siso_tsuffix = 0; /* yech... */ - /* PHASE 2: this call is ok */ - if ((ia = ifa_ifwithaddr((struct sockaddr *)siso)) - == (struct ifaddr *)0) + for (ia = iso_ifaddr; ia; ia = ia->ia_next) + if (SAME_ISOADDR(siso, &ia->ia_addr)) + break; + if (ia == 0) return EADDRNOTAVAIL; - /* copy to the inpcb */ - bcopy( (caddr_t)&((struct sockaddr_iso *)&(ia->ifa_addr))->siso_addr, - (caddr_t)&(isop->isop_laddr.siso_addr), - sizeof(struct sockaddr_iso) ); - isop->isop_laddr.siso_tsuffix = suf; - /* copy also to the nam parameter */ - bcopy( (caddr_t)&(isop->isop_laddr.siso_addr), - (caddr_t)&(siso->siso_addr), sizeof(struct sockaddr_iso)); - siso->siso_tsuffix = suf; } - if (suf) { - if((suf < ISO_PORT_RESERVED) && (u.u_uid != 0)) + if (siso->siso_len <= sizeof (isop->isop_sladdr)) { + isop->isop_laddr = &isop->isop_sladdr; + } else { + if ((nam = m_copy(nam, 0, (int)M_COPYALL)) == 0) + return ENOBUFS; + isop->isop_laddr = mtod(nam, struct sockaddr_iso *); + } + bcopy((caddr_t)siso, (caddr_t)isop->isop_laddr, siso->siso_len); + if (suf.s) { + if((suf.s < ISO_PORT_RESERVED) && (siso->siso_tsuffixlen <= 2) && + (u.u_uid != 0)) return EACCES; if ((isop->isop_socket->so_options & SO_REUSEADDR) == 0 && - iso_pcblookup(head, 0, &(isop->isop_laddr.siso_addr), suf, 0) ) + iso_pcblookup(head, 0, (caddr_t)0, isop->isop_laddr)) return EADDRINUSE; - } - /* copy the if addr to the result (siso) and to the isopcb */ + } else { + register char *cp; noname: + cp = TSEL(isop->isop_laddr); IFDEBUG(D_ISO) printf("iso_pcbbind noname\n"); ENDDEBUG - if (suf == 0) do { if (head->isop_lport++ < ISO_PORT_RESERVED || head->isop_lport > ISO_PORT_USERRESERVED) head->isop_lport = ISO_PORT_RESERVED; - suf = head->isop_lport; - } while (iso_pcblookup(head, 0, &(isop->isop_laddr.siso_addr), suf, 0)); - isop->isop_lport = suf; + suf.s = head->isop_lport; + cp[0] = suf.data[0]; + cp[1] = suf.data[1]; + } while (iso_pcblookup(head, 0, (caddr_t)0, isop->isop_laddr)); + } IFDEBUG(D_ISO) printf("iso_pcbbind returns 0, suf 0x%x\n", suf); ENDDEBUG return 0; } - /* * FUNCTION: iso_pcbconnect * @@ -212,182 +226,118 @@ noname: * * NOTES: */ -#define satosiso(sa) ((struct sockaddr_iso *)(sa)) - int iso_pcbconnect(isop, nam) - struct isopcb *isop; + register struct isopcb *isop; struct mbuf *nam; { - struct ifnet *ifp = (struct ifnet *)0; - struct sockaddr_iso ifaddr; register struct sockaddr_iso *siso = mtod(nam, struct sockaddr_iso *); - int local_zero = 0; + int local_zero, error = 0; + struct iso_ifaddr *ia; IFDEBUG(D_ISO) - printf( - "iso_pcbconnect(isop 0x%x sock 0x%x nam 0x%x nam->m_len 0x%x), addr:\n", - isop, isop->isop_socket, nam, nam->m_len); + printf("iso_pcbconnect(isop 0x%x sock 0x%x nam 0x%x", + isop, isop->isop_socket, nam); + printf("nam->m_len 0x%x), addr:\n", nam->m_len); dump_isoaddr(siso); ENDDEBUG - if (nam->m_len > sizeof (*siso)) - return ENAMETOOLONG; /* not great but better than EINVAL! */ + if (nam->m_len < siso->siso_len) + return EINVAL; if (siso->siso_family != AF_ISO) return EAFNOSUPPORT; -#ifdef notdef - /* removed for the sake of extended tsels - - * user may setsockopt for extended tsel (foreign) and then - * connect to nsap w/ tsuffix zero + /* + * Local zero means either not bound, or bound to a TSEL, but no + * particular local interface. So, if we want to send somebody + * we need to choose a return address. */ - if (siso->siso_tsuffix == 0) - return EADDRNOTAVAIL; - local_zero = iso_addrmatch1(&(isop->isop_laddr.siso_addr), &zeroiso_addr); -#endif notdef - local_zero = !bcmp(&(isop->isop_laddr.siso_addr), &zeroiso_addr, 1); - -#ifdef PHASEONE + local_zero = + ((isop->isop_laddr == 0) || (isop->isop_laddr->siso_nlen == 0)); if (local_zero) { - /* - * We need to get the local nsap address. - * First, route to the destination. This will provide us with - * an ifp. Second, determine which local address linked on - * that ifp is appropriate - */ - struct sockaddr_iso *first_hop; /* filled by clnp_route */ - struct ifnet *ifp; /* filled by clnp_route */ - int err; - struct iso_addr *localaddr; - - if (err = clnp_route(&siso->siso_addr, &isop->isop_route, /* flags */0, - &first_hop, &ifp)) - return(err); - - /* determine local address based upon ifp */ - if ((localaddr = clnp_srcaddr(ifp, &first_hop->siso_addr)) == NULL) - return(ENETUNREACH); - - ifaddr.siso_family = AF_ISO; - ifaddr.siso_addr = *localaddr; - - if (isop->isop_lport == 0) - (void)iso_pcbbind(isop, (struct mbuf *)0); - isop->isop_laddr = ifaddr; - } -#else - if (local_zero) { - struct iso_ifaddr *ia; - register struct route *ro; + int flags; IFDEBUG(D_ISO) printf("iso_pcbconnect localzero 1\n"); ENDDEBUG - ia = (struct iso_ifaddr *)0; /* * If route is known or can be allocated now, * our src addr is taken from the i/f, else punt. */ - ro = &isop->isop_route; - IFDEBUG(D_ISO) - printf("iso_pcbconnect rtalloc 1.1, ro->ro_rt 0x%x\n", - ro->ro_rt); - ENDDEBUG - if (ro->ro_rt && ! iso_addrmatch1( &(satosiso(&ro->ro_dst)->siso_addr), - &siso->siso_addr)) { - RTFREE(ro->ro_rt); - ro->ro_rt = (struct rtentry *)0; - } - /* - * TODO: it seems this code has a lot in common with clnp_route. - * Maybe they could be combined? (RAH) - */ - if ((isop->isop_socket->so_options & SO_DONTROUTE) == 0 && /*XXX*/ - (ro->ro_rt == (struct rtentry *)0 || - (ifp = ro->ro_rt->rt_ifp) == (struct ifnet *)0)) { - /* No route yet, so try to acquire one */ - ro->ro_dst.sa_family = AF_ISO; - ((struct sockaddr_iso *) &ro->ro_dst)->siso_addr = - siso->siso_addr; - rtalloc(ro); - IFDEBUG(D_ISO) - printf("iso_pcbconnect rtalloc 1.5, ro->ro_rt 0x%x\n", - ro->ro_rt); - if (ro->ro_rt != NULL) { - printf("ro->ro_rt->rt_refcnt %d\n", - ro->ro_rt->rt_refcnt); - printf("rt entry rt_gateway (as sockaddr):\n"); - dump_buf(&ro->ro_rt->rt_gateway, - sizeof (struct sockaddr)); - } - ENDDEBUG - /* - * If we found a route, use the address - * corresponding to the outgoing interface - * unless it is the loopback (in case a route - * to our address on another net goes to loopback). - * - * We must check to use the address that is of the - * same type (in the case where the interface has more - * than one type associated with it). (ie ecn0 has - * both t37 and osinet addresses. - */ - if (ro->ro_rt && (ifp = ro->ro_rt->rt_ifp) && - (ifp->if_flags & IFF_LOOPBACK) == 0) - for (ia = iso_ifaddr; ia; ia = ia->ia_next) { - struct iso_addr *isoap = &IA_SIS(ia)->siso_addr; - - IFDEBUG(D_ISO) - printf("iso_pcbconnect: ia x%x yields: %s\n", - ia, clnp_iso_addrp(isoap)); - ENDDEBUG - - if ((ia->ia_ifp == ifp) && - (iso_eqtype(&siso->siso_addr, isoap))) - break; - } - } + flags = isop->isop_socket->so_options & SO_DONTROUTE; + if (error = clnp_route(&siso->siso_addr, &isop->isop_route, flags, + (struct sockaddr **)0, &ia)) + return error; IFDEBUG(D_ISO) - printf("iso_pcbconnect localzero 2: ia x%x\n", ia); + printf("iso_pcbconnect localzero 2, ro->ro_rt 0x%x", + isop->isop_route.ro_rt); + printf(" ia 0x%x\n", ia); ENDDEBUG - if (ia == 0) { - ia = (struct iso_ifaddr *) - ifa_ifwithdstaddr((struct sockaddr *)siso); - if (ia == 0) - ia = iso_iaonnetof(siso); - if (ia == 0) - return EADDRNOTAVAIL; - } - ifaddr = *(struct sockaddr_iso *)&ia->ia_addr; } IFDEBUG(D_ISO) printf("in iso_pcbconnect before lookup isop 0x%x isop->sock 0x%x\n", isop, isop->isop_socket); ENDDEBUG if (local_zero) { - if (isop->isop_lport == 0) + int nlen, tlen, totlen; caddr_t oldtsel, newtsel; + siso = isop->isop_laddr; + if (siso == 0 || siso->siso_tsuffixlen == 0) (void)iso_pcbbind(isop, (struct mbuf *)0); - isop->isop_laddr.siso_addr = ifaddr.siso_addr; - isop->isop_laddr.siso_family = AF_ISO; + /* + * Here we have problem of squezeing in a definite network address + * into an existing sockaddr_iso, which in fact may not have room + * for it. This gets messy. + */ + siso = isop->isop_laddr; + oldtsel = TSEL(siso); + tlen = siso->siso_tsuffixlen; + nlen = ia->ia_addr.siso_nlen; + totlen = tlen + nlen + _offsetof(struct sockaddr_iso, siso_data[0]); + if ((siso == &isop->isop_sladdr) && + (totlen > sizeof(isop->isop_sladdr))) { + struct mbuf *m = m_get(MT_SONAME, M_DONTWAIT); + if (m == 0) + return ENOBUFS; + m->m_len = totlen; + isop->isop_laddr = siso = mtod(m, struct sockaddr_iso *); + } + siso->siso_nlen = ia->ia_addr.siso_nlen; + newtsel = TSEL(siso); + ovbcopy(oldtsel, newtsel, tlen); + bcopy(ia->ia_addr.siso_data, siso->siso_data, nlen); + siso->siso_tsuffixlen = tlen; + siso->siso_family = AF_ISO; + siso->siso_len = totlen; + siso = mtod(nam, struct sockaddr_iso *); } -#endif PHASEONE IFDEBUG(D_ISO) printf("in iso_pcbconnect before bcopy isop 0x%x isop->sock 0x%x\n", isop, isop->isop_socket); ENDDEBUG - bcopy((caddr_t) &(siso->siso_addr), (caddr_t) &(isop->isop_faddr.siso_addr), - sizeof(struct iso_addr)); + /* + * If we had to allocate space to a previous big foreign address, + * and for some reason we didn't free it, we reuse it knowing + * that is going to be big enough, as sockaddrs are delivered in + * 128 byte mbufs. + * If the foreign address is small enough, we use default space; + * otherwise, we grab an mbuf to copy into. + */ + if (isop->isop_faddr == 0 || isop->isop_faddr == &isop->isop_sfaddr) { + if (siso->siso_len <= sizeof(isop->isop_sfaddr)) + isop->isop_faddr = &isop->isop_sfaddr; + else { + struct mbuf *m = m_get(MT_SONAME, M_DONTWAIT); + if (m == 0) + return ENOBUFS; + isop->isop_faddr = mtod(m, struct sockaddr_iso *); + } + } + bcopy((caddr_t)siso, (caddr_t)isop->isop_faddr, siso->siso_len); IFDEBUG(D_ISO) printf("in iso_pcbconnect after bcopy isop 0x%x isop->sock 0x%x\n", isop, isop->isop_socket); - ENDDEBUG - isop->isop_faddr.siso_family = AF_ISO; - isop->isop_fport = siso->siso_tsuffix; - IFDEBUG(D_ISO) - printf("in iso_pcbconnect end isop 0x%x isop->sock 0x%x\n", - isop, isop->isop_socket); printf("iso_pcbconnect connected to addr:\n"); - dump_isoaddr(&isop->isop_faddr); + dump_isoaddr(isop->isop_faddr); printf("iso_pcbconnect end: src addr:\n"); - dump_isoaddr(&isop->isop_laddr); + dump_isoaddr(isop->isop_laddr); ENDDEBUG return 0; } @@ -415,8 +365,14 @@ iso_pcbdisconnect(isop) IFDEBUG(D_ISO) printf("iso_pcbdisconnect(isop 0x%x)\n", isop); ENDDEBUG - isop->isop_laddr.siso_addr = zeroiso_addr; - isop->isop_fport = 0; + /* + * Preserver binding infnormation if already bound. + */ + if (isop->isop_laddr && isop->isop_laddr->siso_nlen) + isop->isop_laddr->siso_nlen = 0; + if (isop->isop_faddr && isop->isop_faddr != &isop->isop_sfaddr) + m_freem(dtom(isop->isop_faddr)); + isop->isop_faddr = 0; if (isop->isop_socket->so_state & SS_NOFDREF) iso_pcbdetach(isop); } @@ -483,7 +439,9 @@ iso_pcbdetach(isop) IFDEBUG(D_ISO) printf("iso_pcbdetach 5 \n"); ENDDEBUG - (void) m_free(dtom(isop)); + if (isop->isop_laddr && (isop->isop_laddr != &isop->isop_sladdr)) + m_freem(dtom(isop->isop_laddr)); + free((caddr_t)isop, M_IFADDR); } #ifdef notdef @@ -546,14 +504,14 @@ iso_pcbnotify(head, dst, errno, notify) printf("iso_pcbnotify(head 0x%x, notify 0x%x) dst:\n", head, notify); ENDDEBUG for (isop = head->isop_next; isop != head;) { - if (!iso_addrmatch1(&(isop->isop_faddr.siso_addr), dst) || + if (!iso_addrmatch1(&(isop->isop_faddr->siso_addr), dst) || isop->isop_socket == 0) { IFDEBUG(D_ISO) printf("iso_pcbnotify: CONTINUE isop 0x%x, sock 0x%x\n" , isop, isop->isop_socket); printf("addrmatch cmp'd with (0x%x):\n", - &(isop->isop_faddr.siso_addr)); - dump_isoaddr(&isop->isop_faddr); + &(isop->isop_faddr->siso_addr)); + dump_isoaddr(isop->isop_faddr); ENDDEBUG isop = isop->isop_next; continue; @@ -587,37 +545,40 @@ iso_pcbnotify(head, dst, errno, notify) * NOTES: */ struct isopcb * -iso_pcblookup(head, fport, laddr, lport, flags) +iso_pcblookup(head, fportlen, fport, laddr) struct isopcb *head; - struct iso_addr *laddr; - u_short fport, lport; - int flags; + register struct sockaddr_iso *laddr; + caddr_t fport; + int fportlen; { register struct isopcb *isop; + register caddr_t lp = TSEL(laddr); + unsigned int llen = laddr->siso_tsuffixlen; IFDEBUG(D_ISO) - printf("iso_pcblookup(head 0x%x lport 0x%x fport 0x%x)\n", - head, lport, fport); + printf("iso_pcblookup(head 0x%x laddr 0x%x fport 0x%x)\n", + head, laddr, fport); ENDDEBUG for (isop = head->isop_next; isop != head; isop = isop->isop_next) { -#ifdef notdef - /* - * This should be changed to do bcmp on lsuffix in the tpcb instead - * since we should be ignoring the lport concept. - */ -#endif notdef - if (isop->isop_lport != lport) + if (isop->isop_laddr == 0 || isop->isop_laddr == laddr) + continue; + if (isop->isop_laddr->siso_tsuffixlen != llen) continue; - if (isop->isop_fport != fport) + if (bcmp(lp, TSEL(isop->isop_laddr), llen)) + continue; + if (fportlen && isop->isop_faddr && + bcmp(fport, TSEL(isop->isop_faddr), (unsigned)fportlen)) continue; /* PHASE2 * addrmatch1 should be iso_addrmatch(a, b, mask) * where mask is taken from isop->isop_laddrmask (new field) * isop_lnetmask will also be available in isop - */ if (laddr != &zeroiso_addr && !iso_addrmatch1(laddr, &(isop->isop_laddr.siso_addr))) continue; + */ + if (laddr->siso_nlen && (!SAME_ISOADDR(laddr, isop->isop_laddr))) + continue; return (isop); } return (struct isopcb *)0; diff --git a/usr/src/sys/netiso/iso_pcb.h b/usr/src/sys/netiso/iso_pcb.h index 0fc3a49bfc..9248263c54 100644 --- a/usr/src/sys/netiso/iso_pcb.h +++ b/usr/src/sys/netiso/iso_pcb.h @@ -37,24 +37,42 @@ struct isopcb { struct isopcb *isop_head; /* pointer back to chain of pcbs for this protocol */ struct socket *isop_socket; /* back pointer to socket */ - struct sockaddr_iso isop_laddr; -#define isop_lport isop_laddr.siso_tsuffix -#define isop_lportlen isop_laddr.siso_tsuffixlen - struct sockaddr_iso isop_faddr; -#define isop_fport isop_faddr.siso_tsuffix -#define isop_fportlen isop_faddr.siso_tsuffixlen - struct route isop_route; /* CLNP routing entry */ + struct sockaddr_iso *isop_laddr; + struct sockaddr_iso *isop_faddr; +#define isop_lportlen isop_laddr->siso_tsuffixlen +#define isop_fportlen isop_faddr->siso_tsuffixlen + struct route_iso { + struct rtentry *ro_rt; + struct sockaddr_iso ro_dst; + } isop_route; /* CLNP routing entry */ struct mbuf *isop_options; /* CLNP options */ struct mbuf *isop_optindex; /* CLNP options index */ struct mbuf *isop_clnpcache; /* CLNP cached hdr */ u_int isop_chanmask; /* which ones used - max 32 supported */ u_int isop_negchanmask; /* which ones used - max 32 supported */ + u_short isop_lport; /* MISLEADLING work var */ int isop_x25crud_len; /* x25 call request ud */ char isop_x25crud[MAXX25CRUDLEN]; - struct ifnet *isop_ifp; /* ESIS interface assoc w/sock */ + struct ifaddr *isop_ifa; /* ESIS interface assoc w/sock */ + struct sockaddr_iso isop_sladdr, /* preallocated laddr */ + isop_sfaddr; /* preallocated faddr */ }; -#define sotoisopcb(so) ((struct isopcb *)(so)->so_npcb) +#ifdef sotorawcb +/* + * Common structure pcb for raw clnp protocol access. + * Here are clnp specific extensions to the raw control block, + * and space is allocated to the necessary sockaddrs. + */ +struct rawisopcb { + struct rawcb risop_rcb; /* common control block prefix */ + int risop_flags; /* flags, e.g. raw sockopts */ + struct isopcb risop_isop; /* space for bound addresses, routes etc.*/ +}; +#endif + +#define sotoisopcb(so) ((struct isopcb *)(so)->so_pcb) +#define sotorawisopcb(so) ((struct rawisopcb *)(so)->so_pcb) #ifdef KERNEL struct isopcb *iso_pcblookup(); diff --git a/usr/src/sys/netiso/iso_proto.c b/usr/src/sys/netiso/iso_proto.c index b78d1818b1..6cc9c5604e 100644 --- a/usr/src/sys/netiso/iso_proto.c +++ b/usr/src/sys/netiso/iso_proto.c @@ -38,14 +38,14 @@ static char *rcsid = "$Header: iso_proto.c,v 4.4 88/09/08 08:38:42 hagens Exp $" #endif #ifdef ISO -#include "../h/types.h" -#include "../h/param.h" -#include "../h/socket.h" -#include "../h/protosw.h" -#include "../h/domain.h" -#include "../h/mbuf.h" - -#include "../netiso/iso.h" +#include "types.h" +#include "param.h" +#include "socket.h" +#include "protosw.h" +#include "domain.h" +#include "mbuf.h" + +#include "iso.h" int clnp_output(), clnp_init(),clnp_slowtimo(),clnp_drain(); int rclnp_input(), rclnp_output(), rclnp_ctloutput(), raw_usrreq(); diff --git a/usr/src/sys/netiso/iso_snpac.c b/usr/src/sys/netiso/iso_snpac.c index 0a4345ded4..02c71b6f71 100644 --- a/usr/src/sys/netiso/iso_snpac.c +++ b/usr/src/sys/netiso/iso_snpac.c @@ -33,39 +33,52 @@ static char *rcsid = "$Header: iso_snpac.c,v 1.8 88/09/19 13:51:36 hagens Exp $" #ifdef ISO -#include "../h/types.h" -#include "../h/param.h" -#include "../h/mbuf.h" -#include "../h/domain.h" -#include "../h/protosw.h" -#include "../h/socket.h" -#include "../h/socketvar.h" -#include "../h/errno.h" -#include "../h/ioctl.h" -#include "../h/time.h" -#include "../h/kernel.h" +#include "types.h" +#include "param.h" +#include "mbuf.h" +#include "domain.h" +#include "protosw.h" +#include "socket.h" +#include "socketvar.h" +#include "errno.h" +#include "ioctl.h" +#include "time.h" +#include "kernel.h" #include "../net/if.h" #include "../net/route.h" -#include "../netiso/iso.h" -#include "../netiso/iso_var.h" -#include "../netiso/iso_snpac.h" -#include "../netiso/clnp.h" -#include "../netiso/clnp_stat.h" -#include "../netiso/argo_debug.h" -#include "../netiso/esis.h" +#include "iso.h" +#include "iso_var.h" +#include "iso_snpac.h" +#include "clnp.h" +#include "clnp_stat.h" +#include "argo_debug.h" +#include "esis.h" #define SNPAC_BSIZ 20 /* bucket size */ #define SNPAC_NB 13 /* number of buckets */ #define SNPAC_SIZE (SNPAC_BSIZ * SNPAC_NB) struct snpa_cache iso_snpac[SNPAC_SIZE]; -int iso_snpac_size = SNPAC_SIZE;/* for iso_map command */ +u_int iso_snpac_size = SNPAC_SIZE;/* for iso_map command */ int iso_systype = SNPA_ES; /* default to be an ES */ -static struct iso_addr zero_isoa; + +struct sockaddr_iso blank_siso = {sizeof(blank_siso), AF_ISO}; +extern u_long iso_hashchar(); +static struct sockaddr_iso + dst = {sizeof(dst), AF_ISO}, + gte = {sizeof(dst), AF_ISO}, + src = {sizeof(dst), AF_ISO}, + msk = {sizeof(dst), AF_ISO}, + zmk = {1}; +#define zsi blank_siso +#define zero_isoa zsi.siso_addr +#define zap_isoaddr(a, b) (bzero((caddr_t)&a.siso_addr, sizeof(*r)), \ + ((r = b) && bcopy((caddr_t)r, (caddr_t)&a.siso_addr, 1 + (r)->isoa_len))) +#define S(x) ((struct sockaddr *)&(x)) #define SNPAC_HASH(addr) \ - (((u_long) iso_hashchar(addr, addr->isoa_len)) % SNPAC_NB) + (((u_long) iso_hashchar((caddr_t)addr, (int)addr->isoa_len)) % SNPAC_NB) #define SNPAC_LOOK(sc,addr) { \ register n; \ @@ -140,24 +153,23 @@ struct snpa_cache all_is = { * A mechanism is needed to prevent this function from * being invoked if the system is an IS. */ -iso_snparesolve(ifp, dst, snpa, snpa_len) +iso_snparesolve(ifp, dest, snpa, snpa_len) struct ifnet *ifp; /* outgoing interface */ -struct sockaddr_iso *dst; /* destination */ +struct sockaddr_iso *dest; /* destination */ char *snpa; /* RESULT: snpa to be used */ int *snpa_len; /* RESULT: length of snpa */ { extern struct ifnet loif; /* loopback interface */ struct snpa_cache *sc; /* ptr to snpa table entry */ struct iso_addr *destiso; /* destination iso addr */ - int s; - destiso = &dst->siso_addr; + destiso = &dest->siso_addr; /* * This hack allows us to send esis packets that have the destination snpa * addresss embedded in the destination nsap address */ - if (destiso->isoa_afi == AFI_SNA) { + if (destiso->isoa_genaddr[0] == AFI_SNA) { /* * This is a subnetwork address. Return it immediately */ @@ -166,7 +178,8 @@ int *snpa_len; /* RESULT: length of snpa */ ENDDEBUG *snpa_len = destiso->isoa_len - 1; /* subtract size of AFI */ - bcopy((caddr_t) destiso->sna_idi, (caddr_t)snpa, *snpa_len); + bcopy((caddr_t) destiso->isoa_genaddr + 1, (caddr_t)snpa, + (unsigned)*snpa_len); return (0); } @@ -177,7 +190,6 @@ int *snpa_len; /* RESULT: length of snpa */ /* * packet is not for us, check cache for an entry */ - s = splimp(); SNPAC_LOOK(sc, destiso); if (sc == 0) { /* not found */ /* If we are an IS, we can't do much with the packet */ @@ -207,11 +219,9 @@ int *snpa_len; /* RESULT: length of snpa */ bcopy((caddr_t)sc->sc_snpa, (caddr_t)snpa, sc->sc_len); *snpa_len = sc->sc_len; - splx(s); return (0); bad: - splx(s); return(ENETUNREACH); } @@ -251,8 +261,8 @@ struct iso_addr *isoa; /* destination nsap */ * * NOTES: This ought to invoke the 8208 ES-IS function */ -iso_8208snparesolve(dst, snpa, snpa_len) -struct sockaddr_iso *dst; /* destination */ +iso_8208snparesolve(dest, snpa, snpa_len) +struct sockaddr_iso *dest; /* destination */ char *snpa; /* RESULT: snpa to be used */ int *snpa_len; /* RESULT: length of snpa */ { @@ -261,7 +271,7 @@ int *snpa_len; /* RESULT: length of snpa */ int s; int err = 0; - destiso = &dst->siso_addr; + destiso = &dest->siso_addr; s = splimp(); SNPAC_LOOK(sc, destiso); @@ -293,7 +303,7 @@ caddr_t snpa; /* translation */ int snpalen; /* length in bytes */ short ht; /* holding time (in seconds) */ { - snpac_add(ifp, nsap, snpa, snpalen, SNPA_ES, ht); + snpac_add(ifp, nsap, snpa, snpalen, SNPA_ES, (u_short)ht); } /* @@ -368,7 +378,6 @@ struct iso_addr *isoa; /* iso address to enter into table */ snpac_free(maybe); return maybe; } - /* * FUNCTION: snpac_free * @@ -384,20 +393,24 @@ struct iso_addr *isoa; /* iso address to enter into table */ snpac_free(sc) register struct snpa_cache *sc; /* entry to free */ { - int s = splimp(); + register struct rtentry *rt; + register struct iso_addr *r; if (known_is == sc) { - snpac_rtrequest(SIOCDELRT, &zero_isoa, &known_is->sc_nsap, - RTF_DYNAMIC|RTF_GATEWAY); known_is = NULL; } - if (sc->sc_da.isoa_len > 0) { - snpac_rtrequest(SIOCDELRT, &sc->sc_da, &known_is->sc_nsap, - RTF_DYNAMIC|RTF_GATEWAY); + if (sc->sc_rt) { + zap_isoaddr(dst, (&(sc->sc_da))); + rt = rtalloc1((struct sockaddr *)&dst, 0); + if ((sc->sc_rt == rt) && (rt->rt_flags & RTF_UP) + && (rt->rt_flags & (RTF_DYNAMIC | RTF_MODIFIED))) { + RTFREE(rt); + rtrequest(RTM_DELETE, rt_key(rt), rt->rt_gateway, rt_mask(rt), + rt->rt_flags, (struct rtentry **)0); + } + RTFREE(rt); } bzero((caddr_t)sc, sizeof(struct snpa_cache)); - - splx(s); } /* @@ -415,12 +428,11 @@ snpac_add(ifp, nsap, snpa, snpalen, type, ht) struct ifnet *ifp; /* interface info is related to */ struct iso_addr *nsap; /* nsap to add */ caddr_t snpa; /* translation */ -int snpalen; /* length in bytes */ +int snpalen; /* translation length */ char type; /* SNPA_IS or SNPA_ES */ -short ht; /* holding time (in seconds) */ +u_short ht; /* holding time (in seconds) */ { struct snpa_cache *sc; - int s = splimp(); SNPAC_LOOK(sc, nsap); if (sc == NULL) { @@ -431,14 +443,12 @@ short ht; /* holding time (in seconds) */ sc->sc_ht = ht; sc->sc_len = min(snpalen, MAX_SNPALEN); - bcopy(snpa, sc->sc_snpa, sc->sc_len); + bcopy(snpa, (caddr_t)sc->sc_snpa, sc->sc_len); sc->sc_flags = SNPA_VALID | type; sc->sc_ifp = ifp; if (type & SNPA_IS) snpac_logdefis(sc); - - splx(s); } /* @@ -460,9 +470,14 @@ caddr_t data; /* data for the cmd */ register struct snpa_cache *sc; register struct iso_addr *isoa; int s; + char *type; - /* look up this address in table */ - isoa = &rq->sr_isoa; + switch(cmd) { + case SIOCSISOMAP: type = "set"; break; + case SIOCDISOMAP: type = "delete"; break; + case SIOCGISOMAP: type = "get"; break; + default: return(snpac_systype(cmd, data)); + } /* sanity check */ if (rq->sr_len > MAX_SNPALEN) @@ -471,18 +486,14 @@ caddr_t data; /* data for the cmd */ IFDEBUG (D_IOCTL) int i; - printf("snpac_ioctl: "); - switch(cmd) { - case SIOCSISOMAP: printf("set"); break; - case SIOCDISOMAP: printf("delete"); break; - case SIOCGISOMAP: printf("get"); break; - } - printf(" %s to ", clnp_iso_addrp(isoa)); + printf("snpac_ioctl: %s %s to ", type, clnp_iso_addrp(isoa)); for (i=0; isr_len; i++) printf("%x%c", rq->sr_snpa[i], i < (rq->sr_len-1) ? ':' : '\n'); ENDDEBUG - s = splimp(); + /* look up this address in table */ + isoa = &rq->sr_isoa; + SNPAC_LOOK(sc, isoa); if (sc == NULL) { /* not found */ if (cmd != SIOCSISOMAP) @@ -491,8 +502,10 @@ caddr_t data; /* data for the cmd */ switch(cmd) { case SIOCSISOMAP: /* set entry */ - snpac_add(NULL, isoa, rq->sr_snpa, rq->sr_len, - rq->sr_flags & (SNPA_ES|SNPA_IS|SNPA_PERM), rq->sr_ht); + snpac_add((struct ifnet *)NULL, isoa, (caddr_t)rq->sr_snpa, + (int)rq->sr_len, + (char)(rq->sr_flags & (SNPA_ES|SNPA_IS|SNPA_PERM)), + rq->sr_ht); break; case SIOCDISOMAP: /* delete entry */ @@ -500,10 +513,9 @@ caddr_t data; /* data for the cmd */ break; case SIOCGISOMAP: /* get entry */ - bcopy((caddr_t)&sc->sc_sr, rq, sizeof(struct snpa_req)); + bcopy((caddr_t)&sc->sc_sr, (caddr_t)rq, sizeof(struct snpa_req)); break; } - splx(s); return(0); } @@ -521,13 +533,13 @@ caddr_t data; /* data for the cmd */ * * NOTES: */ -iso_tryloopback(m, dst) +iso_tryloopback(m, dest) struct mbuf *m; /* pkt */ -struct sockaddr_iso *dst; /* destination */ +struct sockaddr_iso *dest; /* destination */ { struct iso_addr *destiso; /* destination iso addr */ - destiso = &dst->siso_addr; + destiso = &dest->siso_addr; if (clnp_ours(destiso)) { IFDEBUG(D_SNPA) @@ -537,7 +549,7 @@ struct sockaddr_iso *dst; /* destination */ IFDEBUG(D_SNPA) printf("iso_tryloopback: calling looutput\n"); ENDDEBUG - return (looutput(&loif, m, (struct sockaddr *)dst)); + return (looutput(&loif, m, (struct sockaddr *)dest)); } } return (-1); @@ -605,15 +617,30 @@ caddr_t data; /* data for the cmd */ * NOTES: */ snpac_logdefis(sc) -struct snpa_cache *sc; +register struct snpa_cache *sc; { - if (known_is) { - snpac_rtrequest(SIOCDELRT, &zero_isoa, &known_is->sc_nsap, - RTF_DYNAMIC|RTF_GATEWAY); + register struct iso_addr *r; + register struct rtentry *rt = rtalloc1((struct sockaddr *)&zsi, 0); + if (known_is == 0) + known_is = sc; + if (known_is != sc) { + if (known_is->sc_rt) { + rtfree(known_is->sc_rt); + known_is->sc_rt = 0; + } + known_is = sc; + } + if (rt == 0) { + zap_isoaddr(dst, &(sc->sc_nsap)); + rtrequest(RTM_ADD, S(zsi), S(dst), S(zmk), + RTF_DYNAMIC|RTF_GATEWAY, &sc->sc_rt); + return; + } + if (rt->rt_flags & (RTF_DYNAMIC | RTF_MODIFIED)) { + ((struct sockaddr_iso *)rt->rt_gateway)->siso_addr = sc->sc_nsap; + known_is = sc; + sc->sc_rt = rt; } - known_is = sc; - snpac_rtrequest(SIOCADDRT, &zero_isoa, &sc->sc_nsap, - RTF_DYNAMIC|RTF_GATEWAY); } /* @@ -674,8 +701,10 @@ snpac_ownmulti(snpa, len) char *snpa; int len; { - return (((iso_systype & SNPA_ES) && (!bcmp(snpa, all_es.sc_snpa, len))) - || ((iso_systype & SNPA_IS) && (!bcmp(snpa, all_is.sc_snpa, len)))); + return (((iso_systype & SNPA_ES) && + (!bcmp((caddr_t)snpa, (caddr_t)all_es.sc_snpa, (unsigned)len))) || + ((iso_systype & SNPA_IS) && + (!bcmp((caddr_t)snpa, (caddr_t)all_is.sc_snpa, (unsigned)len)))); } /* @@ -715,38 +744,36 @@ struct ifnet *ifp; * NOTES: In the future, this should make a request of a user * level routing daemon. */ -snpac_rtrequest(req, dst, gateway, flags) +snpac_rtrequest(req, host, gateway, netmask, flags, ret_nrt) int req; -struct iso_addr *dst; +struct iso_addr *host; struct iso_addr *gateway; +struct iso_addr *netmask; short flags; +struct rtentry **ret_nrt; { - struct rtentry rte; - struct iso_addr *isoa; + register struct iso_addr *r; IFDEBUG(D_SNPA) printf("snpac_rtrequest: "); - if (req == SIOCADDRT) + if (req == RTM_ADD) printf("add"); - else if (req == SIOCDELRT) + else if (req == RTM_DELETE) printf("delete"); else printf("unknown command"); - printf(" dst: %s\n", clnp_iso_addrp(dst)); + printf(" dst: %s\n", clnp_iso_addrp(host)); printf("\tgateway: %s\n", clnp_iso_addrp(gateway)); ENDDEBUG - bzero((caddr_t)&rte, sizeof(struct rtentry)); - rte.rt_dst.sa_family = rte.rt_gateway.sa_family = AF_ISO; - isoa = &((struct sockaddr_iso *)&rte.rt_dst)->siso_addr; - *isoa = *dst; - isoa = &((struct sockaddr_iso *)&rte.rt_gateway)->siso_addr; - *isoa = *gateway; - rte.rt_flags = RTF_UP|flags; - rtrequest(req, &rte); -} + zap_isoaddr(dst, host); + zap_isoaddr(gte, gateway); + zap_isoaddr(msk, netmask); + rtrequest(req, S(dst), S(gte), (netmask ? S(msk) : (struct sockaddr *)0), + flags, ret_nrt); +} /* * FUNCTION: snpac_addrt @@ -767,21 +794,24 @@ short flags; * This could be made more efficient by checking * the existing route before adding a new one. */ -snpac_addrt(host, gateway) -struct iso_addr *host; -struct iso_addr *gateway; +snpac_addrt(host, gateway, source, netmask) +struct iso_addr *host, *gateway, *source, *netmask; { - struct snpa_cache *sc; - int s; + register struct snpa_cache *sc; + register struct iso_addr *r; - s = splimp(); SNPAC_LOOK(sc, gateway); if (sc != NULL) { - snpac_rtrequest(SIOCDELRT, &sc->sc_da, gateway, - RTF_DYNAMIC|RTF_GATEWAY); - snpac_rtrequest(SIOCADDRT, host, gateway, RTF_DYNAMIC|RTF_GATEWAY); - bcopy(host, &sc->sc_da, sizeof(struct iso_addr)); + bcopy((caddr_t)host, (caddr_t)&sc->sc_da, sizeof(struct iso_addr)); + zap_isoaddr(dst, host); + zap_isoaddr(gte, gateway); + zap_isoaddr(src, source); + zap_isoaddr(msk, netmask); + if (netmask) { + rtredirect(S(dst), S(gte), S(msk), RTF_DONE, S(src), &sc->sc_rt); + } else + rtredirect(S(dst), S(gte), (struct sockaddr *)0, + RTF_DONE | RTF_HOST, S(src), &sc->sc_rt); } - s = splx(s); } #endif ISO diff --git a/usr/src/sys/netiso/iso_snpac.h b/usr/src/sys/netiso/iso_snpac.h index 5a70d6824c..74389bdaf7 100644 --- a/usr/src/sys/netiso/iso_snpac.h +++ b/usr/src/sys/netiso/iso_snpac.h @@ -32,7 +32,7 @@ struct snpa_req { u_char sr_snpa[MAX_SNPALEN]; /* snpa associated with nsap address */ u_char sr_flags; /* true if entry is valid */ - short sr_ht; /* holding time */ + u_short sr_ht; /* holding time */ }; /* @@ -53,7 +53,8 @@ struct snpa_cache { #define SNPA_PERM 0x10 /* redirects only */ - struct iso_addr sc_da; /* DA from RD */ + struct iso_addr sc_da; /* DA from RD */ + struct rtentry *sc_rt; }; struct systype_req { @@ -62,6 +63,9 @@ struct systype_req { char sr_type; /* SNPA_ES or SNPA_IS */ }; +#define SIOCSSTYPE _IOW('a', 39, struct systype_req) /* set system type */ +#define SIOCGSTYPE _IOW('a', 40, struct systype_req) /* set system type */ + #ifdef KERNEL struct snpa_cache *snpac_look(/* struct iso_addr *isoa */); #endif KERNEL diff --git a/usr/src/sys/netiso/iso_usrreq.c b/usr/src/sys/netiso/iso_usrreq.c index c06c43044f..7be8569c44 100644 --- a/usr/src/sys/netiso/iso_usrreq.c +++ b/usr/src/sys/netiso/iso_usrreq.c @@ -38,22 +38,22 @@ static char *rcsid = "$Header: iso_usrreq.c,v 4.2 88/06/29 15:00:06 hagens Exp $ #ifdef ISO -#include "../h/types.h" -#include "../h/param.h" -#include "../h/mbuf.h" -#include "../h/domain.h" -#include "../h/protosw.h" -#include "../h/socket.h" -#include "../h/socketvar.h" -#include "../h/errno.h" +#include "types.h" +#include "param.h" +#include "mbuf.h" +#include "domain.h" +#include "protosw.h" +#include "socket.h" +#include "socketvar.h" +#include "errno.h" #include "../net/if.h" #include "../net/route.h" -#include "../netiso/iso.h" -#include "../netiso/clnp.h" -#include "../netiso/clnp_stat.h" -#include "../netiso/argo_debug.h" +#include "iso.h" +#include "clnp.h" +#include "clnp_stat.h" +#include "argo_debug.h" /* @@ -69,12 +69,13 @@ static char *rcsid = "$Header: iso_usrreq.c,v 4.2 88/06/29 15:00:06 hagens Exp $ * and PRU_DETACH are noops so socket and close don't return * an error code. */ -iso_usrreq(so, req, m, nam, rights) +iso_usrreq(so, req, m, nam, rights, control) struct socket *so; /* socket: used only to get to this code */ int req; /* request */ struct mbuf *m; /* data for request */ struct mbuf *nam; /* optional name */ struct mbuf *rights; /* optional rights */ +struct mbuf *control; /* optional control info */ { int error; diff --git a/usr/src/sys/netiso/iso_var.h b/usr/src/sys/netiso/iso_var.h index 2d8f022110..90394d1e43 100644 --- a/usr/src/sys/netiso/iso_var.h +++ b/usr/src/sys/netiso/iso_var.h @@ -20,12 +20,32 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************/ +/* + * Modifications, + * Copyright (c) 1988 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, 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'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#)iso_var.h 7.2 (Berkeley) %G% + */ /* * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison */ -/* $Header: iso_var.h,v 4.2 88/06/29 15:00:08 hagens Exp $ */ -/* $Source: /usr/argo/sys/netiso/RCS/iso_var.h,v $ */ +/* $Header: iso_var.h,v 4.2 88/06/29 15:00:08 hagens Exp $ + * $Source: /usr/argo/sys/netiso/RCS/iso_var.h,v $ + */ /* * Interface address, iso version. One of these structures is @@ -35,26 +55,81 @@ SOFTWARE. */ struct iso_ifaddr { struct ifaddr ia_ifa; /* protocol-independent info */ +#define ia_ifp ia_ifa.ifa_ifp int ia_flags; + int ia_snpaoffset; struct iso_ifaddr *ia_next; /* next in list of iso addresses */ + struct sockaddr_iso ia_addr; /* reserve space for interface name */ + struct sockaddr_iso ia_dstaddr; /* reserve space for broadcast addr */ +#define ia_broadaddr ia_dstaddr + struct sockaddr_iso ia_sockmask; /* reserve space for general netmask */ +}; + +struct iso_aliasreq { + char ifra_name[IFNAMSIZ]; /* if name, e.g. "en0" */ + struct sockaddr_iso ifra_addr; + struct sockaddr_iso ifra_dstaddr; + struct sockaddr_iso ifra_mask; + int ifra_snpaoffset; +}; + +struct iso_ifreq { + char ifr_name[IFNAMSIZ]; /* if name, e.g. "en0" */ + struct sockaddr_iso ifr_Addr; }; -#define ia_ifp ia_ifa.ifa_ifp -#ifndef ia_addr -#define ia_addr ia_ifa.ifa_addr -#endif ia_addr /* * Given a pointer to an iso_ifaddr (ifaddr), * return a pointer to the addr as a sockaddr_iso */ -#define IA_SIS(ia)\ - ((struct sockaddr_iso *)(&((struct iso_ifaddr *)ia)->ia_addr)) +/* +#define IA_SIS(ia) ((struct sockaddr_iso *)(ia.ia_ifa->ifa_addr)) + * works if sockaddr_iso becomes variable sized. + */ +#define IA_SIS(ia) (&(((struct iso_ifaddr *)ia)->ia_addr)) + +#define SIOCDIFADDR_ISO _IOW('i',25, struct iso_ifreq) /* delete IF addr */ +#define SIOCAIFADDR_ISO _IOW('i',26, struct iso_aliasreq)/* add/chg IFalias */ +#define SIOCGIFADDR_ISO _IOWR('i',33, struct iso_ifreq) /* get ifnet address */ +#define SIOCGIFDSTADDR_ISO _IOWR('i',34, struct iso_ifreq) /* get dst address */ +#define SIOCGIFNETMASK_ISO _IOWR('i',37, struct iso_ifreq) /* get dst address */ + +#ifndef IFA_ROUTE +#define IFA_ROUTE 0x01 /* routing entry installed */ +#endif + +/* ISO arp IOCTL data structures */ +struct arpreq_iso { + int arp_flags; /* flags */ + struct sockaddr_iso arp_pa; /* protocol address */ + struct sockaddr arp_ha; /* hardware address */ +}; + +#define SIOCSISOMAP _IOW('a',30, struct arpreq_iso) /* set arp entry */ +#define SIOCGISOMAP _IOWR('a',38, struct arpreq_iso)/* get arp entry */ +#define SIOCDISOMAP _IOW('a',31, struct arpreq_iso) /* delete arp entry */ +/* + * This stuff should go in if.h or if_llc.h or someplace else, + * but for now . . . + */ -#ifndef IFA_ROUTE -#define IFA_ROUTE 0x01 /* routing entry installed */ -#endif IFA_ROUTE +struct llc_etherhdr { + char dst[6]; + char src[6]; + char len[2]; + char llc_dsap; + char llc_ssap; + char llc_ui_byte; +}; +struct snpa_hdr { + struct ifnet *snh_ifp; + char snh_dhost[6]; + char snh_shost[6]; + short snh_flags; +}; #ifdef KERNEL struct iso_ifaddr *iso_ifaddr; /* linked list of iso address ifaces */ +struct iso_ifaddr *iso_localifa(); /* linked list of iso address ifaces */ struct ifqueue clnlintrq; /* clnl packet input queue */ #endif KERNEL diff --git a/usr/src/sys/netiso/tp.trans b/usr/src/sys/netiso/tp.trans index 4eb4c22207..27fb1d8bd7 100644 --- a/usr/src/sys/netiso/tp.trans +++ b/usr/src/sys/netiso/tp.trans @@ -69,6 +69,8 @@ SOFTWARE. #include "../netiso/cons.h" #define DRIVERTRACE TPPTdriver +#define sbwakeup(sb) sowakeup(p->tp_sock, sb); +#define MCPY(d, w) (d ? m_copym(d, 0, (int)M_COPYALL, w): 0) static trick_hc = 1; @@ -306,7 +308,7 @@ TP_OPEN <== TP_LISTENING CR_TPDU ; TP_AKWAIT <== TP_LISTENING CR_TPDU - ( tp_emit(CC_TPDU_type, $P, 0,0, MNULL) == 0 ) + ( tp_emit(CC_TPDU_type, $P, 0,0, MCPY($P.tp_ucddata, M_NOWAIT)) == 0 ) { IncStat(ts_tp4_conn); /* even though not quite open */ IFTRACE(D_CONN) @@ -321,7 +323,7 @@ TP_AKWAIT <== TP_LISTENING CR_TPDU /* n/a for class 0 */ ASSERT($P.tp_Xrcv.sb_cc == 0); sbappendrecord(&$P.tp_Xrcv, $$.e_data); - $P.tp_flags |= TPF_CONN_DATA_IN; + /*$P.tp_flags |= TPF_CONN_DATA_IN;*/ $$.e_data = MNULL; } $P.tp_fcredit = $$.e_cdt; @@ -352,24 +354,19 @@ TP_CRSENT <== TP_CLOSED T_CONN_req DEFAULT { int error; - extern struct mbuf *m_copy(); struct mbuf *data = MNULL; IFTRACE(D_CONN) - tptrace(TPPTmisc, "T_CONN_req flags sbcc", (int)$P.tp_flags, - $P.tp_sock->so_snd.sb_cc, 0, 0); + tptrace(TPPTmisc, "T_CONN_req flags ucddata", (int)$P.tp_flags, + $P.tp_ucddata, 0, 0); ENDTRACE - if( $P.tp_flags & TPF_CONN_DATA_OUT ) { + data = MCPY($P.tp_ucddata, M_WAIT); + if (data) { IFDEBUG(D_CONN) printf("T_CONN_req.trans m_copy cc 0x%x\n", - $P.tp_sock->so_snd.sb_cc); - dump_mbuf($P.tp_sock->so_snd.sb_mb, "sosnd @ T_CONN_req"); + $P.tp_ucddata); + dump_mbuf(data, "sosnd @ T_CONN_req"); ENDDEBUG - data = - m_copy($P.tp_sock->so_snd.sb_mb, 0, $P.tp_sock->so_snd.sb_cc); - if( data == MNULL ) { - return ENOBUFS; - } } if (error = tp_emit(CR_TPDU_type, $P, 0, 0, data) ) @@ -388,7 +385,8 @@ TP_REFWAIT <== [ TP_CRSENT, TP_AKWAIT, TP_OPEN ] DR_TPDU DEFAULT { if ($$.e_datalen > 0 && $P.tp_class != TP_CLASS_0) { - sbdrop(&$P.tp_Xrcv, $P.tp_Xrcv.sb_cc); /* purge expedited data */ + /*sbdrop(&$P.tp_Xrcv, $P.tp_Xrcv.sb_cc); /* purge expedited data */ + sbflush(&$P.tp_Xrcv); $P.tp_flags |= TPF_DISC_DATA_IN; sbappendrecord(&$P.tp_Xrcv, $$.e_data); $$.e_data = MNULL; @@ -524,14 +522,13 @@ TP_OPEN <== TP_CRSENT CC_TPDU $P.tp_cong_win = $$.e_cdt; tp_getoptions($P); tp_cuntimeout($P.tp_refp, TM_retrans); - if( $P.tp_flags & TPF_CONN_DATA_OUT ) { + if ($P.tp_ucddata) { IFDEBUG(D_CONN) - printf("dropping %d octets of connect data cc 0x%x\n", - $P.tp_sock->so_snd.sb_mb->m_len, - $P.tp_sock->so_snd.sb_cc); + printf("dropping user connect data cc 0x%x\n", + $P.tp_ucddata->m_len); ENDDEBUG - sbdrop(&$P.tp_sock->so_snd, $P.tp_sock->so_snd.sb_cc); - $P.tp_flags &= ~TPF_CONN_DATA_OUT; + m_freem($P.tp_ucddata); + $P.tp_ucddata = 0; } soisconnected($P.tp_sock); if ($$.e_datalen > 0) { @@ -550,19 +547,16 @@ TP_OPEN <== TP_CRSENT CC_TPDU SAME <== TP_CRSENT TM_retrans ( $P.tp_retrans > 0 ) { - extern struct mbuf *m_copy(); struct mbuf *data = MNULL; int error; IncStat(ts_retrans_cr); - if( $P.tp_flags & TPF_CONN_DATA_OUT ) { + data = MCPY($P.tp_ucddata, M_NOWAIT); + if($P.tp_ucddata) { IFDEBUG(D_CONN) - printf("TM_retrans.trans m_copy cc 0x%x\n", - $P.tp_sock->so_snd.sb_cc); - dump_mbuf($P.tp_sock->so_snd.sb_mb, "sosnd @ TM_retrans"); + printf("TM_retrans.trans m_copy cc 0x%x\n", data); + dump_mbuf($P.tp_ucddata, "sosnd @ TM_retrans"); ENDDEBUG - data = - m_copy($P.tp_sock->so_snd.sb_mb, 0, $P.tp_sock->so_snd.sb_cc); if( data == MNULL ) return ENOBUFS; } @@ -595,8 +589,9 @@ SAME <== TP_AKWAIT CR_TPDU */ { int error; + struct mbuf *data = MCPY($P.tp_ucddata, M_WAIT); - if( error = tp_emit(CC_TPDU_type, $P, 0, 0, MNULL) ) { + if( error = tp_emit(CC_TPDU_type, $P, 0, 0, data) ) { $P.tp_sock->so_error = error; } $P.tp_retrans = $P.tp_Nretrans; @@ -611,11 +606,14 @@ TP_OPEN <== TP_AKWAIT DT_TPDU { int doack; - if( $P.tp_flags & TPF_CONN_DATA_OUT ) { - sbdrop(&$P.tp_sock->so_snd, $P.tp_sock->so_snd.sb_cc); - $P.tp_flags &= ~TPF_CONN_DATA_OUT; + /* + * Get rid of any confirm or connect data, so that if we + * crash or close, it isn't thought of as disconnect data. + */ + if ($P.tp_ucddata) { + m_freem($P.tp_ucddata); + $P.tp_ucddata = 0; } - tp_ctimeout($P.tp_refp, TM_inact, (int)$P.tp_inact_ticks); tp_cuntimeout($P.tp_refp, TM_retrans); soisconnected($P.tp_sock); @@ -707,11 +705,10 @@ SAME <== [ TP_OPEN, TP_AKWAIT ] DT_TPDU TP_OPEN <== TP_AKWAIT AK_TPDU DEFAULT { - if( $P.tp_flags & TPF_CONN_DATA_OUT ) { - sbdrop(&$P.tp_sock->so_snd, $P.tp_sock->so_snd.sb_cc); - $P.tp_flags &= ~TPF_CONN_DATA_OUT; + if ($P.tp_ucddata) { + m_freem($P.tp_ucddata); + $P.tp_ucddata = 0; } - (void) tp_goodack($P, $$.e_cdt, $$.e_seq, $$.e_subseq); tp_cuntimeout($P.tp_refp, TM_retrans); @@ -734,12 +731,12 @@ TP_OPEN <== TP_AKWAIT AK_TPDU /* TP4 only */ TP_OPEN <== [ TP_OPEN, TP_AKWAIT ] XPD_TPDU - ( $P.tp_Xrcvnxt == $$.e_seq && $P.tp_Xrcv.sb_cc == 0) + ( $P.tp_Xrcvnxt == $$.e_seq /* && $P.tp_Xrcv.sb_cc == 0*/) { if( $P.tp_state == TP_AKWAIT ) { - if( $P.tp_flags & TPF_CONN_DATA_OUT ) { - sbdrop(&$P.tp_sock->so_snd, $P.tp_sock->so_snd.sb_cc); - $P.tp_flags &= ~TPF_CONN_DATA_OUT; + if ($P.tp_ucddata) { + m_freem($P.tp_ucddata); + $P.tp_ucddata = 0; } tp_cuntimeout($P.tp_refp, TM_retrans); tp_getoptions($P); @@ -752,13 +749,11 @@ TP_OPEN <== [ TP_OPEN, TP_AKWAIT ] XPD_TPDU $P.tp_Xrcvnxt,$$.e_seq, $$.e_datalen, $$.e_data->m_len); ENDTRACE - sbappendrecord(&$P.tp_Xrcv, $$.e_data); + $P.tp_sock->so_state |= SS_RCVATMARK; + sbinsertoob(&$P.tp_Xrcv, $$.e_data); IFDEBUG(D_XPD) dump_mbuf($$.e_data, "XPD TPDU: tp_Xrcv"); ENDDEBUG - $P.tp_flags |= TPF_XPD_PRESENT; - /* kludge for select(): */ - $P.tp_sock->so_state |= SS_OOBAVAIL; tp_indicate(T_XDATA, $P, 0); sbwakeup( &$P.tp_Xrcv ); @@ -772,9 +767,9 @@ SAME <== TP_OPEN T_USR_Xrcvd DEFAULT { if( $P.tp_Xrcv.sb_cc == 0 ) { - $P.tp_flags &= ~TPF_XPD_PRESENT; + /*$P.tp_flags &= ~TPF_XPD_PRESENT;*/ /* kludge for select(): */ - $P.tp_sock->so_state &= ~SS_OOBAVAIL; + /* $P.tp_sock->so_state &= ~SS_OOBAVAIL; */ } } /* OLD WAY: @@ -810,11 +805,13 @@ SAME <== [ TP_AKWAIT, TP_OPEN ] XPD_TPDU if( $P.tp_Xrcvnxt != $$.e_seq ) IncStat(ts_xpd_niw); if( $P.tp_Xrcv.sb_cc ) { +#ifdef notdef if( $P.tp_flags & TPF_CONN_DATA_IN ) { /* user isn't reading the connection data; see note above */ sbdrop(&$P.tp_Xrcv, $P.tp_Xrcv.sb_cc); $P.tp_flags &= ~TPF_CONN_DATA_IN; } +#endif notdef /* might as well kick 'em again */ tp_indicate(T_XDATA, $P, 0); IncStat(ts_xpd_dup); @@ -853,6 +850,7 @@ TP_CLOSING <== [ TP_CLOSING, TP_AKWAIT, TP_CRSENT ] T_DETACH DEFAULT { struct socket *so = $P.tp_sock; + struct mbuf *data = MNULL; /* detach from parent socket so it can finish closing */ if (so->so_head) { @@ -862,7 +860,8 @@ TP_CLOSING <== [ TP_CLOSING, TP_AKWAIT, TP_CRSENT ] T_DETACH } if ($P.tp_state != TP_CLOSING) { tp_soisdisconnecting($P.tp_sock); - (void) tp_emit(DR_TPDU_type, $P, 0, E_TP_NORMAL_DISC, MNULL); + data = MCPY($P.tp_ucddata, M_NOWAIT); + (void) tp_emit(DR_TPDU_type, $P, 0, E_TP_NORMAL_DISC, data); $P.tp_retrans = $P.tp_Nretrans; tp_ctimeout($P.tp_refp, TM_retrans, (int)$P.tp_dr_ticks); } @@ -882,24 +881,20 @@ TP_REFWAIT <== [ TP_OPEN, TP_CRSENT ] T_DISC_req TP_CLOSING <== [ TP_AKWAIT, TP_OPEN, TP_CRSENT ] T_DISC_req DEFAULT { - struct mbuf *data = MNULL; - extern struct mbuf *m_copy(); + struct mbuf *data = MCPY($P.tp_ucddata, M_WAIT); if($P.tp_state == TP_OPEN) { tp_euntimeout($P.tp_refp, TM_data_retrans); /* all */ tp_cuntimeout($P.tp_refp, TM_inact); tp_cuntimeout($P.tp_refp, TM_sendack); } - if( $P.tp_flags & TPF_DISC_DATA_OUT ) { + if (data) { IFDEBUG(D_CONN) - printf("T_DISC_req.trans m_copy cc 0x%x\n", - $P.tp_sock->so_snd.sb_cc); - dump_mbuf($P.tp_sock->so_snd.sb_mb, "sosnd @ T_DISC_req"); + printf("T_DISC_req.trans tp_ucddata 0x%x\n", + $P.tp_ucddata); + dump_mbuf(data, "ucddata @ T_DISC_req"); ENDDEBUG - data = - m_copy($P.tp_sock->so_snd.sb_mb, 0, $P.tp_sock->so_snd.sb_cc); } - tp_soisdisconnecting($P.tp_sock); $P.tp_retrans = $P.tp_Nretrans; tp_ctimeout($P.tp_refp, TM_retrans, (int)$P.tp_dr_ticks); @@ -914,10 +909,11 @@ SAME <== TP_AKWAIT TM_retrans ( $P.tp_retrans > 0 ) { int error; + struct mbuf *data = MCPY($P.tp_ucddata, M_WAIT); IncStat(ts_retrans_cc); $P.tp_retrans --; - if( error = tp_emit(CC_TPDU_type, $P, 0, 0, MNULL) ) + if( error = tp_emit(CC_TPDU_type, $P, 0, 0, data) ) $P.tp_sock->so_error = error; tp_ctimeout($P.tp_refp, TM_retrans, (int)$P.tp_cc_ticks); } @@ -966,8 +962,7 @@ SAME <== TP_OPEN TM_retrans { /* resume XPD */ if ( $P.tp_Xsnd.sb_mb ) { - extern struct mbuf *m_copy(); - struct mbuf *m = m_copy($P.tp_Xsnd.sb_mb, 0, $P.tp_Xsnd.sb_cc); + struct mbuf *m = m_copy($P.tp_Xsnd.sb_mb, 0, (int)$P.tp_Xsnd.sb_cc); /* m_copy doesn't preserve the m_xlink field, but at this pt. * that doesn't matter */ @@ -996,7 +991,6 @@ SAME <== TP_OPEN TM_data_retrans register struct tp_rtc *r = $P.tp_snduna_rtc; register struct mbuf *m; register SeqNum high = $$.e_high; - extern struct mbuf *m_copy(); low = SEQ_GT($P, $P.tp_snduna, $$.e_low )? $P.tp_snduna: $$.e_low; @@ -1113,8 +1107,7 @@ SAME <== TP_OPEN T_XPD_req /* resume XPD */ if ( $P.tp_Xsnd.sb_mb ) { - extern struct mbuf *m_copy(); - struct mbuf *m = m_copy($P.tp_Xsnd.sb_mb, 0, $P.tp_Xsnd.sb_cc); + struct mbuf *m = m_copy($P.tp_Xsnd.sb_mb, 0, (int)$P.tp_Xsnd.sb_cc); /* m_copy doesn't preserve the m_xlink field, but at this pt. * that doesn't matter */ @@ -1201,7 +1194,6 @@ SAME <== TP_OPEN AK_TPDU /* just so happens that this is never true now, because we allow * only 1 packet in the queue at once (this could be changed) if ( $P.tp_Xsnd.sb_mb ) { - extern struct mbuf *m_copy(); struct mbuf *m = m_copy($P.tp_Xsnd.sb_mb, 0, ??); (void) tp_emit(XPD_TPDU_type, $P, $P.tp_Xuna, 1, m); diff --git a/usr/src/sys/netiso/tp_cons.c b/usr/src/sys/netiso/tp_cons.c index 807c06c404..dc36e47792 100644 --- a/usr/src/sys/netiso/tp_cons.c +++ b/usr/src/sys/netiso/tp_cons.c @@ -51,7 +51,7 @@ static char *rcsid = "$Header: tp_cons.c,v 5.6 88/11/18 17:27:13 nhall Exp $"; #ifdef ISO #if NARGOXTWENTYFIVE > 0 -#include "types.h" +#include "param.h" #include "socket.h" #include "domain.h" #include "mbuf.h" @@ -59,18 +59,18 @@ static char *rcsid = "$Header: tp_cons.c,v 5.6 88/11/18 17:27:13 nhall Exp $"; #include "time.h" #include "../net/if.h" -#include "../netiso/tp_param.h" -#include "../netiso/argo_debug.h" -#include "../netiso/tp_stat.h" -#include "../netiso/tp_pcb.h" -#include "../netiso/tp_trace.h" -#include "../netiso/tp_stat.h" -#include "../netiso/tp_tpdu.h" +#include "tp_param.h" +#include "argo_debug.h" +#include "tp_stat.h" +#include "tp_pcb.h" +#include "tp_trace.h" +#include "tp_stat.h" +#include "tp_tpdu.h" #include "../net/route.h" -#include "../netiso/iso.h" -#include "../netiso/iso_pcb.h" -#include "../netiso/cons.h" -#include "../netiso/tp_seq.h" +#include "iso.h" +#include "iso_pcb.h" +#include "cons.h" +#include "tp_seq.h" int tpcons_output(); diff --git a/usr/src/sys/netiso/tp_emit.c b/usr/src/sys/netiso/tp_emit.c index ea17757921..6bf51c5905 100644 --- a/usr/src/sys/netiso/tp_emit.c +++ b/usr/src/sys/netiso/tp_emit.c @@ -58,17 +58,17 @@ static char *rcsid = "$Header: tp_emit.c,v 5.5 88/11/18 17:27:20 nhall Exp $"; #include "errno.h" #include "types.h" #include "time.h" -#include "../netiso/iso.h" -#include "../netiso/argo_debug.h" -#include "../netiso/tp_timer.h" -#include "../netiso/tp_param.h" -#include "../netiso/tp_stat.h" -#include "../netiso/tp_pcb.h" -#include "../netiso/tp_tpdu.h" -#include "../netiso/tp_trace.h" -#include "../netiso/tp_meas.h" -#include "../netiso/tp_seq.h" -#include "../netiso/iso_errno.h" +#include "iso.h" +#include "argo_debug.h" +#include "tp_timer.h" +#include "tp_param.h" +#include "tp_stat.h" +#include "tp_pcb.h" +#include "tp_tpdu.h" +#include "tp_trace.h" +#include "tp_meas.h" +#include "tp_seq.h" +#include "iso_errno.h" void iso_gen_csum(); @@ -144,11 +144,22 @@ tp_emit(dutype, tpcb, seq, eot, data) */ IFDEBUG(D_EMIT) printf( - "tp_emit dutype 0x%x, tpcb 0x%x, eot 0x%x, seq 0x%x, data 0x%x mfree 0x%x", - dutype, tpcb, eot, seq, data, mfree); + "tp_emit dutype 0x%x, tpcb 0x%x, eot 0x%x, seq 0x%x, data 0x%x", + dutype, tpcb, eot, seq, data); ENDDEBUG - MGET(m, M_DONTWAIT, TPMT_TPHDR); + if (dutype == CR_TPDU || dutype == CC_TPDU) { + m = (struct mbuf *) malloc((u_long)256, M_MBUF, M_DONTWAIT); + if (m) { + m->m_type = TPMT_TPHDR; + mbstat.m_mtypes[TPMT_TPHDR]++; + m->m_next = MNULL; + m->m_data = m->m_dat; + m->m_flags = 0; + } + } else { + MGET(m, M_DONTWAIT, TPMT_TPHDR); + } if (m == NULL) { if(data != (struct mbuf *)0) m_freem(data); @@ -159,7 +170,7 @@ tp_emit(dutype, tpcb, seq, eot, data) m->m_act = MNULL; hdr = mtod(m, struct tpdu *); - bzero(hdr, sizeof(struct tpdu)); + bzero((caddr_t)hdr, sizeof(struct tpdu)); { int tp_headersize(); @@ -221,9 +232,9 @@ tp_emit(dutype, tpcb, seq, eot, data) ASSERT( tpcb->tp_fsuffixlen > 0 ); ADDOPTION(TPP_calling_sufx, hdr, - tpcb->tp_lsuffixlen, tpcb->tp_lsuffix); + tpcb->tp_lsuffixlen, tpcb->tp_lsuffix[0]); ADDOPTION(TPP_called_sufx, hdr, - tpcb->tp_fsuffixlen, tpcb->tp_fsuffix); + tpcb->tp_fsuffixlen, tpcb->tp_fsuffix[0]); } else { IncStat(ts_CC_sent); } @@ -334,10 +345,10 @@ tp_emit(dutype, tpcb, seq, eot, data) /* kludge to test the input size checking */ IFDEBUG(D_SIZE_CHECK) - if(data->m_len <= 16 && data->m_off < (MLEN-18) ) { + /*if(data->m_len <= 16 && data->m_off < (MLEN-18) ) { printf("Sending too much data on XPD: 18 bytes\n"); data->m_len = 18; - } + }*/ ENDDEBUG break; @@ -403,7 +414,7 @@ tp_emit(dutype, tpcb, seq, eot, data) * a) when using optimistic credit (which we no longer do). * b) when drain() gets implemented (not in the plans). * c) when D_RENEG is on. - * d) when DEC BIT response (PRC_QUENCH2) is implemented. + * d) when DEC BIT response is implemented. * (not- when we do this, we'll need to implement flow control * confirmation) */ @@ -515,9 +526,9 @@ tp_emit(dutype, tpcb, seq, eot, data) subseq = htons(tpcb->tp_r_subseq); fcredit = htons(tpcb->tp_fcredit); - bcopy((caddr_t) &lwe, &bogus[0], sizeof(SeqNum)); - bcopy((caddr_t) &subseq, &bogus[2], sizeof(u_short)); - bcopy((caddr_t) &fcredit, &bogus[3], sizeof(u_short)); + bcopy((caddr_t) &lwe, (caddr_t)&bogus[0], sizeof(SeqNum)); + bcopy((caddr_t) &subseq, (caddr_t)&bogus[2], sizeof(u_short)); + bcopy((caddr_t) &fcredit, (caddr_t)&bogus[3], sizeof(u_short)); IFTRACE(D_ACKSEND) tptraceTPCB(TPPTmisc, @@ -568,7 +579,7 @@ tp_emit(dutype, tpcb, seq, eot, data) m->m_next = data; - ASSERT( hdr->tpdu_li < MMAXOFF ); /* leave this in */ + ASSERT( hdr->tpdu_li < MLEN ); /* leave this in */ ASSERT( hdr->tpdu_li != 0 ); /* leave this in */ m->m_len = hdr->tpdu_li ; @@ -600,13 +611,13 @@ tp_emit(dutype, tpcb, seq, eot, data) IFDEBUG(D_EMIT) printf("tp_emit before tpxxx_output tpcb 0x%x, dutype 0x%x, datalen 0x%x\n", tpcb, dutype, datalen); - dump_buf( m, datalen+12); + dump_buf(mtod(m, caddr_t), datalen); ENDDEBUG IFPERF(tpcb) if( dutype == DT_TPDU_type ) { PStat(tpcb, Nb_to_ll) += (datalen - m->m_len); - tpmeas( tpcb->tp_lref, TPtime_to_ll, 0, + tpmeas( tpcb->tp_lref, TPtime_to_ll, (struct timeval *)0, seq, PStat(tpcb, Nb_to_ll), (datalen - m->m_len)); } ENDPERF @@ -641,12 +652,11 @@ tp_emit(dutype, tpcb, seq, eot, data) ENDTRACE done: if( error == E_CO_QFULL ) { - tp_quench( tpcb ); + tp_quench(tpcb, PRC_QUENCH); return 0; } return error; } - /* * NAME: tp_error_emit() * CALLED FROM: tp_input() when a DR or ER is to be issued in @@ -757,7 +767,7 @@ tp_error_emit(error, sref, faddr, laddr, erdata, erlen, tpcb, cons_channel, csum_offset = hdr->tpdu_li - 2; } - ASSERT( hdr->tpdu_li < MMAXOFF ); + ASSERT( hdr->tpdu_li < MLEN ); if (dutype == ER_TPDU_type) { /* copy the errant tpdu into another 'variable part' */ @@ -787,8 +797,11 @@ tp_error_emit(error, sref, faddr, laddr, erdata, erlen, tpcb, cons_channel, if(erdata->m_len == 0) { erdata = m_free(erdata); /* returns the next mbuf on the chain */ } - m->m_next = m_copy(erdata, 0, erlen); /* copy only up to the - bad octet (or max that will fit in a header */ + /* + * copy only up to the bad octet + * (or max that will fit in a header + */ + m->m_next = m_copy(erdata, 0, erlen); hdr->tpdu_li += erlen + 2; m_freem(erdata); } else { @@ -832,9 +845,9 @@ tp_error_emit(error, sref, faddr, laddr, erdata, erlen, tpcb, cons_channel, IFDEBUG(D_ERROR_EMIT) printf("tp_error_emit 1 sending DG: Laddr\n"); - dump_isoaddr( laddr ); + dump_addr((struct sockaddr *)laddr); printf("Faddr\n"); - dump_isoaddr( faddr ); + dump_addr((struct sockaddr *)faddr); ENDDEBUG return (tpcb->tp_nlproto->nlp_dgoutput)( &laddr->siso_addr, @@ -844,7 +857,7 @@ tp_error_emit(error, sref, faddr, laddr, erdata, erlen, tpcb, cons_channel, } else { if( cons_channel ) { #if NARGOXTWENTYFIVE > 0 -#include "../netiso/cons.h" +#include "cons.h" /* This is unfortunate... cons_send_on_vc(cons_channel, m, datalen); */ @@ -859,24 +872,24 @@ tp_error_emit(error, sref, faddr, laddr, erdata, erlen, tpcb, cons_channel, cons_channel); #endif NARGOXTWENTYFIVE > 0 } else { -#ifndef nodef +#ifndef notdef IFDEBUG(D_ERROR_EMIT) printf("tp_error_emit sending DG: Laddr\n"); - dump_isoaddr( laddr ); + dump_addr((struct sockaddr *)laddr); printf("Faddr\n"); - dump_isoaddr( laddr ); + dump_addr((struct sockaddr *)faddr); ENDDEBUG return (*dgout_routine)( &laddr->siso_addr, &faddr->siso_addr, m, datalen, /* no route */ (caddr_t)0, /* nochecksum==false */0); -#else nodef +#else notdef IFDEBUG(D_ERROR_EMIT) printf("tp_error_emit DROPPING \n", m); ENDDEBUG IncStat(ts_send_drop); m_freem(m); return 0; -#endif nodef +#endif notdef } } } diff --git a/usr/src/sys/netiso/tp_inet.c b/usr/src/sys/netiso/tp_inet.c index 6d9b96314a..bb50abd4ac 100644 --- a/usr/src/sys/netiso/tp_inet.c +++ b/usr/src/sys/netiso/tp_inet.c @@ -52,23 +52,26 @@ static char *rcsid = "$Header: tp_inet.c,v 5.3 88/11/18 17:27:29 nhall Exp $"; #ifdef INET -#include "types.h" +#include "param.h" #include "socket.h" #include "socketvar.h" #include "mbuf.h" #include "errno.h" #include "time.h" #include "../net/if.h" -#include "../netiso/tp_param.h" -#include "../netiso/argo_debug.h" -#include "../netiso/tp_stat.h" -#include "../netiso/tp_ip.h" -#include "../netiso/tp_pcb.h" -#include "../netiso/tp_trace.h" -#include "../netiso/tp_stat.h" -#include "../netiso/tp_tpdu.h" +#include "tp_param.h" +#include "argo_debug.h" +#include "tp_stat.h" +#include "tp_ip.h" +#include "tp_pcb.h" +#include "tp_trace.h" +#include "tp_stat.h" +#include "tp_tpdu.h" #include "../netinet/in_var.h" +#ifndef ISO +#include "iso_chksum.c" +#endif /* * NAME: in_getsufx() @@ -87,19 +90,22 @@ static char *rcsid = "$Header: tp_inet.c,v 5.3 88/11/18 17:27:29 nhall Exp $"; * * NOTES: */ - -int -in_getsufx(inp, which) +in_getsufx(inp, lenp, data_out, which) struct inpcb *inp; + u_short *lenp; + caddr_t data_out; int which; { + *lenp = sizeof(u_short); switch (which) { case TP_LOCAL: - return (int) inp->inp_lport; + *(u_short *)data_out = inp->inp_lport; + return; case TP_FOREIGN: - return (int) inp->inp_fport; + *(u_short *)data_out = inp->inp_fport; } + } /* @@ -118,19 +124,15 @@ in_getsufx(inp, which) * * NOTES: */ +/*ARGSUSED*/ void -in_putsufx(inp, name, which) +in_putsufx(inp, sufxloc, sufxlen, which) struct inpcb *inp; - struct sockaddr_in *name; + caddr_t sufxloc; int which; { - switch (which) { - case TP_LOCAL: - inp->inp_lport = name->sin_port; - break; - case TP_FOREIGN: - inp->inp_fport = name->sin_port; - break; + if (which == TP_FOREIGN) { + bcopy(sufxloc, (caddr_t)&inp->inp_fport, sizeof(inp->inp_fport)); } } @@ -205,7 +207,7 @@ in_putnetaddr(inp, name, which) * pr_usrreq() PRU_SOCKADDR, PRU_ACCEPT, PRU_PEERADDR * FUNCTION and ARGUMENTS: * Copy a whole net addr from an inpcb (inp) into - * a struct sockaddr (name). + * an mbuf (name); * The argument (which) takes values TP_LOCAL or TP_FOREIGN. * * RETURNS: Nada @@ -217,23 +219,26 @@ in_putnetaddr(inp, name, which) void in_getnetaddr( inp, name, which) + register struct mbuf *name; struct inpcb *inp; - struct sockaddr_in *name; int which; { + register struct sockaddr_in *sin = mtod(name, struct sockaddr_in *); + bzero((caddr_t)sin, sizeof(*sin)); switch (which) { case TP_LOCAL: - bcopy( (caddr_t)&inp->inp_laddr, (caddr_t)&name->sin_addr, - sizeof(struct in_addr)); - /* won't work if the dst address (name) is INADDR_ANY */ + sin->sin_addr = inp->inp_laddr; + sin->sin_port = inp->inp_lport; break; - case TP_FOREIGN: - bcopy( (caddr_t)&inp->inp_faddr, (caddr_t)&name->sin_addr, - sizeof(struct in_addr)); - /* won't work if the dst address (name) is INADDR_ANY */ + sin->sin_addr = inp->inp_faddr; + sin->sin_port = inp->inp_fport; break; + default: + return; } + name->m_len = sin->sin_len = sizeof (*sin); + sin->sin_family = AF_INET; } /* @@ -387,6 +392,7 @@ tpip_output(inp, m0, datalen, nochksum) * NOTES: */ +/*ARGSUSED*/ int tpip_output_dg(laddr, faddr, m0, datalen, ro, nochksum) struct in_addr *laddr, *faddr; @@ -404,21 +410,20 @@ tpip_output_dg(laddr, faddr, m0, datalen, ro, nochksum) ENDDEBUG - MGET(m, M_DONTWAIT, TPMT_IPHDR); + MGETHDR(m, M_DONTWAIT, TPMT_IPHDR); if (m == 0) { error = ENOBUFS; goto bad; } - bzero(mtod(m, caddr_t), MLEN); m->m_next = m0; - m->m_off = MMAXOFF - sizeof(struct ip); + MH_ALIGN(m, sizeof(struct ip)); m->m_len = sizeof(struct ip); - m->m_act = MNULL; ip = mtod(m, struct ip *); + bzero((caddr_t)ip, sizeof *ip); ip->ip_p = IPPROTO_TP; - ip->ip_len = sizeof(struct ip) + datalen; + m->m_pkthdr.len = ip->ip_len = sizeof(struct ip) + datalen; ip->ip_ttl = MAXTTL; /* don't know why you need to set ttl; * overlay doesn't even make this available @@ -462,40 +467,39 @@ bad: * NOTES: */ ProtoHook -tpip_input(m) +tpip_input(m, iplen) struct mbuf *m; + int iplen; { - typedef struct { - struct ip tpip_i; - struct tpdu tpip_d; - } tpiphdr; - register struct tpdu *hdr = mtod(m, struct tpdu *); struct sockaddr_in src, dst; register struct ip *ip; - int s = splnet(); + int s = splnet(), hdrlen; IncStat(ts_pkt_rcvd); - /* IP layer has already pulled up the IP header */ + /* + * IP layer has already pulled up the IP header, + * but the first byte after the IP header may not be there, + * e.g. if you came in via loopback, so you have to do an + * m_pullup to before you can even look to see how much you + * really need. The good news is that m_pullup will round + * up to almost the next mbuf's worth. + */ - while( m->m_len < 1 ) { - struct mbuf *n; - n = m_free(m); - if( n == MNULL ) { - splx(s); - return 0; - } - } + + if((m = m_pullup(m, iplen + 1)) == MNULL) + goto discard; CHANGE_MTYPE(m, TPMT_DATA); /* - * now pull up the whole tp header : we stripped all leading mbufs - * w/o at least one byte, so we know we can read the tpdu_li field. + * Now pull up the whole tp header: + * Unfortunately, there may be IP options to skip past so we + * just fetch it as an unsigned char. */ - hdr = &(mtod(m, tpiphdr *))->tpip_d; + hdrlen = iplen + 1 + mtod(m, u_char *)[iplen]; - if( m->m_len < hdr->tpdu_li + 1 + sizeof(struct ip) ) { - if((m = m_pullup(m, sizeof(struct ip) + (int)(hdr->tpdu_li)+1))==MNULL){ + if( m->m_len < hdrlen ) { + if((m = m_pullup(m, hdrlen)) == MNULL){ IFDEBUG(D_TPINPUT) printf("tp_input, pullup 2!\n"); ENDDEBUG @@ -513,21 +517,24 @@ tpip_input(m) /* * m_pullup may have returned a different mbuf */ - ip = &(mtod(m, tpiphdr *))->tpip_i; + ip = mtod(m, struct ip *); /* * drop the ip header from the front of the mbuf * this is necessary for the tp checksum */ - m->m_len -= sizeof(struct ip); - m->m_off += sizeof(struct ip); + m->m_len -= iplen; + m->m_data += iplen; src.sin_addr = *(struct in_addr *)&(ip->ip_src); src.sin_family = AF_INET; + src.sin_len = sizeof(src); dst.sin_addr = *(struct in_addr *)&(ip->ip_dst); dst.sin_family = AF_INET; + dst.sin_len = sizeof(dst); - (void) tp_input(m, &src, &dst, 0, tpip_output_dg); + (void) tp_input(m, (struct sockaddr *)&src, (struct sockaddr *)&dst, + 0, tpip_output_dg); splx(s); return 0; @@ -540,7 +547,7 @@ discard: ENDTRACE m_freem(m); IncStat(ts_recv_drop); - + splx(s); return 0; } @@ -548,6 +555,7 @@ discard: #include "../h/protosw.h" #include "../netinet/ip_icmp.h" +extern void tp_quench(); /* * NAME: tpin_quench() * @@ -566,7 +574,7 @@ void tpin_quench(inp) struct inpcb *inp; { - tp_quench( inp->inp_socket->so_tpcb ); + tp_quench((struct tp_pcb *)inp->inp_socket->so_tpcb, PRC_QUENCH); } /* @@ -607,7 +615,8 @@ tpip_ctlinput(cmd, sin) switch (cmd) { case PRC_QUENCH: - in_pcbnotify(&tp_inpcb, &sin->sin_addr, 0, tp_quench); + in_pcbnotify(&tp_inpcb, &sin->sin_addr, + 0, (int (*)())tp_quench); break; case PRC_ROUTEDEAD: @@ -635,7 +644,8 @@ tpip_ctlinput(cmd, sin) case PRC_TIMXCEED_REASS: case PRC_PARAMPROB: */ - in_pcbnotify(&tp_inpcb, sin, (int)inetctlerrmap[cmd], tpin_abort); + in_pcbnotify(&tp_inpcb, &sin->sin_addr, + (int)inetctlerrmap[cmd], tpin_abort); } return 0; } @@ -667,7 +677,7 @@ tpin_abort(inp) e.ev_number = ER_TPDU; e.ATTR(ER_TPDU).e_reason = ENETRESET; - (void) tp_driver(inp->inp_ppcb, &e); + (void) tp_driver((struct tp_pcb *)inp->inp_ppcb, &e); return 0; } @@ -697,39 +707,37 @@ struct ifnet * tpip_route(dst) struct in_addr *dst; { - struct ifnet *ifp = (struct ifnet *)0; - struct sockaddr_in *dst_in; - struct route iproute; - struct route *ro = (struct route *)0; - struct in_ifaddr *ia; + struct ifnet *ifp = (struct ifnet *)0; + struct sockaddr_in insock; + struct sockaddr_in *sin = &insock; + struct rtentry *rt; + struct ifaddr *ia; IFDEBUG(D_CONN) printf("tpip_route: dst is x%x\n", *dst); ENDDEBUG - ro = &iproute; - bzero((caddr_t)ro, sizeof (*ro)); - dst_in = (struct sockaddr_in *)&ro->ro_dst; - dst_in->sin_family = AF_INET; - dst_in->sin_addr = *dst; + bzero((caddr_t)sin, sizeof (*sin)); + sin->sin_family = AF_INET; + sin->sin_len = sizeof(*sin); + sin->sin_addr = *dst; - ia = (struct in_ifaddr *)ifa_ifwithdstaddr(dst_in); + ia = ifa_ifwithdstaddr((struct sockaddr *)sin); if (ia == 0) - ia = in_iaonnetof(in_netof(dst_in)); + ia = ifa_ifwithnet((struct sockaddr *)sin); if (ia != 0) { - ifp = ia->ia_ifp; + ifp = ia->ifa_ifp; IFDEBUG(D_CONN) printf("tpip_route: ifp from ia:0x%x\n", ia); ENDDEBUG } else { - rtalloc(ro); - if (ro->ro_rt != 0) { - ifp = ro->ro_rt->rt_ifp; + rt = rtalloc1((struct sockaddr *)sin, 0); + if (rt != 0) { + ifp = rt->rt_ifp; IFDEBUG(D_CONN) - printf("tpip_route: ifp from route:0x%x ro_rt 0x%x\n", ro, - ro->ro_rt); + printf("tpip_route: ifp from rentry: 0x%x\n", rt); ENDDEBUG - rtfree(ro->ro_rt); + rtfree(rt); } } IFDEBUG(D_CONN) diff --git a/usr/src/sys/netiso/tp_input.c b/usr/src/sys/netiso/tp_input.c index c13374f086..ac2ec0387b 100644 --- a/usr/src/sys/netiso/tp_input.c +++ b/usr/src/sys/netiso/tp_input.c @@ -66,32 +66,34 @@ static char *rcsid = "$Header: tp_input.c,v 5.6 88/11/18 17:27:38 nhall Exp $"; #include "time.h" #include "kernel.h" #include "types.h" -#include "../netiso/iso_errno.h" -#include "../netiso/tp_param.h" -#include "../netiso/tp_timer.h" -#include "../netiso/tp_stat.h" -#include "../netiso/tp_pcb.h" -#include "../netiso/argo_debug.h" -#include "../netiso/tp_trace.h" -#include "../netiso/tp_tpdu.h" -#include "../netiso/iso.h" -#include "../netiso/cons.h" +#include "iso_errno.h" +#include "tp_param.h" +#include "tp_timer.h" +#include "tp_stat.h" +#include "tp_pcb.h" +#include "argo_debug.h" +#include "tp_trace.h" +#include "tp_tpdu.h" +#include "iso.h" +#include "cons.h" int iso_check_csum(), tp_driver(), tp_headersize(), tp_error_emit(); -#ifdef lint -#undef ATTR -#define ATTR(X)ev_number -#endif lint +/* + #ifdef lint + #undef ATTR + #define ATTR(X)ev_number + #endif lint +*/ struct mbuf * tp_inputprep(m) - struct mbuf *m; + register struct mbuf *m; { - struct tpdu *hdr; + int hdrlen; IFDEBUG(D_TPINPUT) - printf("tp_inputprep: m 0x%x\n") ; + printf("tp_inputprep: m 0x%x\n", m) ; ENDDEBUG while( m->m_len < 1 ) { @@ -99,35 +101,28 @@ tp_inputprep(m) return (struct mbuf *)0; } } + if(((int)m->m_data) & 0x3) { + /* If we are not 4-byte aligned, we have to be + * above the beginning of the mbuf, and it is ok just + * to slide it back. + */ + caddr_t ocp = m->m_data; - if(m->m_off & 0x3) { - /* align to a 4-byte boundary - sigh */ - register struct mbuf *n; - - MGET(n, M_DONTWAIT, m->m_type); - if( n == MNULL ) { - m_freem(m); - return (struct mbuf *)0; - } - n->m_act = MNULL; - n->m_len = m->m_len; - n->m_next = m->m_next; - bcopy( mtod(m, caddr_t), mtod(n, caddr_t), m->m_len ); - m->m_next = 0; - m_free(m); - m = n; + m->m_data = (caddr_t)(((int)m->m_data) & ~0x3); + ovbcopy(ocp, m->m_data, (unsigned)m->m_len); } CHANGE_MTYPE(m, TPMT_DATA); - /* we KNOW that there is at least 1 byte in this mbuf */ + /* we KNOW that there is at least 1 byte in this mbuf + and that it is hdr->tpdu_li XXXXXXX! */ - hdr = mtod( m, struct tpdu *); + hdrlen = 1 + *mtod( m, u_char *); /* * now pull up the whole tp header */ - if ( m->m_len < hdr->tpdu_li + 1 ) { - if ((m = m_pullup(m, (int)(hdr->tpdu_li) + 1)) == MNULL ) { + if ( m->m_len < hdrlen) { + if ((m = m_pullup(m, hdrlen)) == MNULL ) { IncStat(ts_recv_drop); return (struct mbuf *)0; } @@ -135,7 +130,7 @@ tp_inputprep(m) IFDEBUG(D_INPUT) printf( " at end: m 0x%x hdr->tpdu_li 0x%x m_len 0x%x\n",m, - hdr->tpdu_li,m->m_len); + hdrlen, m->m_len); ENDDEBUG return m; } @@ -248,8 +243,9 @@ tp_newsocket(so, fname, cons_channel, class_to_use, netservice) * listening socket */ IFDEBUG(D_NEWSOCK) - printf("tp_newsocket(channel 0x%x) after sonewconn so 0x%x \n", so); - dump_isoaddr(fname); + printf("tp_newsocket(channel 0x%x) after sonewconn so 0x%x \n", + cons_channel, so); + dump_addr(fname); { struct socket *t, *head ; @@ -273,26 +269,19 @@ tp_newsocket(so, fname, cons_channel, class_to_use, netservice) newtpcb->tp_l_tpdusize = tpcb->tp_l_tpdusize; newtpcb->tp_lsuffixlen = tpcb->tp_lsuffixlen; bcopy( tpcb->tp_lsuffix, newtpcb->tp_lsuffix, newtpcb->tp_lsuffixlen); - soreserve(so, tpcb->tp_winsize, tpcb->tp_winsize); + soreserve(so, (u_long)tpcb->tp_winsize, (u_long)tpcb->tp_winsize); - if( /* old */ tpcb->tp_flags & (TPF_CONN_DATA_OUT | TPF_DISC_DATA_OUT )) { + if( /* old */ tpcb->tp_ucddata) { /* - * Flags has already been copied, now copy the data - * -- these data are the connect- or disconnect- data. + * These data are the connect- , confirm- or disconnect- data. */ struct mbuf *conndata; - ASSERT(tpcb->tp_sock->so_snd.sb_mb != MNULL); - ASSERT(tpcb->tp_sock->so_snd.sb_cc != 0); - conndata = m_copy( tpcb->tp_sock->so_snd.sb_mb, 0, - tpcb->tp_sock->so_snd.sb_cc); + conndata = m_copy(tpcb->tp_ucddata, 0, (int)M_COPYALL); IFDEBUG(D_CONN) dump_mbuf(conndata, "conndata after mcopy"); - dump_mbuf(tpcb->tp_sock->so_snd.sb_mb, "old sosnd after mcopy"); - dump_mbuf(so->so_snd.sb_mb, "new (so->)sosnd before sbapndrec"); - dump_mbuf(conndata, "conndata before sbappendrec"); ENDDEBUG - sbappendrecord( &so->so_snd, conndata ); + newtpcb->tp_ucddata = conndata; } tpcb = newtpcb; @@ -317,10 +306,8 @@ tp_newsocket(so, fname, cons_channel, class_to_use, netservice) * pcb_connect, which expects the name/addr in an mbuf as well. * sigh. */ - bcopy((caddr_t)fname, mtod(m, caddr_t), sizeof (struct sockaddr)); - m->m_act = MNULL; - m->m_len = (fname->sa_family == AF_INET) ? - sizeof(struct sockaddr_in) : sizeof(struct sockaddr_iso); + bcopy((caddr_t)fname, mtod(m, caddr_t), fname->sa_len); + m->m_len = fname->sa_len; /* grot : have to say the kernel can override params in * the passive open case @@ -447,7 +434,7 @@ again: for(;;) { tpdu_len += n->m_len; IFDEBUG(D_MBUF_MEAS) - if( n->m_off > MMAXOFF) { + if( n->m_flags & M_EXT) { IncStat(ts_mb_cluster); } else { IncStat(ts_mb_small); @@ -513,7 +500,7 @@ again: #ifdef notdef /* This is done up above */ sref = hdr->tpdu_CRsref; #endif notdef - preferred_class = (1 << hdr->tpdu_CRclass); + preferred_class = 1 << hdr->tpdu_CRclass; opt = hdr->tpdu_CRoptions; WHILE_OPTIONS(P, hdr, 1 ) /* { */ @@ -558,7 +545,7 @@ again: printf("CR lsufx:"); { register int j; for(j=0; jtpv_len; i>0; i--) { aclass = (u_char *) &(((struct tp_vbp *)P)->tpv_val); - alt_classes |= (1<<(*aclass)); + alt_classes |= (1<<((*aclass)>>4)); } IFDEBUG(D_TPINPUT) printf("alt_classes 0x%x\n", alt_classes); @@ -759,11 +746,12 @@ again: if( (so = tp_newsocket(so, faddr, cons_channel, class_to_use, - (dgout_routine == tpcons_output)?ISO_CONS:ISO_CLNS) + ((tpcb->tp_netservice == IN_CLNS) ? IN_CLNS : + (dgout_routine == tpcons_output)?ISO_CONS:ISO_CLNS)) ) == (struct socket *)0 ) { /* note - even if netservice is IN_CLNS, as far as * the tp entity is concerned, the only differences - * are CO vs CL + * are CO vs CL */ IFDEBUG(D_CONN) printf("tp_newsocket returns 0\n"); @@ -772,42 +760,20 @@ again: } tpcb = sototpcb(so); - /* stash the f suffix in the new tpcb */ - /* l suffix is already there */ - - bcopy( fsufxloc, tpcb->tp_fsuffix, fsufxlen); - if( (tpcb->tp_fsuffixlen = fsufxlen) == sizeof(short) ) { - /* even if it's AF_ISO */ - bcopy (fsufxloc, &(satosin(faddr)->sin_port), sizeof(short)); - (tpcb->tp_nlproto->nlp_putsufx)(so->so_pcb, faddr, TP_FOREIGN); - } - /* - * stash the addresses in the net level pcb + * Stash the addresses in the net level pcb * kind of like a pcbconnect() but don't need * or want all those checks. */ (tpcb->tp_nlproto->nlp_putnetaddr)(so->so_pcb, faddr, TP_FOREIGN); (tpcb->tp_nlproto->nlp_putnetaddr)(so->so_pcb, laddr, TP_LOCAL); - /* - * in the AF_INET case, we need the l,f addrs to contain the ports - */ - if( tpcb->tp_domain == AF_INET) { - CHECK((fsufxlen != sizeof(short))||(lsufxlen != sizeof(short)), - E_TP_ADDR_UNK, ts_inv_dref, respond, - (fsufxloc - (caddr_t)hdr)) - bcopy (lsufxloc, &(satosin(laddr)->sin_port), sizeof(short)); - (tpcb->tp_nlproto->nlp_putsufx)(so->so_pcb, laddr, TP_LOCAL); - /* - this has already been done 'cause the fsufxlen is - sizeof(short): - bcopy (fsufxloc, &(satosin(faddr)->sin_port), - sizeof(short)); - (tpcb->tp_nlproto->nlp_putsufx)(so->so_pcb, faddr, - TP_FOREIGN); - */ - } + /* stash the f suffix in the new tpcb */ + /* l suffix is already there */ + + bcopy(fsufxloc, tpcb->tp_fsuffix, fsufxlen); + (tpcb->tp_nlproto->nlp_putsufx) + (so->so_pcb, fsufxloc, fsufxlen, TP_FOREIGN); #ifdef TP_PERF_MEAS if( tpcb->tp_perf_on = perf_meas ) { /* assignment */ @@ -847,7 +813,7 @@ again: */ IFDEBUG(D_ZDREF) IncStat(ts_zdebug); - tpcb->tp_fref = 0; + /*tpcb->tp_fref = 0;*/ ENDDEBUG } IncStat(ts_CR_rcvd); @@ -938,7 +904,7 @@ again: WHILE_OPTIONS(P, hdr, tpcb->tp_xtd_format) /* { */ -# define caseof(x,y) case (((x)<<8)+(y)) +#define caseof(x,y) case (((x)<<8)+(y)) switch( dutype | vbptr(P)->tpv_code ) { caseof( CC_TPDU_type, TPP_addl_opt ): @@ -993,7 +959,7 @@ again: caseof( XAK_TPDU_type, TPP_checksum): caseof( DC_TPDU_type, TPP_checksum): if( tpcb->tp_use_checksum ) { - CHECK( iso_check_csum(m, hdr->tpdu_li + 1), + CHECK( iso_check_csum(m, (int)hdr->tpdu_li + 1), E_TP_INV_PVAL, ts_bad_csum, discard, 0) } break; @@ -1348,22 +1314,52 @@ again: * into the mbuf's data area and we're still using hdr (the tpdu header) */ m->m_len -= ((int)hdr->tpdu_li + 1); - m->m_off += ((int)hdr->tpdu_li + 1); + m->m_data += ((int)hdr->tpdu_li + 1); - if(takes_data) { - register int max; + if (takes_data) { + int max = tpdu_info[ hdr->tpdu_type ] [TP_MAX_DATA_INDEX]; + int datalen = tpdu_len - hdr->tpdu_li - 1, mbtype = MT_DATA; + struct tp_control_hdr c_hdr; + struct mbuf *n; + CHECK( (max && datalen > max), E_TP_LENGTH_INVAL, + ts_inv_length, respond, (max + hdr->tpdu_li + 1) ); switch( hdr->tpdu_type ) { + case CR_TPDU_type: + c_hdr.cmsg_type = TPOPT_CONN_DATA; + goto make_control_msg; + case CC_TPDU_type: + c_hdr.cmsg_type = TPOPT_CFRM_DATA; + goto make_control_msg; + case DR_TPDU_type: + c_hdr.cmsg_type = TPOPT_DISC_DATA; + make_control_msg: + c_hdr.cmsg_level = SOL_TRANSPORT; + mbtype = MT_CONTROL; + if (datalen > 0) { + datalen += sizeof(c_hdr); + m->m_len += sizeof(c_hdr); + m->m_data -= sizeof(c_hdr); + c_hdr.cmsg_len = datalen; + bcopy((caddr_t)&c_hdr, mtod(m, caddr_t), + sizeof(c_hdr)); + } + /* FALLTHROUGH */ + case XPD_TPDU_type: - case DT_TPDU_type: - e.ATTR(DT_TPDU).e_datalen = tpdu_len - hdr->tpdu_li - 1; - max = tpdu_info[ hdr->tpdu_type ] [TP_MAX_DATA_INDEX]; - CHECK( (max && e.ATTR(DT_TPDU).e_datalen > max), - E_TP_LENGTH_INVAL,ts_inv_length, respond, (max + hdr->tpdu_li + 1)) + if (mbtype != MT_CONTROL) + mbtype = MT_OOBDATA; + m->m_flags |= M_EOR; + /* FALLTHROUGH */ + case DT_TPDU_type: + for (n = m; n; n = n->m_next) { + MCHTYPE(n, mbtype); + } + e.ATTR(DT_TPDU).e_datalen = datalen; e.ATTR(DT_TPDU).e_data = m; break; @@ -1427,6 +1423,7 @@ separate: * we can just pull up some more and repeat */ + if( m = tp_inputprep(m) ) { IFDEBUG(D_TPINPUT) hdr = mtod(m, struct tpdu *); printf("tp_input @ separate: hdr 0x%x size %d m 0x%x\n", @@ -1434,7 +1431,6 @@ separate: dump_mbuf(m, "tp_input after driver, at separate"); ENDDEBUG - if( m = tp_inputprep(m) ) { IncStat(ts_concat_rcvd); goto again; } @@ -1474,9 +1470,9 @@ respond: ENDTRACE if( sref == 0 ) goto discard; - (void) tp_error_emit(error, sref, faddr, laddr, - m, errloc, tpcb, cons_channel, dgout_routine - ); + (void) tp_error_emit(error, (u_long)sref, (struct sockaddr_iso *)faddr, + (struct sockaddr_iso *)laddr, m, (int)errloc, tpcb, + (int)cons_channel, dgout_routine); IFDEBUG(D_ERROR_EMIT) printf("tp_input after error_emit\n"); ENDDEBUG diff --git a/usr/src/sys/netiso/tp_iso.c b/usr/src/sys/netiso/tp_iso.c index 026dc4dbe3..eb37c28afa 100644 --- a/usr/src/sys/netiso/tp_iso.c +++ b/usr/src/sys/netiso/tp_iso.c @@ -26,8 +26,8 @@ SOFTWARE. */ /* * ARGO TP - * $Header: tp_iso.c,v 5.3 88/11/18 17:27:57 nhall Exp $ - * $Source: /usr/argo/sys/netiso/RCS/tp_iso.c,v $ + * $Header: /var/src/sys/netiso/RCS/tp_iso.c,v 5.1 89/02/09 16:20:51 hagens Exp $ + * $Source: /var/src/sys/netiso/RCS/tp_iso.c,v $ * * Here is where you find the iso-dependent code. We've tried * keep all net-level and (primarily) address-family-dependent stuff @@ -49,52 +49,58 @@ SOFTWARE. */ #ifndef lint -static char *rcsid = "$Header: tp_iso.c,v 5.3 88/11/18 17:27:57 nhall Exp $"; +static char *rcsid = "$Header: /var/src/sys/netiso/RCS/tp_iso.c,v 5.1 89/02/09 16:20:51 hagens Exp $"; #endif lint #ifdef ISO -#include "../h/types.h" -#include "../h/socket.h" -#include "../h/socketvar.h" -#include "../h/domain.h" -#include "../h/mbuf.h" -#include "../h/errno.h" -#include "../h/time.h" +#include "param.h" +#include "socket.h" +#include "socketvar.h" +#include "domain.h" +#include "malloc.h" +#include "mbuf.h" +#include "errno.h" +#include "time.h" +#include "protosw.h" + #include "../net/if.h" #include "../net/route.h" -#include "../h/protosw.h" -#include "../netiso/tp_param.h" -#include "../netiso/argo_debug.h" -#include "../netiso/tp_stat.h" -#include "../netiso/tp_pcb.h" -#include "../netiso/tp_trace.h" -#include "../netiso/tp_stat.h" -#include "../netiso/tp_tpdu.h" -#include "../netiso/tp_clnp.h" +#include "argo_debug.h" +#include "tp_param.h" +#include "tp_stat.h" +#include "tp_pcb.h" +#include "tp_trace.h" +#include "tp_stat.h" +#include "tp_tpdu.h" +#include "tp_clnp.h" /* * CALLED FROM: * pr_usrreq() on PRU_BIND, PRU_CONNECT, PRU_ACCEPT, and PRU_PEERADDR - * FUNCTION, ARGUMENTS, and RETURN VALUE: - * Return a transport suffix from an isopcb structure (inp). - * (CAST TO AN INT) + * FUNCTION, ARGUMENTS: * The argument (which) takes the value TP_LOCAL or TP_FOREIGN. */ -short -iso_getsufx(isop, which) +iso_getsufx(isop, lenp, data_out, which) struct isopcb *isop; + u_short *lenp; + caddr_t data_out; int which; { + register struct sockaddr_iso *addr = 0; + switch (which) { case TP_LOCAL: - return htons(isop->isop_laddr.siso_tsuffix); + addr = isop->isop_laddr; + break; case TP_FOREIGN: - return htons(isop->isop_faddr.siso_tsuffix); + addr = isop->isop_faddr; } + if (addr) + bcopy(TSEL(addr), data_out, (*lenp = addr->siso_tsuffixlen)); } /* CALLED FROM: @@ -106,19 +112,51 @@ iso_getsufx(isop, which) * The argument (which) takes the value TP_LOCAL or TP_FOREIGN. */ void -iso_putsufx(isop, name, which) +iso_putsufx(isop, sufxloc, sufxlen, which) struct isopcb *isop; - struct sockaddr_iso *name; - int which; + caddr_t sufxloc; + int sufxlen, which; { + struct sockaddr_iso **dst, *backup; + register struct sockaddr_iso *addr; + struct mbuf *m; + int len; + switch (which) { + default: + return; + case TP_LOCAL: - isop->isop_lport = ntohs(name->siso_tsuffix); + dst = &isop->isop_laddr; + backup = &isop->isop_sladdr; break; + case TP_FOREIGN: - isop->isop_fport = ntohs(name->siso_tsuffix); - break; + dst = &isop->isop_faddr; + backup = &isop->isop_sfaddr; + } + if ((addr = *dst) == 0) { + addr = *dst = backup; + addr->siso_nlen = 0; + addr->siso_ssuffixlen = 0; + printf("iso_putsufx on un-initialized isopcb\n"); } + len = sufxlen + addr->siso_nlen + + (sizeof(struct sockaddr_iso) - sizeof(struct iso_addr)); + if (addr == backup) { + if (len > sizeof(isop->isop_sladdr)) { + m = m_getclr(M_DONTWAIT, MT_SONAME); + if (m == 0) + return; + addr = *dst = mtod(m, struct sockaddr_iso *); + *addr = *backup; + m->m_len = len; + } + } else + dtom(addr)->m_len = len; + bcopy(sufxloc, TSEL(addr), sufxlen); + addr->siso_tsuffixlen = sufxlen; + addr->siso_len = len; } /* @@ -136,7 +174,7 @@ void iso_recycle_tsuffix(isop) struct isopcb *isop; { - isop->isop_laddr.siso_tsuffix = isop->isop_faddr.siso_tsuffix = 0; + isop->isop_laddr->siso_tsuffixlen = isop->isop_faddr->siso_tsuffixlen = 0; } /* @@ -155,27 +193,24 @@ iso_putnetaddr(isop, name, which) struct sockaddr_iso *name; int which; { + struct sockaddr_iso **sisop, *backup; + register struct sockaddr_iso *siso; + switch (which) { case TP_LOCAL: - isop->isop_laddr.siso_family = AF_ISO; - bcopy((caddr_t)&name->siso_addr, - (caddr_t)&isop->isop_laddr.siso_addr, sizeof(struct iso_addr)); - IFDEBUG(D_TPISO) - printf("PUT TP_LOCAL addr\n"); - dump_isoaddr(&isop->isop_laddr); - ENDDEBUG + sisop = &isop->isop_laddr; + backup = &isop->isop_sladdr; break; case TP_FOREIGN: - isop->isop_faddr.siso_family = AF_ISO; - if( name != (struct sockaddr_iso *)0 ) { - bcopy((caddr_t)&name->siso_addr, - (caddr_t)&isop->isop_faddr.siso_addr, sizeof(struct iso_addr)); - } - IFDEBUG(D_TPISO) - printf("PUT TP_FOREIGN addr\n"); - dump_isoaddr(&isop->isop_faddr); - ENDDEBUG + sisop = &isop->isop_faddr; + backup = &isop->isop_sfaddr; } + siso = ((*sisop == 0) ? (*sisop = backup) : *sisop); + IFDEBUG(D_TPISO) + printf("ISO_PUTNETADDR\n"); + dump_isoaddr(isop->isop_faddr); + ENDDEBUG + siso->siso_addr = name->siso_addr; } /* @@ -190,20 +225,16 @@ iso_putnetaddr(isop, name, which) void iso_getnetaddr( isop, name, which) struct isopcb *isop; - struct sockaddr_iso *name; + struct mbuf *name; int which; { - switch (which) { - case TP_LOCAL: - bcopy( (caddr_t)&isop->isop_laddr.siso_addr, - (caddr_t)&name->siso_addr, sizeof(struct iso_addr)); - break; - - case TP_FOREIGN: - bcopy( (caddr_t)&isop->isop_faddr.siso_addr, - (caddr_t)&name->siso_addr, sizeof(struct iso_addr)); - break; - } + struct sockaddr_iso *siso = + (which == TP_LOCAL ? isop->isop_laddr : isop->isop_faddr); + if (siso) + bcopy((caddr_t)siso, mtod(name, caddr_t), + (unsigned)(name->m_len = siso->siso_len)); + else + name->m_len = 0; } /* @@ -236,12 +267,13 @@ tpclnp_mtu(so, isop, size, negot ) u_char *negot; { struct ifnet *ifp; + struct iso_ifaddr *ia; register int i; int windowsize = so->so_rcv.sb_hiwat; int clnp_size; int sizeismtu = 0; - struct ifnet *iso_routeifp(); + struct iso_ifaddr *iso_routeifa(); IFDEBUG(D_CONN) printf("tpclnp_mtu(0x%x,0x%x,0x%x,0x%x)\n", so, isop, size, negot); @@ -256,35 +288,36 @@ tpclnp_mtu(so, isop, size, negot ) *size = windowsize; } - if ((ifp = iso_routeifp(&isop->isop_faddr)) == (struct ifnet *)0) + if (((ia = iso_routeifa(isop->isop_faddr)) == 0) + || (ifp = ia->ia_ifp) == 0) return; /* TODO - make this indirect off the socket structure to the * network layer to get headersize */ - clnp_size = clnp_hdrsize(isop->isop_laddr.siso_addr.isoa_len); + if (isop->isop_laddr) + clnp_size = clnp_hdrsize(isop->isop_laddr->siso_addr.isoa_len); + else + clnp_size = 20; if(*size > ifp->if_mtu - clnp_size) { *size = ifp->if_mtu - clnp_size; sizeismtu = 1; } - IFTRACE(D_CONN) - tptrace(TPPTmisc, "GET MTU MID: tpcb size negot i \n", - *size, *negot, i, 0); - ENDTRACE - /* have to transform size to the log2 of size */ for(i=TP_MIN_TPDUSIZE; (iisop_faddr); - * or something along those lines - */ - if ( iso_netmatch(&isop->isop_laddr, &isop->isop_faddr) && sizeismtu ) { + if (iso_localifa(isop->isop_faddr)) { i++; } else { *size = 1<tpdu_li, (int)hdr->tpdu_type, nochksum); - dump_isoaddr(&isop->isop_faddr); + dump_isoaddr(isop->isop_faddr); printf("\nsrc addr:\n"); - dump_isoaddr(&isop->isop_laddr); + dump_isoaddr(isop->isop_laddr); dump_mbuf(m0, "at tpclnp_output"); ENDDEBUG + if ((m->m_flags & M_PKTHDR) == 0) { + IFDEBUG(D_TPISO) + printf("tpclnp_output: non headered mbuf"); + ENDDEBUG + MGETHDR(m, M_DONTWAIT, MT_DATA); + if (m == 0) { + m_freem(m0); + return ENOBUFS; + } + m->m_next = m0; + m->m_len = 0; + m->m_pkthdr.len = datalen; + m0 = m; + } return - clnp_output(m0, isop, datalen, nochksum?CLNP_NO_CKSUM:0 /* flags */); + clnp_output(m0, isop, /* flags */nochksum ? CLNP_NO_CKSUM : 0); } /* @@ -362,9 +410,9 @@ tpclnp_output_dg(laddr, faddr, m0, datalen, ro, nochksum) int nochksum; { struct isopcb tmppcb; - struct iso_addr *isoa; int err; int flags; + register struct mbuf *m = m0; IFDEBUG(D_TPISO) printf("tpclnp_output_dg datalen 0x%x m0 0x%x\n", datalen, m0); @@ -375,16 +423,16 @@ tpclnp_output_dg(laddr, faddr, m0, datalen, ro, nochksum) * packet. */ bzero((caddr_t)&tmppcb, sizeof(tmppcb)); - isoa = &(tmppcb.isop_laddr.siso_addr); - bcopy((caddr_t)laddr, (caddr_t)isoa, sizeof (struct iso_addr)); - isoa = &(tmppcb.isop_faddr.siso_addr); - bcopy((caddr_t)faddr, (caddr_t)isoa, sizeof (struct iso_addr)); + tmppcb.isop_laddr = &tmppcb.isop_sladdr; + tmppcb.isop_laddr->siso_addr = *laddr; + tmppcb.isop_faddr = &tmppcb.isop_sfaddr; + tmppcb.isop_faddr->siso_addr = *faddr; IFDEBUG(D_TPISO) printf("tpclnp_output_dg faddr: \n"); - dump_isoaddr(&tmppcb.isop_faddr); + dump_isoaddr(&tmppcb.isop_sfaddr); printf("\ntpclnp_output_dg laddr: \n"); - dump_isoaddr(&tmppcb.isop_laddr); + dump_isoaddr(&tmppcb.isop_sladdr); printf("\n"); ENDDEBUG @@ -395,7 +443,19 @@ tpclnp_output_dg(laddr, faddr, m0, datalen, ro, nochksum) IncStat(ts_tpdu_sent); - err = clnp_output(m0, &tmppcb, datalen, flags); + if ((m->m_flags & M_PKTHDR) == 0) { + printf("tpclnp_output: non headered mbuf"); + MGETHDR(m, M_DONTWAIT, MT_DATA); + if (m == 0) { + m_freem(m0); + return ENOBUFS; + } + m->m_next = m0; + m->m_len = 0; + m->m_pkthdr.len = datalen; + m0 = m; + } + err = clnp_output(m0, &tmppcb, flags); /* * Free route allocated by clnp (if the route was indeed allocated) @@ -405,7 +465,7 @@ tpclnp_output_dg(laddr, faddr, m0, datalen, ro, nochksum) return(err); } - +extern struct sockaddr_iso blank_siso; /* * CALLED FROM: * clnp's input routine, indirectly through the protosw. @@ -421,6 +481,7 @@ tpclnp_input(m, faddr, laddr, clnp_len) { struct sockaddr_iso src, dst; int s = splnet(); + struct mbuf *tp_inputprep(); IncStat(ts_pkt_rcvd); @@ -436,17 +497,17 @@ tpclnp_input(m, faddr, laddr, clnp_len) */ m->m_len -= clnp_len; - m->m_off += clnp_len; + m->m_data += clnp_len; - m = (struct mbuf *)tp_inputprep(m); + m = tp_inputprep(m); IFDEBUG(D_TPINPUT) dump_mbuf(m, "after tpclnp_input both pullups"); ENDDEBUG - src.siso_family = dst.siso_family = AF_ISO; - bcopy(faddr, &src.siso_addr, sizeof(struct iso_addr)); - bcopy(laddr, &dst.siso_addr, sizeof(struct iso_addr)); + src = blank_siso; dst = blank_siso; + bcopy((caddr_t)faddr, (caddr_t)&src.siso_addr, 1 + faddr->isoa_len); + bcopy((caddr_t)laddr, (caddr_t)&dst.siso_addr, 1 + laddr->isoa_len); IFDEBUG(D_TPISO) printf("calling tp_input: &src 0x%x &dst 0x%x, src addr:\n", @@ -456,7 +517,8 @@ tpclnp_input(m, faddr, laddr, clnp_len) dump_isoaddr(&dst); ENDDEBUG - (void) tp_input(m, &src, &dst, 0, tpclnp_output_dg); + (void) tp_input(m, (struct sockaddr *)&src, (struct sockaddr *)&dst, + 0, tpclnp_output_dg); IFDEBUG(D_QUENCH) { @@ -474,19 +536,6 @@ tpclnp_input(m, faddr, laddr, clnp_len) splx(s); return 0; - -discard: - IFDEBUG(D_TPINPUT) - printf("tpclnp_input DISCARD\n"); - ENDDEBUG - IFTRACE(D_TPINPUT) - tptrace(TPPTmisc, "tpclnp_input DISCARD m", m,0,0,0); - ENDTRACE - m_freem(m); - IncStat(ts_recv_drop); - splx(s); - - return 0; } ProtoHook @@ -505,7 +554,7 @@ void tpiso_decbit(isop) struct isopcb *isop; { - tp_quench( isop->isop_socket->so_tpcb, PRC_QUENCH2 ); + tp_quench((struct tp_pcb *)isop->isop_socket->so_tpcb, PRC_QUENCH2); } /* * CALLED FROM: @@ -517,7 +566,7 @@ void tpiso_quench(isop) struct isopcb *isop; { - tp_quench( isop->isop_socket->so_tpcb, PRC_QUENCH ); + tp_quench((struct tp_pcb *)isop->isop_socket->so_tpcb, PRC_QUENCH); } /* @@ -535,16 +584,27 @@ ProtoHook tpclnp_ctlinput(cmd, siso) int cmd; struct sockaddr_iso *siso; +{ + return tpclnp_ctlinput1(cmd, &siso->siso_addr); +} + +/* + * Entry to ctlinput with argument of an iso_addr rather than a sockaddr + */ +ProtoHook +tpclnp_ctlinput1(cmd, isoa) + int cmd; + struct iso_addr *isoa; { extern u_char inetctlerrmap[]; extern ProtoHook tpiso_abort(); extern ProtoHook iso_rtchange(); extern ProtoHook tpiso_reset(); + void iso_pcbnotify(); IFDEBUG(D_TPINPUT) - printf("tpclnp_ctlinput: cmd 0x%x addr: ", cmd); - dump_isoaddr(siso); - printf("\n"); + printf("tpclnp_ctlinput1: cmd 0x%x addr: %s\n", cmd, + clnp_iso_addrp(isoa)); ENDDEBUG if (cmd < 0 || cmd > PRC_NCMDS) @@ -552,23 +612,23 @@ tpclnp_ctlinput(cmd, siso) switch (cmd) { case PRC_QUENCH2: - iso_pcbnotify(&tp_isopcb, &siso->siso_addr, 0, tpiso_decbit); + iso_pcbnotify(&tp_isopcb, isoa, 0, (int (*)())tpiso_decbit); break; case PRC_QUENCH: - iso_pcbnotify(&tp_isopcb, &siso->siso_addr, 0, tpiso_quench); + iso_pcbnotify(&tp_isopcb, isoa, 0, (int (*)())tpiso_quench); break; case PRC_TIMXCEED_REASS: case PRC_ROUTEDEAD: - iso_pcbnotify(&tp_isopcb, &siso->siso_addr, 0, tpiso_reset); + iso_pcbnotify(&tp_isopcb, isoa, 0, tpiso_reset); break; case PRC_HOSTUNREACH: case PRC_UNREACH_NET: case PRC_IFDOWN: case PRC_HOSTDEAD: - iso_pcbnotify(&tp_isopcb, &siso->siso_addr, + iso_pcbnotify(&tp_isopcb, isoa, (int)inetctlerrmap[cmd], iso_rtchange); break; @@ -587,8 +647,7 @@ tpclnp_ctlinput(cmd, siso) case PRC_TIMXCEED_INTRANS: case PRC_PARAMPROB: */ - iso_pcbnotify(&tp_isopcb, &siso->siso_addr, - (int)inetctlerrmap[cmd], tpiso_abort); + iso_pcbnotify(&tp_isopcb, isoa, (int)inetctlerrmap[cmd], tpiso_abort); break; } return 0; diff --git a/usr/src/sys/netiso/tp_meas.c b/usr/src/sys/netiso/tp_meas.c index 6b51d67881..a7cb277c84 100644 --- a/usr/src/sys/netiso/tp_meas.c +++ b/usr/src/sys/netiso/tp_meas.c @@ -38,7 +38,8 @@ static char *rcsid = "$Header: tp_meas.c,v 5.2 88/11/18 17:28:04 nhall Exp $"; #include "types.h" #include "time.h" -#include "../netiso/tp_meas.h" +#include "argo_debug.h" +#include "tp_meas.h" extern struct timeval time; @@ -66,7 +67,7 @@ struct tp_Meas tp_Meas[TPMEASN]; * NOTES: */ void -tpmeas(ref, kind, timev, seq, win, size) +Tpmeas(ref, kind, timev, seq, win, size) u_int ref; u_int kind; struct timeval *timev; diff --git a/usr/src/sys/netiso/tp_meas.h b/usr/src/sys/netiso/tp_meas.h index 8bb635e6d8..87ba7fbd6e 100644 --- a/usr/src/sys/netiso/tp_meas.h +++ b/usr/src/sys/netiso/tp_meas.h @@ -24,6 +24,11 @@ SOFTWARE. /* * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison */ +#ifdef TPPT +#define TP_PERF_MEAS +#endif TPPT +#define tpmeas(a, b, t, c, d, e) \ + Tpmeas((u_int)(a), (u_int)(b), t, (u_int)(c), (u_int)(d), (u_int)(e)) #ifdef TP_PERF_MEAS struct tp_Meas { diff --git a/usr/src/sys/netiso/tp_output.c b/usr/src/sys/netiso/tp_output.c index 971b270698..e500545268 100644 --- a/usr/src/sys/netiso/tp_output.c +++ b/usr/src/sys/netiso/tp_output.c @@ -46,14 +46,14 @@ static char *rcsid = "$Header: tp_output.c,v 5.4 88/11/18 17:28:08 nhall Exp $"; #include "errno.h" #include "types.h" #include "time.h" -#include "../netiso/tp_param.h" -#include "../netiso/tp_user.h" -#include "../netiso/tp_stat.h" -#include "../netiso/tp_ip.h" -#include "../netiso/tp_timer.h" -#include "../netiso/argo_debug.h" -#include "../netiso/tp_pcb.h" -#include "../netiso/tp_trace.h" +#include "tp_param.h" +#include "tp_user.h" +#include "tp_stat.h" +#include "tp_ip.h" +#include "tp_timer.h" +#include "argo_debug.h" +#include "tp_pcb.h" +#include "tp_trace.h" #define USERFLAGSMASK_G 0x0f00643b #define USERFLAGSMASK_S 0x0f000432 @@ -154,7 +154,8 @@ tp_consistency( tpcb, cmd, param ) error = EINVAL; goto done; } else { if( tpcb->tp_state == TP_CLOSED ) - soreserve(tpcb->tp_sock, param->p_winsize, param->p_winsize); + soreserve(tpcb->tp_sock, (u_long)param->p_winsize, + (u_long)param->p_winsize); } IFDEBUG(D_SETPARAMS) printf("use_csum 0x%x\n", param->p_use_checksum ); @@ -197,14 +198,12 @@ tp_consistency( tpcb, cmd, param ) } /* connect/disc data not allowed for class 0 */ - if ( tpcb->tp_flags & - (TPF_CONN_DATA_OUT | TPF_DISC_DATA_OUT) ) { + if (tpcb->tp_ucddata) { if(cmd & TP_STRICT) { error = EINVAL; } else if(cmd & TP_FORCE) { - sbdrop(&tpcb->tp_sock->so_snd, tpcb->tp_sock->so_snd.sb_cc); - tpcb->tp_flags &= - ~(TPF_CONN_DATA_OUT | TPF_DISC_DATA_OUT); + m_freem(tpcb->tp_ucddata); + tpcb->tp_ucddata = 0; } } break; @@ -335,8 +334,8 @@ tp_ctloutput(cmd, so, level, optname, mp) { struct tp_pcb *tpcb = sototpcb(so); int s = splnet(); - u_char *value; - int val_len; + caddr_t value; + unsigned val_len; int error = 0; IFTRACE(D_REQUEST) @@ -412,9 +411,9 @@ tp_ctloutput(cmd, so, level, optname, mp) } } - value = (u_char *) mtod(*mp, u_char *); /* it's aligned, don't worry, - * but lint complains about it - */ + value = mtod(*mp, caddr_t); /* it's aligned, don't worry, + * but lint complains about it + */ val_len = (*mp)->m_len; switch (optname) { @@ -422,14 +421,14 @@ tp_ctloutput(cmd, so, level, optname, mp) case TPOPT_MY_TSEL: if ( cmd == PRCO_GETOPT ) { ASSERT( tpcb->tp_lsuffixlen <= MAX_TSAP_SEL_LEN ); - bcopy( tpcb->tp_lsuffix, value, tpcb->tp_lsuffixlen); + bcopy((caddr_t)tpcb->tp_lsuffix, value, tpcb->tp_lsuffixlen); (*mp)->m_len = tpcb->tp_lsuffixlen; } else /* cmd == PRCO_SETOPT */ { if( (val_len > MAX_TSAP_SEL_LEN) || (val_len <= 0 )) { printf("val_len 0x%x (*mp)->m_len 0x%x\n", val_len, (*mp)); error = EINVAL; } else { - bcopy( value, tpcb->tp_lsuffix, val_len ); + bcopy(value, (caddr_t)tpcb->tp_lsuffix, val_len); tpcb->tp_lsuffixlen = val_len; } } @@ -438,14 +437,14 @@ tp_ctloutput(cmd, so, level, optname, mp) case TPOPT_PEER_TSEL: if ( cmd == PRCO_GETOPT ) { ASSERT( tpcb->tp_fsuffixlen <= MAX_TSAP_SEL_LEN ); - bcopy( tpcb->tp_fsuffix, value, tpcb->tp_fsuffixlen); + bcopy((caddr_t)tpcb->tp_fsuffix, value, tpcb->tp_fsuffixlen); (*mp)->m_len = tpcb->tp_fsuffixlen; } else /* cmd == PRCO_SETOPT */ { if( (val_len > MAX_TSAP_SEL_LEN) || (val_len <= 0 )) { printf("val_len 0x%x (*mp)->m_len 0x%x\n", val_len, (*mp)); error = EINVAL; } else { - bcopy( value, tpcb->tp_fsuffix, val_len ); + bcopy(value, (caddr_t)tpcb->tp_fsuffix, val_len); tpcb->tp_fsuffixlen = val_len; } } @@ -506,10 +505,14 @@ tp_ctloutput(cmd, so, level, optname, mp) error = EINVAL; goto done; } IFPERF(tpcb) - /* tp_p_meas is a cluster : "copy" it */ - mclrefcnt[mtocl( (tpcb->tp_p_meas) )]++; - (*mp)->m_off = (u_long)((int)tpcb->tp_p_meas - (int)(*mp)); - (*mp)->m_len = sizeof(struct tp_pmeas); + if (*mp) { + struct mbuf * n; + do { + MFREE(*mp, n); + *mp = n; + } while (n); + } + *mp = m_copym(tpcb->tp_p_mbuf, (int)M_COPYALL, M_WAITOK); ENDPERF else { error = EINVAL; goto done; @@ -524,9 +527,9 @@ tp_ctloutput(cmd, so, level, optname, mp) if (cmd == PRCO_GETOPT) { error = EINVAL; } else { - if ( tpcb->tp_flags & (TPF_CONN_DATA_OUT | TPF_DISC_DATA_OUT) ) { - sbdrop(&so->so_snd, so->so_snd.sb_cc); - tpcb->tp_flags &= ~(TPF_CONN_DATA_OUT | TPF_DISC_DATA_OUT); + if (tpcb->tp_ucddata) { + m_freem(tpcb->tp_ucddata); + tpcb->tp_ucddata = 0; } } break; @@ -553,63 +556,28 @@ tp_ctloutput(cmd, so, level, optname, mp) printf("m_len 0x%x, vallen 0x%x so_snd.cc 0x%x\n", (*mp)->m_len, val_len, so->so_snd.sb_cc); dump_mbuf(so->so_snd.sb_mb, "tp_ctloutput: sosnd "); - dump_mbuf(tpcb->tp_Xrcv.sb_mb, "tp_ctlout: tpXrcv "); ENDDEBUG if (cmd == PRCO_SETOPT) { + int len = tpcb->tp_ucddata ? tpcb->tp_ucddata->m_len : 0; /* can append connect data in several calls */ - if (so->so_snd.sb_cc + val_len > + if (len + val_len > (optname==TPOPT_CONN_DATA?TP_MAX_CR_DATA:TP_MAX_DR_DATA) ) { error = EMSGSIZE; goto done; } - tpcb->tp_flags |= - ((optname==TPOPT_CONN_DATA)?TPF_CONN_DATA_OUT:TPF_DISC_DATA_OUT); (*mp)->m_next = MNULL; (*mp)->m_act = 0; - sbappendrecord( &so->so_snd, *mp); + if (tpcb->tp_ucddata) + m_cat(tpcb->tp_ucddata, *mp); + else + tpcb->tp_ucddata = *mp; IFDEBUG(D_REQUEST) - dump_mbuf(so->so_snd.sb_mb, "tp_ctloutput after sbappendrecord"); + dump_mbuf(tpcb->tp_ucddata, "tp_ctloutput after CONN_DATA"); ENDDEBUG IFTRACE(D_REQUEST) tptrace(TPPTmisc,"C/D DATA: flags snd.sbcc val_len", tpcb->tp_flags, so->so_snd.sb_cc,val_len,0); ENDTRACE *mp = MNULL; /* prevent sosetopt from freeing it! */ - } else /* cmd == PRCO_GETOPT */ { - register int len = tpcb->tp_Xrcv.sb_cc; - - /* getsockopt() allocated an mbuf but it's a whole lot easier - * to do an m_copy than to explicitly copy from the socket buf - * into the buffer provided by getsockopt() - */ - IFDEBUG(D_REQUEST) - dump_mbuf(tpcb->tp_Xrcv.sb_mb, - "tp_ctlout: tpXrcv before sbdrop"); - ENDDEBUG - if(len) { - (void) m_freem(*mp); - *mp = m_copy( tpcb->tp_Xrcv.sb_mb, 0, len); - if( *mp != MNULL ) { - (*mp)->m_act = 0; - sbdrop( &tpcb->tp_Xrcv, len); - } else { - error = ENOBUFS; - } - } else { - (*mp)->m_len = 0; - } - IFDEBUG(D_REQUEST) - dump_mbuf(tpcb->tp_Xrcv.sb_mb, - "tp_ctlout: tpXrcv after sbdrop"); - ENDDEBUG - /* a potential problem here is that REAL expedited may have arrived - * after the data-on-connect - * however, this presently works because incoming XPD_TPDUs are - * dropped if tp_Xrcv.sb_cc != 0 - */ - - if( tpcb->tp_Xrcv.sb_cc == 0) - tpcb->tp_flags &= - optname == TPOPT_CONN_DATA?~TPF_CONN_DATA_IN:~TPF_DISC_DATA_IN; } break; diff --git a/usr/src/sys/netiso/tp_param.h b/usr/src/sys/netiso/tp_param.h index 9a186bb6e0..41d425b30f 100644 --- a/usr/src/sys/netiso/tp_param.h +++ b/usr/src/sys/netiso/tp_param.h @@ -46,8 +46,8 @@ SOFTWARE. #define N_TPREF 100 -#define TP_SOCKBUFSIZE 4096 -#define TP0_SOCKBUFSIZE 512 +#define TP_SOCKBUFSIZE ((u_long)4096) +#define TP0_SOCKBUFSIZE ((u_long)512) #define MAX_TSAP_SEL_LEN 64 /* maximum tpdu size we'll accept: */ @@ -284,7 +284,7 @@ bcopy((caddr_t)&(((struct tp_vbp *)(src))->tpv_val),(caddr_t)&(dst),sizeof(type) P = (caddr_t)(DU) + (int)((DU)->tpdu_li);\ vbptr(P)->tpv_code = type;\ vbptr(P)->tpv_len = len;\ - bcopy((caddr_t)&src, (caddr_t)&(vbptr(P)->tpv_val), (int)len);\ + bcopy((caddr_t)&src, (caddr_t)&(vbptr(P)->tpv_val), (unsigned)len);\ DU->tpdu_li += len+2;/* 1 for code, 1 for length */\ } /****************************************************** diff --git a/usr/src/sys/netiso/tp_pcb.c b/usr/src/sys/netiso/tp_pcb.c index 6d2a82ab59..5c823f45f8 100644 --- a/usr/src/sys/netiso/tp_pcb.c +++ b/usr/src/sys/netiso/tp_pcb.c @@ -56,17 +56,17 @@ static char *rcsid = "$Header: tp_pcb.c,v 5.4 88/11/18 17:28:24 nhall Exp $"; #include "protosw.h" #include "errno.h" #include "time.h" -#include "../netiso/tp_param.h" -#include "../netiso/tp_timer.h" -#include "../netiso/tp_ip.h" -#include "../netiso/tp_stat.h" -#include "../netiso/tp_pcb.h" -#include "../netiso/argo_debug.h" -#include "../netiso/tp_tpdu.h" -#include "../netiso/tp_trace.h" -#include "../netiso/tp_meas.h" -#include "../netiso/tp_seq.h" -#include "../netiso/tp_clnp.h" +#include "argo_debug.h" +#include "tp_param.h" +#include "tp_timer.h" +#include "tp_ip.h" +#include "tp_stat.h" +#include "tp_pcb.h" +#include "tp_tpdu.h" +#include "tp_trace.h" +#include "tp_meas.h" +#include "tp_seq.h" +#include "tp_clnp.h" /* list of reference structures */ struct tp_ref tp_ref[N_TPREF]; @@ -276,6 +276,7 @@ int tpcons_output_dg(); struct isopcb tp_isopcb; #endif NARGOXTWENTYFIVE + struct nl_protosw nl_protosw[] = { /* ISO_CLNS */ #ifdef ISO @@ -288,6 +289,8 @@ struct nl_protosw nl_protosw[] = { tpclnp_output, tpclnp_output_dg, iso_nlctloutput, (caddr_t) &tp_isopcb, }, +#else + { 0 }, #endif ISO /* IN_CLNS */ #ifdef INET @@ -300,10 +303,11 @@ struct nl_protosw nl_protosw[] = { tpip_output, tpip_output_dg, /* nl_ctloutput */ NULL, (caddr_t) &tp_inpcb, }, +#else + { 0 }, #endif INET /* ISO_CONS */ -#ifdef ISO -#if NARGOXTWENTYFIVE > 0 +#if defined(ISO) && (NARGOXTWENTYFIVE > 0) { AF_ISO, iso_putnetaddr, iso_getnetaddr, iso_putsufx, iso_getsufx, iso_recycle_tsuffix, @@ -313,17 +317,11 @@ struct nl_protosw nl_protosw[] = { tpcons_output, tpcons_output_dg, iso_nlctloutput, (caddr_t) &tp_isopcb, }, -#endif NARGOXTWENTYFIVE -#endif ISO - { 0, 0, 0, - 0, 0, - 0, - 0, 0, 0, - 0, 0, - 0, - 0, 0, 0, - (caddr_t) 0, - } +#else + { 0 }, +#endif ISO_CONS + /* End of protosw marker */ + { 0 } }; /* @@ -341,25 +339,15 @@ struct nl_protosw nl_protosw[] = { * * NOTES: */ -void +int tp_init() { static int init_done=0; void tp_timerinit(); if (init_done++) - return; + return 0; -#ifndef lint - if ( (sizeof(struct tp_pcb) >= MLEN) || (sizeof(struct tp_pcb_aux) >= MLEN) ){ - tp_param.tpp_configed = 0; - printf( - "TP not configured !!! pcb (0x%x, %d) or aux (0x%x, %d) too big!\n", - sizeof(struct tp_pcb), sizeof(struct tp_pcb), - sizeof(struct tp_pcb_aux), sizeof(struct tp_pcb_aux)); - printf("MLEN (0x%x, %d)\n", MLEN, MLEN); - } -#endif lint /* FOR INET */ tp_inpcb.inp_next = tp_inpcb.inp_prev = &tp_inpcb; @@ -368,6 +356,7 @@ tp_init() tp_timerinit(); bzero((caddr_t)&tp_stat, sizeof(struct tp_stat)); + return 0; } /* @@ -408,11 +397,10 @@ tp_soisdisconnecting(so) register struct tp_pcb *tpcb = sototpcb(so); u_int fsufx, lsufx; - bcopy ( tpcb->tp_fsuffix, &fsufx, sizeof(u_int) ); - bcopy ( tpcb->tp_lsuffix, &lsufx, sizeof(u_int) ); + bcopy ((caddr_t)tpcb->tp_fsuffix, (caddr_t)&fsufx, sizeof(u_int) ); + bcopy ((caddr_t)tpcb->tp_lsuffix, (caddr_t)&lsufx, sizeof(u_int) ); - tpmeas( tpcb->tp_lref, TPtime_close, - &time, fsufx, lsufx, tpcb->tp_fref); + tpmeas(tpcb->tp_lref, TPtime_close, &time, fsufx, lsufx, tpcb->tp_fref); tpcb->tp_perf_on = 0; /* turn perf off */ ENDPERF } @@ -457,15 +445,15 @@ tp_soisdisconnected(tpcb) sowwakeup(so); sorwakeup(so); IFPERF(sototpcb(so)) - register struct tp_pcb *tpcb = sototpcb(so); + register struct tp_pcb *ttpcb = sototpcb(so); u_int fsufx, lsufx; /* CHOKE */ - bcopy ( tpcb->tp_fsuffix, &fsufx, sizeof(u_int) ); - bcopy ( tpcb->tp_lsuffix, &lsufx, sizeof(u_int) ); + bcopy ((caddr_t)ttpcb->tp_fsuffix, (caddr_t)&fsufx, sizeof(u_int) ); + bcopy ((caddr_t)ttpcb->tp_lsuffix, (caddr_t)&lsufx, sizeof(u_int) ); - tpmeas( tpcb->tp_lref, TPtime_close, - &time, &lsufx, &fsufx, tpcb->tp_fref); + tpmeas(ttpcb->tp_lref, TPtime_close, + &time, &lsufx, &fsufx, ttpcb->tp_fref); tpcb->tp_perf_on = 0; /* turn perf off */ ENDPERF @@ -594,14 +582,11 @@ tp_getref(tpcb) * * NOTES: */ -int -tp_attach(so,dom) +tp_attach(so, dom) struct socket *so; int dom; { register struct tp_pcb *tpcb; - register struct mbuf *m; - register struct mbuf *p; int error; int protocol = so->so_proto->pr_protocol; extern struct tp_conn_param tp_conn_param[]; @@ -627,27 +612,13 @@ tp_attach(so,dom) if (error) goto bad2; - MGET(m, M_DONTWAIT, TPMT_PCB); /* for tpcb, main half */ - if (m == NULL) { + MALLOC(tpcb, struct tp_pcb *, sizeof(*tpcb), M_PCB, M_NOWAIT); + if (tpcb == NULL) { error = ENOBUFS; goto bad2; } - - tpcb = mtod( m, struct tp_pcb * ); bzero( (caddr_t)tpcb, sizeof (struct tp_pcb) ); - MGET(p, M_DONTWAIT, TPMT_PCB); /* for the tpcb, auxilliary half */ - if (p == NULL) { - error = ENOBUFS; - m_free(m); /* which is tpcb */ - goto bad2; - } else { - p->m_len = sizeof(struct tp_pcb_aux); - p->m_act = MNULL; - tpcb->tp_aux = mtod(p, struct tp_pcb_aux *); - bzero( (caddr_t)tpcb->tp_aux, sizeof (struct tp_pcb_aux) ); - } - if ( ((tpcb->tp_lref = tp_getref(tpcb)) & TP_ENOREF) != 0 ) { error = ETOOMANYREFS; goto bad3; @@ -732,8 +703,7 @@ bad3: printf("BAD3 in tp_attach, so 0x%x\n", so); ENDDEBUG - m_free(dtom(tpcb)); /* never a cluster */ - m_free(dtom(tpcb->tp_aux)); /* never a cluster */ + free((caddr_t)tpcb, M_PCB); /* never a cluster */ bad2: IFDEBUG(D_CONN) @@ -743,7 +713,7 @@ bad2: so->so_tpcb = 0; sofree(so); -bad: +/*bad:*/ IFDEBUG(D_CONN) printf("BAD in tp_attach, so 0x%x\n", so); ENDDEBUG @@ -781,8 +751,8 @@ tp_detach(tpcb) register struct socket *so = tpcb->tp_sock; IFDEBUG(D_CONN) - printf("tp_detach(tpcb 0x%x, so 0x%x) freelist 0%x\n", - tpcb,so, mfree); + printf("tp_detach(tpcb 0x%x, so 0x%x)\n", + tpcb,so); ENDDEBUG IFTRACE(D_CONN) tptraceTPCB(TPPTmisc, "tp_detach tpcb so lsufx", @@ -824,7 +794,7 @@ tp_detach(tpcb) so->so_q0len, so->so_qlen, so->so_qlimit); ENDDEBUG - if ( tpcb->tp_flags & (TPF_CONN_DATA_OUT | TPF_DISC_DATA_OUT ) ) { + if ( tpcb->tp_flags & (TPF_DISC_DATA_OUT | TPF_CONN_DATA_OUT ) ) { ASSERT( so->so_snd.sb_cc != 0 ); IFDEBUG(D_CONN) printf( @@ -833,7 +803,7 @@ tp_detach(tpcb) dump_mbuf( so->so_snd.sb_mb, "detach so snd: \n"); ENDDEBUG if ( so->so_snd.sb_cc != 0 ) - sbdrop( &so->so_snd, so->so_snd.sb_cc); + sbflush(&so->so_snd); tpcb->tp_flags &= ~(TPF_CONN_DATA_OUT | TPF_DISC_DATA_OUT); } if ( tpcb->tp_flags & (TPF_DISC_DATA_IN | TPF_CONN_DATA_IN ) ) { @@ -845,7 +815,7 @@ tp_detach(tpcb) dump_mbuf( tpcb->tp_Xrcv.sb_mb, "detach Xrcv: \n"); ENDDEBUG if( tpcb->tp_Xrcv.sb_cc != 0 ) - sbdrop( &tpcb->tp_Xrcv, tpcb->tp_Xrcv.sb_cc); + sbdrop(&tpcb->tp_Xrcv, (int)tpcb->tp_Xrcv.sb_cc); tpcb->tp_flags &= ~(TPF_CONN_DATA_IN | TPF_DISC_DATA_IN); } @@ -856,13 +826,11 @@ tp_detach(tpcb) tpcb->tp_nlproto, tpcb->tp_nlproto->nlp_pcbdetach); ENDDEBUG - if ((tpcb->tp_nlproto->nlp_pcbdetach) ( - (struct inpcb *)so->so_pcb) /* does an sofree(so) */ < 0 ) { -#ifdef ARGO_DEBUG - printf("tp: nl_detach failed: tpcb 0x%x so 0x%x\n", tpcb, so); -#endif ARGO_DEBUG - } + + (tpcb->tp_nlproto->nlp_pcbdetach)((struct inpcb *)so->so_pcb); + /* does an sofree(so) */ + IFDEBUG(D_CONN) printf("after xxx_pcbdetach\n"); ENDDEBUG @@ -877,6 +845,10 @@ tp_detach(tpcb) tp_freeref(tpcb->tp_refp); } + if (tpcb->tp_Xsnd.sb_mb) { + printf("Unsent Xdata on detach; would panic"); + sbflush(&tpcb->tp_Xsnd); + } so->so_tpcb = (caddr_t)0; /* @@ -887,27 +859,23 @@ tp_detach(tpcb) * of code, not the IFPERFs) */ #ifdef TP_PERF_MEAS - if( tpcb->tp_p_meas != (struct tp_pmeas *)0 ) { - register struct mbuf *n; - - n = MTOCL((struct mbuf *)(tpcb->tp_p_meas)); + if(tpcb->tp_p_mbuf) { + register struct mbuf *m = tpcb->tp_p_mbuf; + struct mbuf *n; IFDEBUG(D_PERF_MEAS) printf("freeing tp_p_meas 0x%x ", tpcb->tp_p_meas); - printf("n = 0x%x\n", n); ENDDEBUG - if (--mclrefcnt[mtocl(n)] == 0) { - n->m_next = mclfree; - mclfree = n; - mbstat.m_clfree++; - } + do { + MFREE(m, n); + m = n; + } while (n); + tpcb->tp_p_meas = 0; + tpcb->tp_p_mbuf = 0; } #endif TP_PERF_MEAS IFDEBUG(D_CONN) - printf( -"end of detach, NOT single, tpcb 0x%x, dtom(tpcb) 0x%x tp_aux 0x%x dtom(aux) 0x%x\n", - tpcb, dtom(tpcb), tpcb->tp_aux, dtom(tpcb->tp_aux)); + printf( "end of detach, NOT single, tpcb 0x%x\n", tpcb); ENDDEBUG - m_free(dtom(tpcb->tp_aux)); - m_free(dtom(tpcb)); + /* free((caddr_t)tpcb, M_PCB); WHere to put this ? */ } diff --git a/usr/src/sys/netiso/tp_pcb.h b/usr/src/sys/netiso/tp_pcb.h index 1ec6d7278d..9a794e1f90 100644 --- a/usr/src/sys/netiso/tp_pcb.h +++ b/usr/src/sys/netiso/tp_pcb.h @@ -121,46 +121,15 @@ struct nl_protosw { caddr_t nlp_pcblist; /* list of xx_pcb's for connections */ } nl_protosw[]; -struct tp_pcb_aux { - /* addressing */ - u_short tpa_domain; /* domain (INET, ISO) */ - /* for compatibility with the *old* way and with INET, be sure that - * that lsuffix and fsuffix are aligned to a short addr. - * having them follow the u_short *suffixlen should suffice (choke) - */ - u_short tpa_fsuffixlen; /* foreign suffix */ - u_char tpa_fsuffix[MAX_TSAP_SEL_LEN]; - u_short tpa_lsuffixlen; /* local suffix */ - u_char tpa_lsuffix[MAX_TSAP_SEL_LEN]; -#define SHORT_LSUFXP(tpcb) ((short *)((tpcb)->tp_aux->tpa_lsuffix)) -#define SHORT_FSUFXP(tpcb) ((short *)((tpcb)->tp_aux->tpa_fsuffix)) - - u_char tpa_vers; /* protocol version */ - u_char tpa_peer_acktime; /* used to compute DT retrans time */ - - struct sockbuf tpa_Xsnd; /* for expedited data */ - struct sockbuf tpa_Xrcv; /* for expedited data */ - SeqNum tpa_Xsndnxt; /* next XPD seq # to send */ - SeqNum tpa_Xuna; /* seq # of unacked XPD */ - SeqNum tpa_Xrcvnxt; /* next XPD seq # expect to recv */ - - /* AK subsequencing */ - u_short tpa_s_subseq; /* next subseq to send */ - u_short tpa_r_subseq; /* highest recv subseq */ - -}; struct tp_pcb { u_short tp_state; /* state of fsm */ short tp_retrans; /* # times can still retrans */ struct tp_ref *tp_refp; /* rest of pcb */ - struct tp_pcb_aux *tp_aux; /* second half of the tpcb */ caddr_t tp_npcb; /* to lower layer pcb */ struct nl_protosw *tp_nlproto; /* lower-layer dependent routines */ struct socket *tp_sock; /* back ptr */ -#define tp_Xsnd tp_aux->tpa_Xsnd -#define tp_Xrcv tp_aux->tpa_Xrcv RefNum tp_lref; /* local reference */ RefNum tp_fref; /* foreign reference */ @@ -169,9 +138,6 @@ struct tp_pcb { u_int tp_seqbit; /* bit for seq number wraparound */ u_int tp_seqhalf; /* half the seq space */ -#define tp_vers tp_aux->tpa_vers -#define tp_peer_acktime tp_aux->tpa_peer_acktime - /* credit & sequencing info for SENDING */ u_short tp_fcredit; /* current remote credit in # packets */ @@ -184,13 +150,12 @@ struct tp_pcb { * Minimizes the amount sent in a * regular tp_send() also. */ -#define tp_Xsndnxt tp_aux->tpa_Xsndnxt -#define tp_Xuna tp_aux->tpa_Xuna SeqNum tp_snduna; /* seq # of lowest unacked DT */ struct tp_rtc *tp_snduna_rtc; /* lowest unacked stuff sent so far */ SeqNum tp_sndhiwat; /* highest seq # sent so far */ struct tp_rtc *tp_sndhiwat_rtc; /* last stuff sent so far */ int tp_Nwindow; /* for perf. measurement */ + struct mbuf *tp_ucddata; /* user connect/disconnect data */ /* credit & sequencing info for RECEIVING */ SeqNum tp_sent_lcdt; /* cdt according to last ack sent */ @@ -201,12 +166,6 @@ struct tp_pcb { u_short tp_lcredit; /* current local credit in # packets */ SeqNum tp_rcvnxt; /* next DT seq # expect to recv */ struct tp_rtc *tp_rcvnxt_rtc; /* unacked stuff recvd out of order */ -#define tp_Xrcvnxt tp_aux->tpa_Xrcvnxt -#define tp_domain tp_aux->tpa_domain -#define tp_fsuffix tp_aux->tpa_fsuffix -#define tp_fsuffixlen tp_aux->tpa_fsuffixlen -#define tp_lsuffix tp_aux->tpa_lsuffix -#define tp_lsuffixlen tp_aux->tpa_lsuffixlen /* parameters per-connection controllable by user */ struct tp_conn_param _tp_param; @@ -267,29 +226,48 @@ struct tp_pcb { tp_unused:16; -#define tp_s_subseq tp_aux->tpa_s_subseq -#define tp_r_subseq tp_aux->tpa_r_subseq #ifdef TP_PERF_MEAS /* performance stats - see tp_stat.h */ - struct tp_pmeas *tp_p_meas; + struct tp_pmeas *tp_p_meas; + struct mbuf *tp_p_mbuf; #endif TP_PERF_MEAS + /* addressing */ + u_short tp_domain; /* domain (INET, ISO) */ + /* for compatibility with the *old* way and with INET, be sure that + * that lsuffix and fsuffix are aligned to a short addr. + * having them follow the u_short *suffixlen should suffice (choke) + */ + u_short tp_fsuffixlen; /* foreign suffix */ + char tp_fsuffix[MAX_TSAP_SEL_LEN]; + u_short tp_lsuffixlen; /* local suffix */ + char tp_lsuffix[MAX_TSAP_SEL_LEN]; +#define SHORT_LSUFXP(tpcb) ((short *)((tpcb)->tp_lsuffix)) +#define SHORT_FSUFXP(tpcb) ((short *)((tpcb)->tp_fsuffix)) + + u_char tp_vers; /* protocol version */ + u_char tp_peer_acktime; /* used to compute DT retrans time */ + + struct sockbuf tp_Xsnd; /* for expedited data */ +/* struct sockbuf tp_Xrcv; /* for expedited data */ +#define tp_Xrcv tp_sock->so_rcv + SeqNum tp_Xsndnxt; /* next XPD seq # to send */ + SeqNum tp_Xuna; /* seq # of unacked XPD */ + SeqNum tp_Xrcvnxt; /* next XPD seq # expect to recv */ + + /* AK subsequencing */ + u_short tp_s_subseq; /* next subseq to send */ + u_short tp_r_subseq; /* highest recv subseq */ + }; extern struct timeval time; extern struct tp_ref tp_ref[]; extern struct tp_param tp_param; -#ifdef lint -#define sototpcb(so) ((struct tp_pcb *)0) -#define sototpref(so) ((struct tp_ref *)0) -#define tpcbtoso(tp) ((struct socket *)0) -#define tpcbtoref(tp) ((struct tp_ref *)0) -#else #define sototpcb(so) ((struct tp_pcb *)(so->so_tpcb)) #define sototpref(so) ((struct tp_ref *)((so)->so_tpcb->tp_ref)) #define tpcbtoso(tp) ((struct socket *)((tp)->tp_sock)) #define tpcbtoref(tp) ((struct tp_ref *)((tp)->tp_ref)) -#endif #endif __TP_PCB__ diff --git a/usr/src/sys/netiso/tp_sizes.c b/usr/src/sys/netiso/tp_sizes.c index 82f46ecdbc..004a6558df 100644 --- a/usr/src/sys/netiso/tp_sizes.c +++ b/usr/src/sys/netiso/tp_sizes.c @@ -1,4 +1,4 @@ -/*********************************************************** +/************************************************************ Copyright IBM Corporation 1987 All Rights Reserved @@ -29,7 +29,7 @@ SOFTWARE. #define MERGED #define IBMRTPC #define CLNPECHO -#define TP_PERF_MEAS +/* #define TP_PERF_MEAS */ #define CONS #define TPPT #define ARGO_TP @@ -75,103 +75,49 @@ static char *rcsid = "$Header: tp_sizes.c,v 5.1 88/10/12 12:21:03 root Exp $"; #include "protosw.h" #include "errno.h" #include "time.h" -#include "../netiso/tp_param.h" -#include "../netiso/tp_timer.h" -#include "../netiso/tp_ip.h" -#include "../netiso/tp_stat.h" -#include "../netiso/tp_pcb.h" -#include "../netiso/tp_tpdu.h" -#include "../netiso/tp_trace.h" -#include "../netiso/tp_meas.h" -#include "../netiso/tp_seq.h" -#include "../netiso/tp_clnp.h" - -#include "../netiso/iso_errno.h" -#include "../netiso/cons.h" -#include "../netiso/cons_pcb.h" - +#include "tp_param.h" +#include "tp_timer.h" +#include "tp_ip.h" +#include "tp_stat.h" +#include "tp_pcb.h" +#include "tp_tpdu.h" +#include "tp_trace.h" +#include "tp_meas.h" +#include "tp_seq.h" +#include "tp_clnp.h" + +#include "iso_errno.h" +#include "cons.h" +#undef IncStat +#include "cons_pcb.h" + +#define DUP(x) x, x +#define SIZE(P) printf("Size of %s: 0x%x %d\n", "P", DUP(sizeof(struct P))) +#define OFF(P, Q) printf("\toffset of %s in %s: 0x%x %d\n", "P", "Q", \ + DUP(_offsetof(struct Q, P))) main() { printf( "TP struct sizes:\n"); - printf( "tpcb 0x%x %d\n", sizeof(struct tp_pcb), sizeof(struct tp_pcb)); - printf( "aux 0x%x %d\n", - sizeof(struct tp_pcb_aux), sizeof(struct tp_pcb_aux)); - printf( "ref 0x%x %d\n", sizeof(struct tp_ref), sizeof(struct tp_ref)); - printf( "tp_stat 0x%x %d\n", - sizeof(struct tp_stat), sizeof(struct tp_stat)); - printf( "tp_param 0x%x %d\n", - sizeof(struct tp_param), sizeof(struct tp_param)); - printf( "tp_conn_param 0x%x %d\n", - sizeof(struct tp_conn_param), sizeof(struct tp_conn_param)); - printf( "tp_rtc 0x%x %d\n", - sizeof(struct tp_rtc), sizeof(struct tp_rtc)); - printf( "nl_protosw 0x%x %d\n", - sizeof(struct nl_protosw), sizeof(struct nl_protosw)); - + SIZE(tp_pcb); +#define O(y) OFF(tp_/**/y,tp_pcb); + O(state) O(retrans) O(snduna) + O(lref) O(fref) O(fsuffix) + O(fsuffixlen) O(lsuffix) O(lsuffixlen) + O(Xsnd) O(Xuna) + SIZE(tp_ref); OFF(tpr_pcb,tp_ref);OFF(tpr_calltodo,tp_ref); + SIZE(tp_stat); SIZE(tp_param); + SIZE(tp_conn_param); SIZE(tp_rtc); SIZE(nl_protosw); #ifdef TP_PERF_MEAS - printf( "\tpmeas 0x%x %d\n", sizeof(struct tp_pmeas), - sizeof(struct tp_pmeas)); -#else - printf("perf meas NOT configured\n"); -#endif TP_PERF_MEAS - + SIZE(tp_Meas); +#endif printf( "ISO struct sizes:\n"); - printf( "socket 0x%x %d\n", - sizeof(struct socket), sizeof(struct socket)); - printf( "\t offset of so_timeo 0x%x %d\n", - _offsetof( struct socket, so_timeo ), - _offsetof( struct socket, so_timeo )); - printf( "\t offset of so_rcv 0x%x %d\n", - _offsetof( struct socket, so_rcv ), - _offsetof( struct socket, so_rcv )); - printf( "\t offset of so_snd 0x%x %d\n", - _offsetof( struct socket, so_snd ), - _offsetof( struct socket, so_snd )); - printf( "\t offset of sb_flags in sockbuf 0x%x %d\n", - _offsetof( struct sockbuf, sb_flags ), - _offsetof( struct sockbuf, sb_flags )); - printf( "\t offset of sb_cc in sockbuf 0x%x %d\n", - _offsetof( struct sockbuf, sb_cc ), - _offsetof( struct sockbuf, sb_cc )); - printf( "\t offset of so_qlen in sockbuf 0x%x %d\n", - _offsetof( struct socket, so_qlen ), - _offsetof( struct socket, so_qlen )); - printf( "\t offset of so_error in sockbuf 0x%x %d\n", - _offsetof( struct socket, so_error ), - _offsetof( struct socket, so_error )); - printf( "\t offset of so_state in sockbuf 0x%x %d\n", - _offsetof( struct socket, so_state ), - _offsetof( struct socket, so_state )); - - printf( "SIZE OF isopcb 0x%x %d\n", - sizeof(struct isopcb), sizeof(struct isopcb)); - printf( "SIZE OF cons_pcb 0x%x %d\n", - sizeof(struct cons_pcb), sizeof(struct cons_pcb)); - printf( "\t offset of co_state in cons_pcb 0x%x %d\n", - _offsetof( struct cons_pcb, co_state ), - _offsetof( struct cons_pcb, co_state )); - -#include "../h/types.h" -#include "../h/ioctl.h" -#include "../h/tty.h" - printf( "SIZE OF tty 0x%x %d\n", - sizeof(struct tty), sizeof(struct tty)); - printf( "\t offset of t_outq in tty 0x%x %d\n", - _offsetof( struct tty, t_outq ), - _offsetof( struct tty, t_outq )); - printf( "\t offset of t_canq in tty 0 0\n"); - printf( "\t offset of t_rawq in tty 0 0\n"); - printf( "SIZE OF clist 0x%x %d\n", - sizeof(struct clist), sizeof(struct clist)); - printf( "\t offset of c_cf in clist 0x%x %d\n", - _offsetof( struct clist, c_cf ), - _offsetof( struct clist, c_cf )); - - { - unsigned x; - - if( x<0 ) { - printf("x"); - } - } + SIZE(socket); + OFF(so_timeo,socket); OFF(so_rcv,socket); OFF(so_snd,socket); + OFF(so_tpcb,socket); OFF(so_pcb,socket); OFF(so_qlen,socket); + OFF(so_error,socket); OFF(so_state,socket); + SIZE(sockbuf); + OFF(sb_flags,sockbuf); OFF(sb_cc,sockbuf); + OFF(sb_mb,sockbuf); OFF(sb_mbcnt,sockbuf); + SIZE(isopcb); + SIZE(cons_pcb); OFF(co_state,cons_pcb); } diff --git a/usr/src/sys/netiso/tp_stat.h b/usr/src/sys/netiso/tp_stat.h index ccc3128aeb..6a6e891300 100644 --- a/usr/src/sys/netiso/tp_stat.h +++ b/usr/src/sys/netiso/tp_stat.h @@ -227,8 +227,7 @@ struct tp_pmeas { int Nb_from_ll; }; -#define IFPERF(tpcb) if (tpcb->tp_perf_on &&\ - (tpcb->tp_p_meas != (struct tp_pmeas *)0 )) { +#define IFPERF(tpcb) if (tpcb->tp_perf_on && tpcb->tp_p_meas) { #define ENDPERF } #else diff --git a/usr/src/sys/netiso/tp_subr.c b/usr/src/sys/netiso/tp_subr.c index 97c43763fe..d2c3674355 100644 --- a/usr/src/sys/netiso/tp_subr.c +++ b/usr/src/sys/netiso/tp_subr.c @@ -52,17 +52,17 @@ static char *rcsid = "$Header: tp_subr.c,v 5.3 88/11/18 17:28:43 nhall Exp $"; #include "types.h" #include "time.h" -#include "../netiso/tp_ip.h" -#include "../netiso/iso.h" -#include "../netiso/argo_debug.h" -#include "../netiso/tp_timer.h" -#include "../netiso/tp_param.h" -#include "../netiso/tp_stat.h" -#include "../netiso/tp_pcb.h" -#include "../netiso/tp_tpdu.h" -#include "../netiso/tp_trace.h" -#include "../netiso/tp_meas.h" -#include "../netiso/tp_seq.h" +#include "tp_ip.h" +#include "iso.h" +#include "argo_debug.h" +#include "tp_timer.h" +#include "tp_param.h" +#include "tp_stat.h" +#include "tp_pcb.h" +#include "tp_tpdu.h" +#include "tp_trace.h" +#include "tp_meas.h" +#include "tp_seq.h" int tp_emit(); static void tp_sbdrop(); @@ -213,7 +213,7 @@ tp_goodack(tpcb, cdt, seq, subseq) ENDTRACE IFPERF(tpcb) - tpmeas(tpcb->tp_lref, TPtime_ack_rcvd, 0, seq, 0, 0); + tpmeas(tpcb->tp_lref, TPtime_ack_rcvd, (struct timeval *)0, seq, 0, 0); ENDPERF if ( subseq != 0 && (subseq <= tpcb->tp_r_subseq) ) { @@ -391,20 +391,12 @@ tp_sbdrop(tpcb, seq) * RETURN VALUE: * the highest seq # sent successfully. */ - -/* For xpd marks we use mbufs of a special type with length 0; - * the m_next field is really the seq number of the xpd tpdu that - * must be acked before more normal data may be sent - */ - tp_send(tpcb) register struct tp_pcb *tpcb; { register int len; register struct mbuf *m; /* the one we're inspecting now */ struct mbuf *mb;/* beginning of this tpdu */ - register struct mbuf **n;/* link field we'll be modifying when we - take mb-->m out of the socket buffer */ struct mbuf *nextrecord; /* NOT next tpdu but next sb record */ struct sockbuf *sb = &tpcb->tp_sock->so_snd; int maxsize = tpcb->tp_l_tpdusize @@ -465,98 +457,32 @@ tp_send(tpcb) if (m == (struct mbuf *)0) { break; /* empty socket buffer */ } - if ( m->m_type == TPMT_XPD ) { + if (tpcb->tp_Xsnd.sb_mb) { register SeqNum Xuna = * (mtod(m, SeqNum *)); - register struct mbuf *mnext = MNULL; IFTRACE(D_XPD) tptraceTPCB( TPPTmisc, "tp_send XPD mark low high tpcb.Xuna", Xuna, lowseq, highseq, tpcb->tp_Xuna); ENDTRACE - if( SEQ_GEQ(tpcb, Xuna, tpcb->tp_Xuna)) { - /* stop sending here because there are unacked XPD which were - * given to us before the next data were. Leave mark in place. - */ - IncStat(ts_xpd_intheway); - break; - } - /* otherwise, mark is obsolete; delete it */ - sbfree(sb, m); /* have to do this to delete the sb_mbcnt */ - sb->sb_mb = m->m_act; - IncStat(ts_xpdmark_del); - if( mnext = m_free(m) ) { - IFTRACE(D_XPD) - tptraceTPCB( TPPTmisc, - "tp_send XPD mark deleted mnext old_act new_act", - mnext, sb->sb_mb, mnext->m_act, 0); - ENDTRACE - IFDEBUG(D_XPD) - printf( - "tp_send XPD mark deleted mnext 0x%x old act 0x%x new act 0x%x\n", - mnext, sb->sb_mb, mnext->m_act, 0); - ENDDEBUG - mnext->m_act = sb->sb_mb; - sb->sb_mb = mnext; - } - continue; + /* stop sending here because there are unacked XPD which were + * given to us before the next data were. + */ + IncStat(ts_xpd_intheway); + break; } - n = &sb->sb_mb; eotsdu_reached = 0; - len = 0; nextrecord = m->m_act; - while ( eotsdu_reached == 0 && len < maxsize && m != MNULL) { - *n = m; /* meaningless first time through the loop */ + for (len = 0; m; m = m->m_next) { len += m->m_len; - if ( len > maxsize ) { - /* - * Won't use the whole mbuf - split into 2 mbufs. - */ - int amount = m->m_len + maxsize - len; - struct mbuf *mx; - - /* copy the part we are NOT using and put that back in the - * socket buf; leave m with this tpdu chain; adjust its fields - */ - IFTRACE(D_STASH) - tptraceTPCB(TPPTmisc, - "tp_send SPLIT len, amount, m->m_len, tpdusize", - len, amount, m->m_len, maxsize); - ENDTRACE - mx = m_copy(m, amount, m->m_len - amount); /* preserves type */ - mx->m_next = m->m_next; - mx->m_act = m->m_act; /* preserve */ - - CHANGE_MTYPE(m, TPMT_DATA); - m->m_next = (struct mbuf *)0; - m->m_act = (struct mbuf *)0; /* not strictly necessary */ - m->m_len = amount; - - /* would do an sbfree but don't want the mbcnt to be - * decremented since it was never sballoced - */ - sb->sb_cc -= amount; - len = maxsize; - m = mx; - break; - } - - /* going to use the whole mbuf */ - IFTRACE(D_STASH) - tptraceTPCB(TPPTmisc, "tp_send whole mbuf: m_len len maxsize", - 0, m->m_len, len, maxsize); - ENDTRACE - - if ( m->m_type == TPMT_EOT ) + if (m->m_flags & M_EOR) eotsdu_reached = 1; - sbfree(sb, m); /* reduce counts in socket buffer */ - n = &m->m_next; - m = m->m_next; - - *n = (struct mbuf *)0; /* unlink the to-be-sent stuff from - the stuff still in the sb_mb so when we do the m_free - it won't clobber part of the socket buffer */ } + m = sb->sb_mb = nextrecord; + IFTRACE(D_STASH) + tptraceTPCB(TPPTmisc, "tp_send whole mbuf: m_len len maxsize", + 0, mb->m_len, len, maxsize); + ENDTRACE if ( len == 0 && !eotsdu_reached) { /* THIS SHOULD NEVER HAPPEN! */ @@ -564,14 +490,6 @@ tp_send(tpcb) goto done; } - /* sb_mb is non-null */ - if(m) { - sb->sb_mb = m; - if(nextrecord != m) - m->m_act = nextrecord; - } else - sb->sb_mb = nextrecord; - /* If we arrive here one of the following holds: * 1. We have exactly octets of whole mbufs, * 2. We accumulated octets using partial mbufs, @@ -733,32 +651,19 @@ tp_stash( tpcb, e ) if ( E.e_eot ) { register struct mbuf *n = E.e_data; - - /* sigh. have to go through this again! */ - /* a kludgy optimization would be to take care of this in - * tp_input (oh, horrors!) - * BTW, don't set ack_reason here because we don't know if the - * sequence number is right - */ - while (n->m_next ) - n = n->m_next; - - n->m_act = MNULL; /* set on tp_input */ - CHANGE_MTYPE(n, TPMT_EOT); - + n->m_flags |= M_EOR; + } IFDEBUG(D_STASH) - printf("EOT! changing m_type of m 0x%x\n", n); dump_mbuf(tpcb->tp_sock->so_rcv.sb_mb, "stash: so_rcv before appending"); dump_mbuf(E.e_data, "stash: e_data before appending"); ENDDEBUG - } IFPERF(tpcb) PStat(tpcb, Nb_from_ll) += E.e_datalen; tpmeas(tpcb->tp_lref, TPtime_from_ll, &e->e_time, - E.e_seq, PStat(tpcb, Nb_from_ll), E.e_datalen); + E.e_seq, (u_int)PStat(tpcb, Nb_from_ll), (u_int)E.e_datalen); ENDPERF if( E.e_seq == tpcb->tp_rcvnxt ) { @@ -773,18 +678,8 @@ tp_stash( tpcb, e ) E.e_seq, E.e_datalen, E.e_eot, 0); ENDTRACE - if( E.e_datalen == 0 && E.e_eot ) { - IFDEBUG(D_STASH) - printf("stash EQ: appendrec\n"); - ENDDEBUG - sbappendrecord (&tpcb->tp_sock->so_rcv, E.e_data); - /* 'cause sbappend won't append something of length zero */ - } else { - IFDEBUG(D_STASH) - printf("stash EQ: plain old append\n"); - ENDDEBUG - sbappend(&tpcb->tp_sock->so_rcv, E.e_data); - } + sbappend(&tpcb->tp_sock->so_rcv, E.e_data); + if (newrec = E.e_eot ) /* ASSIGNMENT */ ack_reason |= ACK_EOT; @@ -800,11 +695,7 @@ tp_stash( tpcb, e ) while (s != (struct tp_rtc *)0 && s->tprt_seq == tpcb->tp_rcvnxt) { *r = s->tprt_next; - if ( newrec ) { - sbappendrecord(&tpcb->tp_sock->so_rcv, s->tprt_data); - } else - sbappend(&tpcb->tp_sock->so_rcv, s->tprt_data); - newrec = s->tprt_eot; + sbappend(&tpcb->tp_sock->so_rcv, s->tprt_data); SEQ_INC( tpcb, tpcb->tp_rcvnxt ); @@ -976,16 +867,11 @@ tp0_stash( tpcb, e ) n->m_act = MNULL; /* set on tp_input */ - CHANGE_MTYPE(n, TPMT_EOT); - } - if( E.e_datalen == 0 && E.e_eot ) { - sbappendrecord (&tpcb->tp_sock->so_rcv, E.e_data); - } else { - sbappend(&tpcb->tp_sock->so_rcv, E.e_data); + n->m_flags |= M_EOR; } + sbappendrecord (&tpcb->tp_sock->so_rcv, E.e_data); IFDEBUG(D_STASH) dump_mbuf(tpcb->tp_sock->so_rcv.sb_mb, "stash 0: so_rcv after appending"); ENDDEBUG } - diff --git a/usr/src/sys/netiso/tp_subr2.c b/usr/src/sys/netiso/tp_subr2.c index 356e357443..2fe935f8ff 100644 --- a/usr/src/sys/netiso/tp_subr2.c +++ b/usr/src/sys/netiso/tp_subr2.c @@ -60,20 +60,20 @@ static char *rcsid = "$Header: tp_subr2.c,v 5.5 88/11/18 17:28:55 nhall Exp $"; #include "time.h" #include "kernel.h" #undef MNULL -#include "../netiso/tp_ip.h" -#include "../netiso/tp_param.h" -#include "../netiso/tp_timer.h" -#include "../netiso/tp_stat.h" -#include "../netiso/argo_debug.h" -#include "../netiso/tp_tpdu.h" -#include "../netiso/iso.h" -#include "../netiso/iso_errno.h" -#include "../netiso/tp_pcb.h" -#include "../netiso/tp_seq.h" -#include "../netiso/tp_trace.h" -#include "../netiso/iso_pcb.h" -#include "../netiso/tp_user.h" -#include "../netiso/cons.h" +#include "argo_debug.h" +#include "tp_param.h" +#include "tp_ip.h" +#include "iso.h" +#include "iso_errno.h" +#include "iso_pcb.h" +#include "tp_timer.h" +#include "tp_stat.h" +#include "tp_tpdu.h" +#include "tp_pcb.h" +#include "tp_seq.h" +#include "tp_trace.h" +#include "tp_user.h" +#include "cons.h" /* * NAME: tp_local_credit() @@ -185,18 +185,18 @@ tp_indicate(ind, tpcb, error) register struct socket *so = tpcb->tp_sock; IFTRACE(D_INDICATION) tptraceTPCB(TPPTindicate, ind, *(int *)(tpcb->tp_lsuffix), - *(int *)(tpcb->tp_fsuffix), error,so->so_pgrp); + *(int *)(tpcb->tp_fsuffix), error,so->so_pgid); ENDTRACE IFDEBUG(D_INDICATION) - u_char *ls, *fs; + char *ls, *fs; ls = tpcb->tp_lsuffix, fs = tpcb->tp_fsuffix, printf( -"indicate 0x%x lsuf 0x%02x%02x fsuf 0x%02x%02x err 0x%x prgp 0x%x noind 0x%x ref 0x%x\n", +"indicate 0x%x lsuf 0x%02x%02x fsuf 0x%02x%02x err 0x%x noind 0x%x ref 0x%x\n", ind, *ls, *(ls+1), *fs, *(fs+1), - error,so->so_pgrp, + error, /*so->so_pgrp,*/ tpcb->tp_no_disc_indications, tpcb->tp_lref); ENDDEBUG @@ -263,8 +263,8 @@ void tp_recycle_tsuffix(tpcb) struct tp_pcb *tpcb; { - bzero( tpcb->tp_lsuffix, sizeof( tpcb->tp_lsuffix)); - bzero( tpcb->tp_fsuffix, sizeof( tpcb->tp_fsuffix)); + bzero((caddr_t)tpcb->tp_lsuffix, sizeof( tpcb->tp_lsuffix)); + bzero((caddr_t)tpcb->tp_fsuffix, sizeof( tpcb->tp_fsuffix)); tpcb->tp_fsuffixlen = tpcb->tp_lsuffixlen = 0; (tpcb->tp_nlproto->nlp_recycle_suffix)(tpcb->tp_npcb); @@ -396,7 +396,7 @@ copyQOSparms(src, dst) /* copy all but the bits stuff at the end */ #define COPYSIZE (12 * sizeof(short)) - bcopy( src, dst, COPYSIZE); + bcopy((caddr_t)src, (caddr_t)dst, COPYSIZE); dst->p_tpdusize = src->p_tpdusize; dst->p_ack_strat = src->p_ack_strat; dst->p_rx_strat = src->p_rx_strat; @@ -443,7 +443,7 @@ tp_route_to( m, tpcb, channel) IFTRACE(D_CONN) tptraceTPCB(TPPTmisc, "route_to: so afi netservice class", - tpcb->tp_sock, siso->siso_addr.isoa_afi, tpcb->tp_netservice, + tpcb->tp_sock, siso->siso_addr.isoa_genaddr[0], tpcb->tp_netservice, tpcb->tp_class); ENDTRACE IFDEBUG(D_CONN) @@ -456,6 +456,14 @@ tp_route_to( m, tpcb, channel) error = EAFNOSUPPORT; goto done; } + IFDEBUG(D_CONN) + printf("tp_route_to calling nlp_pcbconn, netserv %d\n", + tpcb->tp_netservice); + ENDDEBUG + error = (tpcb->tp_nlproto->nlp_pcbconn)(tpcb->tp_sock->so_pcb, m); + if( error ) + goto done; + { register int save_netservice = tpcb->tp_netservice; @@ -464,8 +472,9 @@ tp_route_to( m, tpcb, channel) case ISO_CLNS: /* This is a kludge but seems necessary so the passive end * can get long enough timers. sigh. + if( siso->siso_addr.osinet_idi[1] == (u_char)IDI_OSINET ) */ - if( siso->siso_addr.osinet_idi[1] == (u_char)IDI_OSINET ) { + if( siso->siso_addr.isoa_genaddr[2] == (char)IDI_OSINET ) { if( tpcb->tp_dont_change_params == 0) { copyQOSparms( &tp_conn_param[ISO_COSNS], &tpcb->_tp_param); @@ -474,6 +483,8 @@ tp_route_to( m, tpcb, channel) } /* drop through to IN_CLNS*/ case IN_CLNS: + if (iso_localifa(siso)) + tpcb->tp_flags |= TPF_PEER_ON_SAMENET; if( (tpcb->tp_class & TP_CLASS_4)==0 ) { error = EPROTOTYPE; break; @@ -549,27 +560,10 @@ tp_route_to( m, tpcb, channel) ASSERT( save_netservice == tpcb->tp_netservice); } - if( error ) - goto done; - IFDEBUG(D_CONN) - printf("tp_route_to calling nlp_pcbconn, netserv %d\n", - tpcb->tp_netservice); - ENDDEBUG - error = (tpcb->tp_nlproto->nlp_pcbconn)(tpcb->tp_sock->so_pcb, m); - if( error && vc_to_kill ) { tp_netcmd( tpcb, CONN_CLOSE); goto done; } - - /* PHASE 2: replace iso_netmatch with iso_on_localnet(foreign addr) */ - if( iso_netmatch( - &(((struct isopcb *)(tpcb->tp_sock->so_pcb))->isop_laddr), - &(((struct isopcb *)(tpcb->tp_sock->so_pcb))->isop_faddr) - )) { - tpcb->tp_flags |= TPF_PEER_ON_SAMENET; - } - { /* start with the global rtt, rtv stats */ register int i = (int) tpcb->tp_flags & (TPF_PEER_ON_SAMENET | TPF_NLQOS_PDN); @@ -607,32 +601,26 @@ tp_setup_perf(tpcb) { register struct mbuf *q; - if( tpcb->tp_p_meas == (struct tp_pmeas *)0 ) { - - /* allocate a cluster for all the stats */ - MGET(q, M_DONTWAIT, TPMT_PERF); /* something we don't otherwise use */ + if( tpcb->tp_p_meas == 0 ) { + MGET(q, M_WAITOK, MT_PCB); if (q == 0) return ENOBUFS; - q->m_act = MNULL; - MCLGET(q); /* for the tp_pmeas struct */ - if(q->m_len == 0) { - m_free(q); + MCLGET(q, M_WAITOK); + if ((q->m_flags & M_EXT) == 0) { + (void) m_free(q); return ENOBUFS; - } else { - /* point into the cluster */ - tpcb->tp_p_meas = mtod(q, struct tp_pmeas *); - /* get rid of the original little mbuf */ - q->m_off = 0; q->m_len = 0; - m_free(q); - bzero( (caddr_t)tpcb->tp_p_meas, sizeof (struct tp_pmeas) ); - IFDEBUG(D_PERF_MEAS) - printf( - "tpcb 0x%x so 0x%x ref 0x%x tp_p_meas 0x%x tp_perf_on 0x%x\n", - tpcb, tpcb->tp_sock, tpcb->tp_lref, - tpcb->tp_p_meas, tpcb->tp_perf_on); - ENDDEBUG - tpcb->tp_perf_on = 1; } + q->m_len = sizeof (struct tp_pmeas); + tpcb->tp_p_mbuf = q; + tpcb->tp_p_meas = mtod(q, struct tp_pmeas *); + bzero( (caddr_t)tpcb->tp_p_meas, sizeof (struct tp_pmeas) ); + IFDEBUG(D_PERF_MEAS) + printf( + "tpcb 0x%x so 0x%x ref 0x%x tp_p_meas 0x%x tp_perf_on 0x%x\n", + tpcb, tpcb->tp_sock, tpcb->tp_lref, + tpcb->tp_p_meas, tpcb->tp_perf_on); + ENDDEBUG + tpcb->tp_perf_on = 1; } return 0; } @@ -644,16 +632,56 @@ dump_addr (addr) { switch( addr->sa_family ) { case AF_INET: - dump_inaddr(addr); + dump_inaddr((struct sockaddr_in *)addr); break; +#ifdef ISO case AF_ISO: - dump_isoaddr(addr); + dump_isoaddr((struct sockaddr_iso *)addr); break; +#endif ISO default: printf("BAD AF: 0x%x\n", addr->sa_family); break; } } +#define MAX_COLUMNS 8 +/* + * Dump the buffer to the screen in a readable format. Format is: + * + * hex/dec where hex is the hex format, dec is the decimal format. + * columns of hex/dec numbers will be printed, followed by the + * character representations (if printable). + */ +Dump_buf(buf, len) +caddr_t buf; +int len; +{ + int i,j; + + printf("Dump buf 0x%x len 0x%x\n", buf, len); + for (i = 0; i < len; i += MAX_COLUMNS) { + printf("+%d:\t", i); + for (j = 0; j < MAX_COLUMNS; j++) { + if (i + j < len) { + printf("%x/%d\t", buf[i+j]&0xff, buf[i+j]); + } else { + printf(" "); + } + } + + for (j = 0; j < MAX_COLUMNS; j++) { + if (i + j < len) { + if (((buf[i+j]) > 31) && ((buf[i+j]) < 128)) + printf("%c", buf[i+j]&0xff); + else + printf("."); + } + } + printf("\n"); + } +} + + #endif ARGO_DEBUG diff --git a/usr/src/sys/netiso/tp_timer.c b/usr/src/sys/netiso/tp_timer.c index 31d3dee30c..f78e9162d5 100644 --- a/usr/src/sys/netiso/tp_timer.c +++ b/usr/src/sys/netiso/tp_timer.c @@ -54,15 +54,16 @@ static char *rcsid = "$Header: tp_timer.c,v 5.2 88/11/18 17:29:07 nhall Exp $"; #include "param.h" #include "types.h" #include "time.h" +#include "malloc.h" -#include "../netiso/tp_param.h" -#include "../netiso/tp_timer.h" -#include "../netiso/tp_stat.h" -#include "../netiso/tp_pcb.h" -#include "../netiso/tp_tpdu.h" -#include "../netiso/argo_debug.h" -#include "../netiso/tp_trace.h" -#include "../netiso/tp_seq.h" +#include "tp_param.h" +#include "tp_timer.h" +#include "tp_stat.h" +#include "tp_pcb.h" +#include "tp_tpdu.h" +#include "argo_debug.h" +#include "tp_trace.h" +#include "tp_seq.h" static struct Ecallout *TP_callfree; static struct Ecallout TP_callout[N_TPREF*2]; @@ -143,6 +144,7 @@ tp_Eclock(refp) } for (;;) { + struct tp_pcb *tpcb; if ((p1 = refp->tpr_calltodo.c_next) == 0 || p1->c_time > 0) { break; } @@ -163,7 +165,9 @@ tp_Eclock(refp) TP_callfree = p1; IncStat(ts_Eexpired); - (void) tp_driver( refp->tpr_pcb, &E); + (void) tp_driver( tpcb = refp->tpr_pcb, &E); + if (p1->c_func == TM_reference && tpcb->tp_state == TP_CLOSED) + free((caddr_t)tpcb, M_PCB); /* XXX wart; where else to do it? */ } } @@ -410,7 +414,7 @@ tp_cuntimeout(refp, which) cp = &(refp->tpr_callout[which]); IFDEBUG(D_TIMER) - printf("tp_cuntimeout(0x%x, %d) active\n", refp, which, cp->c_active); + printf("tp_cuntimeout(0x%x, %d) active %d\n", refp, which, cp->c_active); ENDDEBUG IFTRACE(D_TIMER) diff --git a/usr/src/sys/netiso/tp_tpdu.h b/usr/src/sys/netiso/tp_tpdu.h index 082ebcf67f..ff479820bf 100644 --- a/usr/src/sys/netiso/tp_tpdu.h +++ b/usr/src/sys/netiso/tp_tpdu.h @@ -58,16 +58,16 @@ SOFTWARE. * structure below */ struct tpdu_fixed { - unsigned _tpduf_li:8, /* length indicator */ + u_char _tpduf_li:8, /* length indicator */ #if BYTE_ORDER == LITTLE_ENDIAN _tpduf_cdt: 4, /* credit */ - _tpduf_type: 4, /* type of tpdu (DT, CR, etc.) */ + _tpduf_type: 4; /* type of tpdu (DT, CR, etc.) */ #endif #if BYTE_ORDER == BIG_ENDIAN _tpduf_type: 4, /* type of tpdu (DT, CR, etc.) */ - _tpduf_cdt: 4, /* credit */ + _tpduf_cdt: 4; /* credit */ #endif - _tpduf_dref: 16; /* destination ref; not in DT in class 0 */ + u_short _tpduf_dref; /* destination ref; not in DT in class 0 */ }; #define tpdu_li _tpduf._tpduf_li @@ -76,7 +76,8 @@ struct tpdu_fixed { #define tpdu_dref _tpduf._tpduf_dref struct tp0du { - unsigned _tp0same:16, /* same as in tpdu_fixed */ + u_char _tp0_li, + _tp0_cdt_type, /* same as in tpdu_fixed */ #if BYTE_ORDER == BIG_ENDIAN _tp0_eot: 1, /* eot */ _tp0_mbz: 7, /* must be zero */ @@ -123,7 +124,7 @@ union seq_type { union tpdu_fixed_rest { struct { - unsigned _tpdufr_sref:16, /* source reference */ + u_short _tpdufr_sref, /* source reference */ #if BYTE_ORDER == BIG_ENDIAN _tpdufr_class: 4, /* class [ ISO 8073 13.3.3.e ] */ _tpdufr_opt: 4, /* options [ ISO 8073 13.3.3.e ] */ diff --git a/usr/src/sys/netiso/tp_trace.c b/usr/src/sys/netiso/tp_trace.c index ae71be6f69..653c0ae739 100644 --- a/usr/src/sys/netiso/tp_trace.c +++ b/usr/src/sys/netiso/tp_trace.c @@ -50,15 +50,15 @@ static char *rcsid = "$Header: tp_trace.c,v 5.3 88/11/18 17:29:14 nhall Exp $"; #include "types.h" #include "time.h" -#include "../netiso/tp_param.h" -#include "../netiso/tp_timer.h" -#include "../netiso/tp_stat.h" -#include "../netiso/tp_param.h" -#include "../netiso/tp_ip.h" -#include "../netiso/tp_pcb.h" -#include "../netiso/tp_tpdu.h" -#include "../netiso/argo_debug.h" -#include "../netiso/tp_trace.h" +#include "tp_param.h" +#include "tp_timer.h" +#include "tp_stat.h" +#include "tp_param.h" +#include "tp_ip.h" +#include "tp_pcb.h" +#include "tp_tpdu.h" +#include "argo_debug.h" +#include "tp_trace.h" #ifdef TPPT static tp_seq = 0; @@ -98,7 +98,7 @@ tpTrace(tpcb, event, arg, src, len, arg4, arg5) case TPPTertpdu: bcopy((caddr_t)src, (caddr_t)&tp->tpt_ertpdu, - MIN((int)len, sizeof(struct tp_Trace))); + (unsigned)MIN((int)len, sizeof(struct tp_Trace))); break; case TPPTusrreq: @@ -106,7 +106,7 @@ tpTrace(tpcb, event, arg, src, len, arg4, arg5) /* arg is a string */ bcopy((caddr_t)arg, (caddr_t)tp->tpt_str, - MIN(1+strlen((caddr_t) arg), TPTRACE_STRLEN)); + (unsigned)MIN(1+strlen((caddr_t) arg), TPTRACE_STRLEN)); tp->tpt_m2 = src; tp->tpt_m3 = len; tp->tpt_m4 = arg4; @@ -137,8 +137,8 @@ tpTrace(tpcb, event, arg, src, len, arg4, arg5) case TPPTtpduin: case TPPTtpduout: tp->tpt_arg2 = arg4; - bcopy((caddr_t)src, (caddr_t)&tp->tpt_tpdu, MIN((int)len, - sizeof(struct tp_Trace))); + bcopy((caddr_t)src, (caddr_t)&tp->tpt_tpdu, + (unsigned)MIN((int)len, sizeof(struct tp_Trace))); break; } } diff --git a/usr/src/sys/netiso/tp_user.h b/usr/src/sys/netiso/tp_user.h index cd6864bc39..2d3ce7c153 100644 --- a/usr/src/sys/netiso/tp_user.h +++ b/usr/src/sys/netiso/tp_user.h @@ -29,6 +29,7 @@ SOFTWARE. * * $Header: tp_user.h,v 5.2 88/11/04 15:44:44 nhall Exp $ * $Source: /usr/argo/sys/netiso/RCS/tp_user.h,v $ + * @(#)tp_user.h 7.2 (Berkeley) %G% * * These are the values a real-live user ;-) needs. */ @@ -78,6 +79,18 @@ struct tp_conn_param { u_char p_netservice; }; +struct tp_control_hdr { + u_short cmsg_len; + u_short cmsg_type; /* TPOPT_[CONN,DISC,CFRM]_DATA */ + u_short cmsg_level; /* e.g. SOL_SOCKET, _TRANSPORT, etc. */ +/* u_char cmsg_data[msg_len - sizeof(tp_control_hdr)]; */ +}; +/* + * These sockopt level definitions should be considered for socket.h + */ +#define SOL_TRANSPORT 0xfffe +#define SOL_NETWORK 0xfffd + /* get/set socket opt commands */ #define TPACK_WINDOW 0x0 /* ack only on full window */ #define TPACK_EACH 0x1 /* ack every packet */ @@ -89,6 +102,7 @@ struct tp_conn_param { #define TPOPT_FLAGS 0x300 #define TPOPT_CONN_DATA 0x400 #define TPOPT_DISC_DATA 0x500 +#define TPOPT_CFRM_DATA 0x600 #define TPOPT_CDDATA_CLEAR 0x700 #define TPOPT_PERF_MEAS 0xa00 #define TPOPT_PSTATISTICS 0xb00 diff --git a/usr/src/sys/netiso/tp_usrreq.c b/usr/src/sys/netiso/tp_usrreq.c index 6781a476d4..9a366f33f2 100644 --- a/usr/src/sys/netiso/tp_usrreq.c +++ b/usr/src/sys/netiso/tp_usrreq.c @@ -52,17 +52,17 @@ static char *rcsid = "$Header: tp_usrreq.c,v 5.4 88/11/18 17:29:18 nhall Exp $"; #include "protosw.h" #include "errno.h" -#include "../netiso/tp_param.h" -#include "../netiso/tp_timer.h" -#include "../netiso/tp_stat.h" -#include "../netiso/tp_seq.h" -#include "../netiso/tp_ip.h" -#include "../netiso/tp_pcb.h" -#include "../netiso/argo_debug.h" -#include "../netiso/tp_trace.h" -#include "../netiso/tp_meas.h" -#include "../netiso/iso.h" -#include "../netiso/iso_errno.h" +#include "tp_param.h" +#include "tp_timer.h" +#include "tp_stat.h" +#include "tp_seq.h" +#include "tp_ip.h" +#include "tp_pcb.h" +#include "argo_debug.h" +#include "tp_trace.h" +#include "tp_meas.h" +#include "iso.h" +#include "iso_errno.h" int tp_attach(), tp_driver(); @@ -91,8 +91,8 @@ dump_mbuf(n, str) nextrecord = n->m_act; printf("RECORD:\n"); while (n) { - printf("%x : Len %x Of %x A %x Nx %x Tp %x\n", - n, n->m_len, n->m_off, n->m_act, n->m_next, n->m_type); + printf("%x : Len %x Data %x A %x Nx %x Tp %x\n", + n, n->m_len, n->m_data, n->m_act, n->m_next, n->m_type); #ifdef notdef { register char *p = mtod(n, char *); @@ -135,7 +135,6 @@ dump_mbuf(n, str) * xpd data in the buffer * E* whatever is returned from the fsm. */ -static int tp_rcvoob(tpcb, so, m, outflags, inflags) struct tp_pcb *tpcb; register struct socket *so; @@ -144,9 +143,10 @@ tp_rcvoob(tpcb, so, m, outflags, inflags) int inflags; { register struct mbuf *n; - register struct sockbuf *sb = &tpcb->tp_Xrcv; + register struct sockbuf *sb = &so->so_rcv; struct tp_event E; int error = 0; + register struct mbuf **nn; IFDEBUG(D_XPD) printf("PRU_RCVOOB, sostate 0x%x\n", so->so_state); @@ -165,7 +165,23 @@ restart: return ENOTCONN; } - if ( sb->sb_cc == 0) { + /* Take the first mbuf off the chain. + * Each XPD TPDU gives you a complete TSDU so the chains don't get + * coalesced, but one TSDU may span several mbufs. + * Nevertheless, since n should have a most 16 bytes, it + * will fit into m. (size was checked in tp_input() ) + */ + + /* + * Code for excision of OOB data should be added to + * uipc_socket2.c (like sbappend). + */ + + for (nn = &sb->sb_mb; n = *nn; nn = &n->m_act) + if (n->m_type == MT_OOBDATA) + break; + + if (n == 0) { ASSERT( (tpcb->tp_flags & TPF_DISC_DATA_IN) == 0 ); IFDEBUG(D_XPD) printf("RCVOOB: empty queue!\n"); @@ -177,36 +193,17 @@ restart: sbwait(sb); goto restart; } - /* Take the first mbuf off the chain. - * Each XPD TPDU gives you a complete TSDU so the chains don't get - * coalesced, but one TSDU may span several mbufs. - * Nevertheless, since n should have a most 16 bytes, it - * will fit into m. (size was checked in tp_input() ) - */ - - n = sb->sb_mb; - ASSERT((n->m_type == TPMT_DATA) || - n->m_type == TPMT_IPHDR || n->m_type == TPMT_TPHDR); - - /* - * mtod doesn't work for cluster-type mbufs, hence this disaster check: - */ - if( n->m_off > MMAXOFF ) - panic("tp_rcvoob: unexpected cluster "); - - m->m_next = MNULL; - m->m_act = MNULL; - m->m_off = MMINOFF; m->m_len = 0; /* Assuming at most one xpd tpdu is in the buffer at once */ while ( n != MNULL ) { m->m_len += n->m_len; - bcopy(mtod(n, caddr_t), mtod(m, caddr_t), n->m_len); - m->m_off += n->m_len; /* so mtod() in bcopy() above gives right addr */ + bcopy(mtod(n, caddr_t), mtod(m, caddr_t), (unsigned)n->m_len); + m->m_data += n->m_len; /* so mtod() in bcopy() above gives right addr */ n = n->m_next; } - m->m_off = MMINOFF; /* restore it to its proper value */ + m->m_data = m->m_dat; + m->m_flags |= M_EOR; IFDEBUG(D_XPD) printf("tp_rcvoob: xpdlen 0x%x\n", m->m_len); @@ -214,8 +211,11 @@ restart: dump_mbuf(sb->sb_mb, "RCVOOB: Xrcv socketbuf"); ENDDEBUG - if( (inflags & MSG_PEEK) == 0 ) - sbdrop(sb, m->m_len); + if( (inflags & MSG_PEEK) == 0 ) { + n = *nn; + *nn = n->m_act; + sb->sb_cc -= m->m_len; + } release: sbunlock(sb); @@ -224,8 +224,6 @@ release: tptraceTPCB(TPPTmisc, "PRU_RCVOOB @ release sb_cc m_len", tpcb->tp_Xrcv.sb_cc, m->m_len,0,0 ); ENDTRACE - if(outflags) - *outflags = MSG_OOB | MSG_EOTSDU | inflags; /* always on xpd recv */ if (error == 0) error = DoEvent(T_USR_Xrcvd); return error; @@ -245,7 +243,6 @@ release: * EMSGSIZE if trying to send > max-xpd bytes (16) * ENOBUFS if ran out of mbufs */ -static int tp_sendoob(tpcb, so, xdata, outflags) struct tp_pcb *tpcb; register struct socket *so; @@ -291,12 +288,12 @@ oob_again: if (xdata == (struct mbuf *)0) { /* empty xpd packet */ - MGET(xdata, M_WAIT, TPMT_DATA); + MGETHDR(xdata, M_WAIT, MT_OOBDATA); if (xdata == NULL) { return ENOBUFS; } xdata->m_len = 0; - xdata->m_act = MNULL; + xdata->m_pkthdr.len = 0; } IFDEBUG(D_XPD) printf("tp_sendoob 1:"); @@ -317,26 +314,11 @@ oob_again: printf("xdata len 0x%x\n", len); ENDDEBUG - /* stick an xpd mark in the normal data queue - * make sure we have enough mbufs before we stick anything into any queues - */ - MGET(xmark,M_WAIT, TPMT_XPD); - if (xmark == MNULL) { - return ENOBUFS; - } - xmark->m_len = 0; - xmark->m_act = MNULL; - - { /* stash the xpd sequence number in the mark */ - SeqNum *Xuna = mtod(xmark, SeqNum *); - *Xuna = tpcb->tp_Xuna; - } IFTRACE(D_XPD) tptraceTPCB(TPPTmisc, "XPD mark m_next ", xmark->m_next, 0, 0, 0); ENDTRACE - sbappendrecord(&so->so_snd, xmark); /* the mark */ sbappendrecord(sb, xdata); IFDEBUG(D_XPD) @@ -344,7 +326,6 @@ oob_again: dump_mbuf(so->so_snd.sb_mb, "XPD request Regular sndbuf:"); dump_mbuf(tpcb->tp_Xsnd.sb_mb, "XPD request Xsndbuf:"); ENDDEBUG - u.u_r.r_val1 += len; return DoEvent(T_XPD_req); } @@ -367,15 +348,15 @@ oob_again: */ /*ARGSUSED*/ ProtoHook -tp_usrreq(so, req, m, nam, rightsp, outflags) +tp_usrreq(so, req, m, nam, rightsp, controlp) struct socket *so; u_int req; - struct mbuf *m, *nam, *rightsp /* not used */; - int *outflags; + struct mbuf *m, *nam, *rightsp, *controlp; { register struct tp_pcb *tpcb = sototpcb(so); int s = splnet(); int error = 0; + int flags, *outflags = &flags; u_long eotsdu = 0; struct tp_event E; @@ -397,23 +378,6 @@ tp_usrreq(so, req, m, nam, rightsp, outflags) return ENOTCONN; } - - IFDEBUG(D_XPD) - extern struct mbuf *mfree; - struct mbuf *m = mfree, *n=MNULL; - - if ( (u_int) tpcb != 0 ) { - n = tpcb->tp_Xrcv.sb_mb; - if(n) while(m) { - if(m == n) { - printf("enter usrreq %d Xrcv sb_mb 0x%x is on freelist!\n", - req, n); - } - m = m->m_next; - } - } - ENDDEBUG - switch (req) { case PRU_ATTACH: @@ -439,6 +403,10 @@ tp_usrreq(so, req, m, nam, rightsp, outflags) case PRU_DETACH: /* called from close() */ /* called only after disconnect was called */ error = DoEvent(T_DETACH); + if (tpcb->tp_state == TP_CLOSED) { + free((caddr_t)tpcb, M_PCB); + tpcb = 0; + } break; case PRU_SHUTDOWN: @@ -451,9 +419,8 @@ tp_usrreq(so, req, m, nam, rightsp, outflags) case PRU_BIND: error = (tpcb->tp_nlproto->nlp_pcbbind)( so->so_pcb, nam ); if (error == 0) { - tpcb->tp_lsuffixlen = sizeof(short); /* default */ - *(u_short *)(tpcb->tp_lsuffix) = (u_short) - (tpcb->tp_nlproto->nlp_getsufx)( so->so_pcb, TP_LOCAL ); + (tpcb->tp_nlproto->nlp_getsufx)(so->so_pcb, &tpcb->tp_lsuffixlen, + tpcb->tp_lsuffix, TP_LOCAL ); } break; @@ -464,9 +431,8 @@ tp_usrreq(so, req, m, nam, rightsp, outflags) break; } if( tpcb->tp_lsuffixlen == 0) { - tpcb->tp_lsuffixlen = sizeof(short); /* default */ - *SHORT_LSUFXP(tpcb) = (short) - (tpcb->tp_nlproto->nlp_getsufx)( so->so_pcb, TP_LOCAL ); + (tpcb->tp_nlproto->nlp_getsufx)(so->so_pcb, &tpcb->tp_lsuffixlen, + tpcb->tp_lsuffix, TP_LOCAL ); } IFDEBUG(D_TPISO) if(tpcb->tp_state != TP_CLOSED) @@ -482,7 +448,7 @@ tp_usrreq(so, req, m, nam, rightsp, outflags) case PRU_CONNECT: IFTRACE(D_CONN) tptraceTPCB(TPPTmisc, - "PRU_CONNECT: so *SHORT_LSUFXP(tpcb) 0x%x lsuflen 0x%x, class 0x%x", + "PRU_CONNECT: so 0x%x *SHORT_LSUFXP(tpcb) 0x%x lsuflen 0x%x, class 0x%x", tpcb->tp_sock, *SHORT_LSUFXP(tpcb), tpcb->tp_lsuffixlen, tpcb->tp_class); ENDTRACE @@ -501,12 +467,10 @@ tp_usrreq(so, req, m, nam, rightsp, outflags) break; } } - if (tpcb->tp_lsuffixlen == 0) { - /* didn't set an extended suffix */ - tpcb->tp_lsuffixlen = sizeof(short); - *SHORT_LSUFXP(tpcb) = (short) - (tpcb->tp_nlproto->nlp_getsufx)( so->so_pcb, TP_LOCAL ); - } + if( tpcb->tp_lsuffixlen == 0) { + (tpcb->tp_nlproto->nlp_getsufx)(so->so_pcb, &tpcb->tp_lsuffixlen, + tpcb->tp_lsuffix, TP_LOCAL ); + } IFDEBUG(D_CONN) printf("isop 0x%x isop->isop_socket offset 12 :\n", tpcb->tp_npcb); @@ -521,11 +485,10 @@ tp_usrreq(so, req, m, nam, rightsp, outflags) printf("isop 0x%x isop->isop_socket offset 12 :\n", tpcb->tp_npcb); dump_buf( tpcb->tp_npcb, 16); ENDDEBUG - if( tpcb->tp_fsuffixlen == 0 ) { + if( tpcb->tp_fsuffixlen == 0) { /* didn't set peer extended suffix */ - tpcb->tp_fsuffixlen = sizeof(short); - *SHORT_FSUFXP(tpcb) = (short) - (tpcb->tp_nlproto->nlp_getsufx)(so->so_pcb, TP_FOREIGN); + (tpcb->tp_nlproto->nlp_getsufx)(so->so_pcb, &tpcb->tp_fsuffixlen, + tpcb->tp_fsuffix, TP_FOREIGN ); } (void) (tpcb->tp_nlproto->nlp_mtu)(so, so->so_pcb, &tpcb->tp_l_tpdusize, &tpcb->tp_tpdusize, 0); @@ -566,26 +529,10 @@ tp_usrreq(so, req, m, nam, rightsp, outflags) if (so->so_error) { error = so->so_error; } else { - struct sockaddr *sa = mtod(nam, struct sockaddr *); - - nam->m_len = sizeof (struct sockaddr); - (tpcb->tp_nlproto->nlp_getnetaddr)(so->so_pcb, sa, TP_FOREIGN); - - switch(sa->sa_family = sototpcb(so)->tp_domain) { - case AF_INET: - satosin(sa)->sin_port = - (tpcb->tp_nlproto->nlp_getsufx)(so->so_pcb, TP_FOREIGN); - break; - case AF_ISO: - satosiso(sa)->siso_tsuffix = - (tpcb->tp_nlproto->nlp_getsufx)(so->so_pcb, TP_FOREIGN); - /* doesn't cover the case where the suffix is extended - - * grotesque - the user *has* to do the getsockopt */ - break; - } + (tpcb->tp_nlproto->nlp_getnetaddr)(so->so_pcb, nam, TP_FOREIGN); IFDEBUG(D_REQUEST) printf("ACCEPT PEERADDDR:"); - dump_buf(sa, sizeof(struct sockaddr)); + dump_buf(mtod(nam, char *), nam->m_len); ENDDEBUG } IFPERF(tpcb) @@ -610,7 +557,15 @@ tp_usrreq(so, req, m, nam, rightsp, outflags) sbspace(&so->so_rcv), tpcb->tp_lcredit, so->so_rcv.sb_cc, so->so_rcv.sb_hiwat); ENDTRACE - error = DoEvent(T_USR_rcvd); + IFDEBUG(D_REQUEST) + printf("RCVD: cc %d space %d hiwat %d\n", + so->so_rcv.sb_cc, sbspace(&so->so_rcv), + so->so_rcv.sb_hiwat); + ENDDEBUG + if (((int)nam) & MSG_OOB) + error = DoEvent(T_USR_Xrcvd); + else + error = DoEvent(T_USR_rcvd); break; case PRU_RCVOOB: @@ -627,10 +582,12 @@ tp_usrreq(so, req, m, nam, rightsp, outflags) break; case PRU_SENDOOB: - if ((so->so_state & SS_ISCONNECTED) == 0) { - error = ENOTCONN; + if (controlp && (error = tp_snd_control(controlp, so, &m))) break; - } + if (m == 0) + break; + if (so->so_state & SS_ISCONFIRMING) + tp_confirm(); if( ! tpcb->tp_xpd_service ) { error = EOPNOTSUPP; break; @@ -638,9 +595,6 @@ tp_usrreq(so, req, m, nam, rightsp, outflags) error = tp_sendoob(tpcb, so, m, outflags); break; - case PRU_SENDEOT: - eotsdu = 1; - /* fall through */ case PRU_SEND: /* * The protocol machine copies mbuf chains, @@ -652,103 +606,80 @@ tp_usrreq(so, req, m, nam, rightsp, outflags) * Sbspace may be made negative by appending this mbuf chain, * possibly by a whole cluster. */ - if ((so->so_state & SS_ISCONNECTED) == 0) { - error = ENOTCONN; + if (controlp && (error = tp_snd_control(controlp, so, &m))) break; - } + if (m == 0) + break; + if (so->so_state & SS_ISCONFIRMING) + tp_confirm(); { - register struct mbuf *n; + register struct mbuf *n = m; register int len=0; register struct sockbuf *sb = &so->so_snd; - - n = m; - while (n) { /* Could have eotsdu and no data.(presently MUST have - * an mbuf though, even if its length == 0) - */ - len += n->m_len; - if( n->m_next == MNULL && eotsdu ) { - CHANGE_MTYPE(n, TPMT_EOT); - } - n = n->m_next; - } + int maxsize = tpcb->tp_l_tpdusize + - tp_headersize(DT_TPDU_type, tpcb) + - (tpcb->tp_use_checksum?4:0) ; + int totlen = n->m_pkthdr.len; + + /* + * Could have eotsdu and no data.(presently MUST have + * an mbuf though, even if its length == 0) + */ + if (n->m_flags & M_EOR) + eotsdu = 1; IFPERF(tpcb) - PStat(tpcb, Nb_from_sess) += len; + PStat(tpcb, Nb_from_sess) += totlen; tpmeas(tpcb->tp_lref, TPtime_from_session, 0, 0, - PStat(tpcb, Nb_from_sess), len); + PStat(tpcb, Nb_from_sess), totlen); ENDPERF IFDEBUG(D_SYSCALL) printf( "PRU_SEND: eot %d before sbappend 0x%x len 0x%x to sb @ 0x%x\n", - eotsdu, m,len, &sb->sb_mb); + eotsdu, m,len, sb); dump_mbuf(sb->sb_mb, "so_snd.sb_mb"); dump_mbuf(m, "m : to be added"); ENDDEBUG - /* The last mbuf has type TPMT_EOT so it will never be compressed - * with TPMT_DATA mbufs, but if this was an EOTSDU request w/o - * any data, the only way to keep this mbuf from being thrown - * away is to link it through the m_act field - * We are ASSUMING that if there are any data at all with this - * request, the last mbuf will be non-empty!!! + /* + * Pre-packetize the data in the sockbuf + * according to negotiated mtu. Do it here + * where we can safely wait for mbufs. */ - if( m->m_type == TPMT_EOT ) /* first mbuf in chain is EOT? */ - sbappendrecord(sb, m); /* to keep 2 TPMT_EOTs from being - compressed */ - else - sbappend(sb, m); + while (n->m_pkthdr.len > maxsize) { + struct mbuf *nn + = m_copym(n, 0, maxsize, M_WAIT); + if (eotsdu) + n->m_flags &= ~M_EOR; + sbappendrecord(sb, nn); + m_adj(n, maxsize); + } + sbappendrecord(sb, n); IFDEBUG(D_SYSCALL) printf("PRU_SEND: eot %d after sbappend 0x%x len 0x%x\n", - eotsdu, m,len); + eotsdu, n, len); dump_mbuf(sb->sb_mb, "so_snd.sb_mb"); ENDDEBUG - u.u_r.r_val1 += len; error = DoEvent(T_DATA_req); IFDEBUG(D_SYSCALL) printf("PRU_SEND: after driver error 0x%x \n",error); + printf("so_snd 0x%x cc 0t%d mbcnt 0t%d\n", + sb, sb->sb_cc, sb->sb_mbcnt); + dump_mbuf(sb->sb_mb, "so_snd.sb_mb after driver"); ENDDEBUG } break; - case PRU_SOCKADDR: { - struct sockaddr *sa = mtod(nam, struct sockaddr *); - - nam->m_len = sizeof (struct sockaddr); - (tpcb->tp_nlproto->nlp_getnetaddr)(so->so_pcb, sa, TP_LOCAL); - switch ( sa->sa_family = sototpcb(so)->tp_domain ) { - case AF_INET: - satosin(sa)->sin_port = - (tpcb->tp_nlproto->nlp_getsufx)(so->so_pcb, TP_LOCAL); - break; - case AF_ISO: - satosiso(sa)->siso_tsuffix = - (tpcb->tp_nlproto->nlp_getsufx)(so->so_pcb, TP_LOCAL); - break; - } - } + case PRU_SOCKADDR: + (tpcb->tp_nlproto->nlp_getnetaddr)(so->so_pcb, nam, TP_LOCAL); break; case PRU_PEERADDR: - if( (so->so_state & SS_ISCONNECTED) && - (so->so_state & SS_ISDISCONNECTING) == 0) { - struct sockaddr *sa = mtod(nam, struct sockaddr *); - - nam->m_len = sizeof (struct sockaddr); - - (tpcb->tp_nlproto->nlp_getnetaddr)(so->so_pcb, sa, TP_FOREIGN); - - switch ( sa->sa_family = sototpcb(so)->tp_domain ) { - case AF_INET: - satosin(sa)->sin_port = - (tpcb->tp_nlproto->nlp_getsufx)(so->so_pcb, TP_FOREIGN); - break; - case AF_ISO: - satosiso(sa)->siso_tsuffix = - (tpcb->tp_nlproto->nlp_getsufx)(so->so_pcb, TP_FOREIGN); - break; - } - IFDEBUG(D_REQUEST) - printf("PEERADDDR:"); - dump_buf(sa, sizeof(struct sockaddr)); - ENDDEBUG + if ((so->so_state & SS_ISCONNECTED) && + (so->so_state & SS_ISDISCONNECTING) == 0) { + (tpcb->tp_nlproto->nlp_getnetaddr)(so->so_pcb, nam, TP_FOREIGN); + IFDEBUG(D_REQUEST) + printf("PEERADDDR:"); + dump_buf(mtod(nam, char *), nam->m_len); + ENDDEBUG } else error = ENOTCONN; break; @@ -782,3 +713,43 @@ tp_usrreq(so, req, m, nam, rightsp, outflags) splx(s); return error; } + +/* + * Stub for future negotiated confirmation of connections. + */ +tp_confirm() +{ +} + +/* + * Process control data sent with sendmsg() + */ +tp_snd_control(m0, so, data) + register struct mbuf *m0; + struct socket *so; + register struct mbuf **data; +{ + register struct tp_control_hdr *ch; + struct mbuf *m; + int error = 0; + + if (m0 && m0->m_len) { + ch = mtod(m0, struct tp_control_hdr *); + m0->m_len -= sizeof (*ch); + m0->m_data += sizeof (*ch); + m = m_copym(m0, 0, M_COPYALL, M_WAIT); + error = tp_ctloutput(PRCO_SETOPT, + so, ch->cmsg_level, ch->cmsg_type, &m); + if (m) + m_freem(m); + if (ch->cmsg_type == TPOPT_DISC_DATA) { + if (data && *data) { + m_freem(*data); + *data = 0; + } + m0 = 0; + error = tp_usrreq(so, PRU_DISCONNECT, m0, (caddr_t)0, m0, m0); + } + } + return error; +} -- 2.20.1