2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
23 * Copyright (c) 1991, 1993
24 * The Regents of the University of California. All rights reserved.
26 * Redistribution and use in source and binary forms, with or without
27 * modification, are permitted provided that the following conditions
29 * 1. Redistributions of source code must retain the above copyright
30 * notice, this list of conditions and the following disclaimer.
31 * 2. Redistributions in binary form must reproduce the above copyright
32 * notice, this list of conditions and the following disclaimer in the
33 * documentation and/or other materials provided with the distribution.
34 * 3. All advertising materials mentioning features or use of this software
35 * must display the following acknowledgement:
36 * This product includes software developed by the University of
37 * California, Berkeley and its contributors.
38 * 4. Neither the name of the University nor the names of its contributors
39 * may be used to endorse or promote products derived from this software
40 * without specific prior written permission.
42 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
43 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
45 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
46 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
47 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
48 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
49 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
50 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
51 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
54 * @(#)tp_subr2.c 8.1 (Berkeley) 6/10/93
57 /***********************************************************
58 Copyright IBM Corporation 1987
62 Permission to use, copy, modify, and distribute this software and its
63 documentation for any purpose and without fee is hereby granted,
64 provided that the above copyright notice appear in all copies and that
65 both that copyright notice and this permission notice appear in
66 supporting documentation, and that the name of IBM not be
67 used in advertising or publicity pertaining to distribution of the
68 software without specific, written prior permission.
70 IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
71 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
72 IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
73 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
74 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
75 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
78 ******************************************************************/
81 * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
86 * Some auxiliary routines:
87 * tp_protocol_error: required by xebec- called when a combo of state,
88 * event, predicate isn't covered for by the transition file.
89 * tp_indicate: gives indications(signals) to the user process
90 * tp_getoptions: initializes variables that are affected by the options
94 /* this def'n is to cause the expansion of this macro in the
95 * routine tp_local_credit :
97 #define LOCAL_CREDIT_EXPAND
99 #include <sys/param.h>
100 #include <sys/systm.h>
101 #include <sys/mbuf.h>
102 #include <sys/socket.h>
103 #include <sys/socketvar.h>
104 #include <sys/domain.h>
105 #include <sys/protosw.h>
106 #include <sys/errno.h>
107 #include <sys/time.h>
108 #include <sys/kernel.h>
111 #include <netiso/argo_debug.h>
112 #include <netiso/tp_param.h>
113 #include <netiso/tp_ip.h>
114 #include <netiso/iso.h>
115 #include <netiso/iso_errno.h>
116 #include <netiso/iso_pcb.h>
117 #include <netiso/tp_timer.h>
118 #include <netiso/tp_stat.h>
119 #include <netiso/tp_tpdu.h>
120 #include <netiso/tp_pcb.h>
121 #include <netiso/tp_seq.h>
122 #include <netiso/tp_trace.h>
123 #include <netiso/tp_user.h>
124 #include <netiso/cons.h>
127 #include <net/if_types.h>
132 #include <netccitt/x25.h>
133 #include <netccitt/pk.h>
134 #include <netccitt/pk_var.h>
139 * NAME: tp_local_credit()
142 * tp_emit(), tp_usrreq()
144 * FUNCTION and ARGUMENTS:
145 * Computes the local credit and stashes it in tpcb->tp_lcredit.
146 * It's a macro in the production system rather than a procdure.
153 * This doesn't actually get called in a production system -
154 * the macro gets expanded instead in place of calls to this proc.
155 * But for debugging, we call this and that allows us to add
156 * debugging messages easily here.
159 tp_local_credit(tpcb
)
164 printf("ref 0x%x lcdt 0x%x l_tpdusize 0x%x decbit 0x%x\n",
173 tptraceTPCB(TPPTmisc
,
175 tpcb
->tp_lcredit
, tpcb
->tp_l_tpdusize
, 0, 0);
180 * NAME: tp_protocol_error()
183 * tp_driver(), when it doesn't know what to do with
184 * a combo of event, state, predicate
186 * FUNCTION and ARGUMENTS:
197 tp_protocol_error(e
,tpcb
)
201 printf("TP PROTOCOL ERROR! tpcb 0x%x event 0x%x, state 0x%x\n",
202 tpcb
, e
->ev_number
, tpcb
->tp_state
);
204 tptraceTPCB(TPPTmisc
, "PROTOCOL ERROR tpcb event state",
205 tpcb
, e
->ev_number
, tpcb
->tp_state
, 0 );
207 return EIO
; /* for lack of anything better */
211 /* Not used at the moment */
220 * NAME: tp_indicate()
223 * tp.trans when XPD arrive, when a connection is being disconnected by
224 * the arrival of a DR or ER, and when a connection times out.
226 * FUNCTION and ARGUMENTS:
227 * (ind) is the type of indication : T_DISCONNECT, T_XPD
228 * (error) is an E* value that will be put in the socket structure
229 * to be passed along to the user later.
230 * Gives a SIGURG to the user process or group indicated by the socket
231 * attached to the tpcb.
240 tp_indicate(ind
, tpcb
, error
)
243 register struct tp_pcb
*tpcb
;
245 register struct socket
*so
= tpcb
->tp_sock
;
246 IFTRACE(D_INDICATION
)
247 tptraceTPCB(TPPTindicate
, ind
, *(u_short
*)(tpcb
->tp_lsuffix
),
248 *(u_short
*)(tpcb
->tp_fsuffix
), error
,so
->so_pgid
);
250 IFDEBUG(D_INDICATION
)
252 ls
= tpcb
->tp_lsuffix
,
253 fs
= tpcb
->tp_fsuffix
,
256 "indicate 0x%x lsuf 0x%02x%02x fsuf 0x%02x%02x err 0x%x noind 0x%x ref 0x%x\n",
258 *ls
, *(ls
+1), *fs
, *(fs
+1),
259 error
, /*so->so_pgrp,*/
260 tpcb
->tp_no_disc_indications
,
264 if (ind
== ER_TPDU
) {
265 register struct mbuf
*m
;
266 struct tp_disc_reason x
;
268 if ((so
->so_state
& SS_CANTRCVMORE
) == 0 &&
269 (m
= m_get(M_DONTWAIT
, MT_OOBDATA
)) != 0) {
271 x
.dr_hdr
.cmsg_len
= m
->m_len
= sizeof(x
);
272 x
.dr_hdr
.cmsg_level
= SOL_TRANSPORT
;
273 x
.dr_hdr
.cmsg_type
= TPOPT_DISC_REASON
;
275 *mtod(m
, struct tp_disc_reason
*) = x
;
276 sbappendrecord(&tpcb
->tp_Xrcv
, m
);
281 so
->so_error
= error
;
283 if (ind
== T_DISCONNECT
) {
285 so
->so_error
= ENOTCONN
;
286 if ( tpcb
->tp_no_disc_indications
)
289 IFTRACE(D_INDICATION
)
290 tptraceTPCB(TPPTmisc
, "doing sohasoutofband(so)", so
,0,0,0);
296 * NAME : tp_getoptions()
299 * tp.trans whenever we go into OPEN state
301 * FUNCTION and ARGUMENTS:
302 * sets the proper flags and values in the tpcb, to control
303 * the appropriate actions for the given class, options,
304 * sequence space, etc, etc.
317 tpcb
->tp_xtd_format
? TP_XTD_FMT_MASK
: TP_NML_FMT_MASK
;
319 tpcb
->tp_xtd_format
? TP_XTD_FMT_BIT
: TP_NML_FMT_BIT
;
320 tpcb
->tp_seqhalf
= tpcb
->tp_seqbit
>> 1;
322 max(tpcb
->tp_dt_ticks
, (tpcb
->tp_peer_acktime
+ 2));
328 * NAME: tp_recycle_tsuffix()
331 * Called when a ref is frozen.
333 * FUNCTION and ARGUMENTS:
334 * allows the suffix to be reused.
343 tp_recycle_tsuffix(tpcb
)
346 bzero((caddr_t
)tpcb
->tp_lsuffix
, sizeof( tpcb
->tp_lsuffix
));
347 bzero((caddr_t
)tpcb
->tp_fsuffix
, sizeof( tpcb
->tp_fsuffix
));
348 tpcb
->tp_fsuffixlen
= tpcb
->tp_lsuffixlen
= 0;
350 (tpcb
->tp_nlproto
->nlp_recycle_suffix
)(tpcb
->tp_npcb
);
357 * tp{af}_quench() when ICMP source quench or similar thing arrives.
359 * FUNCTION and ARGUMENTS:
360 * Drop the congestion window back to 1.
361 * Congestion window scheme:
362 * Initial value is 1. ("slow start" as Nagle, et. al. call it)
363 * For each good ack that arrives, the congestion window is increased
364 * by 1 (up to max size of logical infinity, which is to say,
365 * it doesn't wrap around).
366 * Source quench causes it to drop back to 1.
367 * tp_send() uses the smaller of (regular window, congestion window).
368 * One retransmission strategy option is to have any retransmission
369 * cause reset the congestion window back to 1.
371 * (cmd) is either PRC_QUENCH: source quench, or
372 * PRC_QUENCH2: dest. quench (dec bit)
381 tp_quench( tpcb
, cmd
)
386 printf("tp_quench tpcb 0x%x ref 0x%x sufx 0x%x\n",
387 tpcb
, tpcb
->tp_lref
, *(u_short
*)(tpcb
->tp_lsuffix
));
388 printf("cong_win 0x%x decbit 0x%x \n",
389 tpcb
->tp_cong_win
, tpcb
->tp_decbit
);
393 tpcb
->tp_cong_win
= tpcb
->tp_l_tpdusize
;
397 tpcb
->tp_cong_win
= tpcb
->tp_l_tpdusize
; /* might as well quench source also */
398 tpcb
->tp_decbit
= TP_DECBIT_CLEAR_COUNT
;
399 IncStat(ts_rcvdecbit
);
410 * FUNCTION and ARGUMENTS:
418 tp_netcmd( tpcb
, cmd
)
426 if (tpcb
->tp_netservice
!= ISO_CONS
)
428 isop
= (struct isopcb
*)tpcb
->tp_npcb
;
429 lcp
= (struct pklcd
*)isop
->isop_chan
;
434 if (isop
->isop_refcnt
== 1) {
435 /* This is really superfluous, since it would happen
436 anyway in iso_pcbdetach, although it is a courtesy
437 to free up the x.25 channel before the refwait timer
443 isop
->isop_refcnt
= 0;
448 printf("tp_netcmd(0x%x, 0x%x) NOT IMPLEMENTED\n", tpcb
, cmd
);
452 printf("tp_netcmd(): X25 NOT CONFIGURED!!\n");
457 * tp_ctloutput() and tp_emit()
458 * FUNCTION and ARGUMENTS:
459 * Convert a class mask to the highest numeric value it represents.
468 for(j
= 4; j
>=0 ;j
--) {
472 ASSERT( (j
== 4) || (j
== 0) ); /* for now */
473 if( (j
!= 4) && (j
!= 0) ) {
474 printf("ASSERTION ERROR: tp_mask_to_num: x 0x%x j %d\n",
478 tptrace(TPPTmisc
, "tp_mask_to_num(x) returns j", x
, j
, 0, 0);
481 printf("tp_mask_to_num(0x%x) returns 0x%x\n", x
, j
);
487 copyQOSparms(src
, dst
)
488 struct tp_conn_param
*src
, *dst
;
490 /* copy all but the bits stuff at the end */
491 #define COPYSIZE (12 * sizeof(short))
493 bcopy((caddr_t
)src
, (caddr_t
)dst
, COPYSIZE
);
494 dst
->p_tpdusize
= src
->p_tpdusize
;
495 dst
->p_ack_strat
= src
->p_ack_strat
;
496 dst
->p_rx_strat
= src
->p_rx_strat
;
500 * Determine a reasonable value for maxseg size.
501 * If the route is known, check route for mtu.
502 * We also initialize the congestion/slow start
503 * window to be a single segment if the destination isn't local.
504 * While looking at the routing entry, we also initialize other path-dependent
505 * parameters from pre-set or cached values in the routing entry.
508 tp_mss(tpcb
, nhdr_size
)
509 register struct tp_pcb
*tpcb
;
512 register struct rtentry
*rt
;
514 register int rtt
, mss
;
516 int i
, ssthresh
= 0, rt_mss
;
519 if (tpcb
->tp_ptpdusize
)
520 mss
= tpcb
->tp_ptpdusize
<< 7;
522 mss
= 1 << tpcb
->tp_tpdusize
;
524 if ((rt
= *(tpcb
->tp_routep
)) == 0) {
525 bufsize
= so
->so_rcv
.sb_hiwat
;
530 #ifdef RTV_MTU /* if route characteristics exist ... */
532 * While we're here, check if there's an initial rtt
533 * or rttvar. Convert from the route-table units
534 * to hz ticks for the smoothed timers and slow-timeout units
535 * for other inital variables.
537 if (tpcb
->tp_rtt
== 0 && (rtt
= rt
->rt_rmx
.rmx_rtt
)) {
538 tpcb
->tp_rtt
= rtt
* hz
/ RTM_RTTUNIT
;
539 if (rt
->rt_rmx
.rmx_rttvar
)
540 tpcb
->tp_rtv
= rt
->rt_rmx
.rmx_rttvar
543 tpcb
->tp_rtv
= tpcb
->tp_rtt
;
546 * if there's an mtu associated with the route, use it
548 if (rt
->rt_rmx
.rmx_mtu
)
549 rt_mss
= rt
->rt_rmx
.rmx_mtu
- nhdr_size
;
552 rt_mss
= (ifp
->if_mtu
- nhdr_size
);
553 if (tpcb
->tp_ptpdusize
== 0 || /* assume application doesn't care */
554 mss
> rt_mss
/* network won't support what was asked for */)
556 /* can propose mtu which are multiples of 128 */
559 * If there's a pipesize, change the socket buffer
563 if ((bufsize
= rt
->rt_rmx
.rmx_sendpipe
) > 0) {
565 bufsize
= min(bufsize
, so
->so_snd
.sb_hiwat
);
566 (void) sbreserve(&so
->so_snd
, bufsize
);
569 if ((bufsize
= rt
->rt_rmx
.rmx_recvpipe
) > 0) {
571 bufsize
= min(bufsize
, so
->so_rcv
.sb_hiwat
);
572 (void) sbreserve(&so
->so_rcv
, bufsize
);
574 bufsize
= so
->so_rcv
.sb_hiwat
;
577 * There's some sort of gateway or interface
578 * buffer limit on the path. Use this to set
579 * the slow start threshhold, but set the
580 * threshold to no less than 2*mss.
582 ssthresh
= rt
->rt_rmx
.rmx_ssthresh
;
585 * The current mss is initialized to the default value.
586 * If we compute a smaller value, reduce the current mss.
587 * If we compute a larger value, return it for use in sending
588 * a max seg size option.
589 * If we received an offer, don't exceed it.
590 * However, do not accept offers under 128 bytes.
592 if (tpcb
->tp_l_tpdusize
)
593 mss
= min(mss
, tpcb
->tp_l_tpdusize
);
595 * We want a minimum recv window of 4 packets to
596 * signal packet loss by duplicate acks.
598 mss
= min(mss
, bufsize
>> 2) & ~0x7f;
599 mss
= max(mss
, 128); /* sanity */
601 (rt
== 0 || (rt
->rt_flags
& RTF_GATEWAY
)) ? mss
: bufsize
;
602 tpcb
->tp_l_tpdusize
= mss
;
604 tpcb
->tp_ssthresh
= max(2 * mss
, ssthresh
);
605 /* Calculate log2 of mss */
606 for (i
= TP_MIN_TPDUSIZE
+ 1; i
<= TP_MAX_TPDUSIZE
; i
++)
610 tpcb
->tp_tpdusize
= i
;
616 * tp_usrreq on PRU_CONNECT and tp_input on receipt of CR
618 * FUNCTION and ARGUMENTS:
619 * -- An mbuf containing the peer's network address.
620 * -- Our control block, which will be modified
621 * -- In the case of cons, a control block for that layer.
626 * EAFNOSUPPORT if can't find an nl_protosw for x.25 (really could panic)
627 * ECONNREFUSED if trying to run TP0 with non-type 37 address
628 * possibly other E* returned from cons_netcmd()
631 * Determines recommended tpdusize, buffering and intial delays
632 * based on information cached on the route.
635 tp_route_to( m
, tpcb
, channel
)
637 register struct tp_pcb
*tpcb
;
640 register struct sockaddr_iso
*siso
; /* NOTE: this may be a sockaddr_in */
641 extern struct tp_conn_param tp_conn_param
[];
642 int error
= 0, save_netservice
= tpcb
->tp_netservice
;
643 register struct rtentry
*rt
= 0;
644 int nhdr_size
, mtu
, bufsize
;
646 siso
= mtod(m
, struct sockaddr_iso
*);
648 tptraceTPCB(TPPTmisc
,
649 "route_to: so afi netservice class",
650 tpcb
->tp_sock
, siso
->siso_addr
.isoa_genaddr
[0], tpcb
->tp_netservice
,
654 printf("tp_route_to( m x%x, channel 0x%x, tpcb 0x%x netserv 0x%x)\n",
655 m
, channel
, tpcb
, tpcb
->tp_netservice
);
656 printf("m->mlen x%x, m->m_data:\n", m
->m_len
);
657 dump_buf(mtod(m
, caddr_t
), m
->m_len
);
661 struct pklcd
*lcp
= (struct pklcd
*)channel
;
662 struct isopcb
*isop
= (struct isopcb
*)lcp
->lcd_upnext
,
663 *isop_new
= (struct isopcb
*)tpcb
->tp_npcb
;
664 /* The next 2 lines believe that you haven't
665 set any network level options or done a pcbconnect
666 and XXXXXXX'edly apply to both inpcb's and isopcb's */
668 FREE(isop_new
, M_PCB
);
669 tpcb
->tp_npcb
= (caddr_t
)isop
;
670 tpcb
->tp_netservice
= ISO_CONS
;
671 tpcb
->tp_nlproto
= nl_protosw
+ ISO_CONS
;
672 if (isop
->isop_refcnt
++ == 0) {
673 iso_putsufx(isop
, tpcb
->tp_lsuffix
, tpcb
->tp_lsuffixlen
, TP_LOCAL
);
674 isop
->isop_socket
= tpcb
->tp_sock
;
676 /* there are already connections sharing this */;
679 switch (siso
->siso_family
) {
681 error
= EAFNOSUPPORT
;
686 struct isopcb
*isop
= (struct isopcb
*)tpcb
->tp_npcb
;
687 int flags
= tpcb
->tp_sock
->so_options
& SO_DONTROUTE
;
688 tpcb
->tp_netservice
= ISO_CLNS
;
689 if (clnp_route(&siso
->siso_addr
, &isop
->isop_route
,
690 flags
, (void **)0, (void **)0) == 0) {
691 rt
= isop
->isop_route
.ro_rt
;
692 if (rt
&& rt
->rt_flags
& RTF_PROTO1
)
693 tpcb
->tp_netservice
= ISO_CONS
;
699 tpcb
->tp_netservice
= IN_CLNS
;
702 if (tpcb
->tp_nlproto
->nlp_afamily
!= siso
->siso_family
) {
704 printf("tp_route_to( CHANGING nlproto old 0x%x new 0x%x)\n",
705 save_netservice
, tpcb
->tp_netservice
);
707 if (error
= tp_set_npcb(tpcb
))
711 printf("tp_route_to calling nlp_pcbconn, netserv %d\n",
712 tpcb
->tp_netservice
);
714 tpcb
->tp_nlproto
= nl_protosw
+ tpcb
->tp_netservice
;
715 error
= (tpcb
->tp_nlproto
->nlp_pcbconn
)(tpcb
->tp_npcb
, m
);
719 nhdr_size
= tpcb
->tp_nlproto
->nlp_mtu(tpcb
); /* only gets common info */
720 tp_mss(tpcb
, nhdr_size
);
723 printf("tp_route_to returns 0x%x\n", error
);
726 tptraceTPCB(TPPTmisc
, "route_to: returns: error netserv class", error
,
727 tpcb
->tp_netservice
, tpcb
->tp_class
, 0);
733 /* class zero version */
736 register struct tp_pcb
*tpcb
;
737 register struct tp_event
*e
;
740 #define E e->ATTR(DT_TPDU)
742 #define E e->ev_union.EV_DT_TPDU
745 register struct sockbuf
*sb
= &tpcb
->tp_sock
->so_rcv
;
746 register struct isopcb
*isop
= (struct isopcb
*)tpcb
->tp_npcb
;
749 PStat(tpcb
, Nb_from_ll
) += E
.e_datalen
;
750 tpmeas(tpcb
->tp_lref
, TPtime_from_ll
, &e
->e_time
,
751 E
.e_seq
, PStat(tpcb
, Nb_from_ll
), E
.e_datalen
);
755 printf("stash EQ: seq 0x%x datalen 0x%x eot 0x%x",
756 E
.e_seq
, E
.e_datalen
, E
.e_eot
);
760 tptraceTPCB(TPPTmisc
, "stash EQ: seq len eot",
761 E
.e_seq
, E
.e_datalen
, E
.e_eot
, 0);
765 register struct mbuf
*n
= E
.e_data
;
767 n
->m_act
= MNULL
; /* set on tp_input */
769 sbappend(sb
, E
.e_data
);
771 dump_mbuf(sb
->sb_mb
, "stash 0: so_rcv after appending");
773 if (tpcb
->tp_netservice
!= ISO_CONS
)
774 printf("tp0_stash: tp running over something wierd\n");
776 register struct pklcd
*lcp
= (struct pklcd
*)isop
->isop_chan
;
777 pk_flowcontrol(lcp
, sbspace(sb
) <= 0, 1);
783 register struct tp_pcb
*tpcb
;
785 register struct isopcb
*isop
= (struct isopcb
*)tpcb
->tp_npcb
;
786 if (tpcb
->tp_netservice
!= ISO_CONS
)
787 printf("tp0_openflow: tp running over something wierd\n");
789 register struct pklcd
*lcp
= (struct pklcd
*)isop
->isop_chan
;
790 if (lcp
->lcd_rxrnr_condition
)
791 pk_flowcontrol(lcp
, 0, 0);
802 * tp_ctloutput() when the user sets TPOPT_PERF_MEAS on
803 * and tp_newsocket() when a new connection is made from
804 * a listening socket with tp_perf_on == true.
805 * FUNCTION and ARGUMENTS:
806 * (tpcb) is the usual; this procedure gets a clear cluster mbuf for
807 * a tp_pmeas structure, and makes tpcb->tp_p_meas point to it.
809 * ENOBUFS if it cannot get a cluster mbuf.
814 register struct tp_pcb
*tpcb
;
816 register struct mbuf
*q
;
818 if( tpcb
->tp_p_meas
== 0 ) {
819 MGET(q
, M_WAIT
, MT_PCB
);
823 if ((q
->m_flags
& M_EXT
) == 0) {
827 q
->m_len
= sizeof (struct tp_pmeas
);
829 tpcb
->tp_p_meas
= mtod(q
, struct tp_pmeas
*);
830 bzero( (caddr_t
)tpcb
->tp_p_meas
, sizeof (struct tp_pmeas
) );
833 "tpcb 0x%x so 0x%x ref 0x%x tp_p_meas 0x%x tp_perf_on 0x%x\n",
834 tpcb
, tpcb
->tp_sock
, tpcb
->tp_lref
,
835 tpcb
->tp_p_meas
, tpcb
->tp_perf_on
);
837 tpcb
->tp_perf_on
= 1;
841 #endif /* TP_PERF_MEAS */
845 register struct sockaddr
*addr
;
847 switch( addr
->sa_family
) {
849 dump_inaddr((struct sockaddr_in
*)addr
);
853 dump_isoaddr((struct sockaddr_iso
*)addr
);
857 printf("BAD AF: 0x%x\n", addr
->sa_family
);
862 #define MAX_COLUMNS 8
864 * Dump the buffer to the screen in a readable format. Format is:
866 * hex/dec where hex is the hex format, dec is the decimal format.
867 * columns of hex/dec numbers will be printed, followed by the
868 * character representations (if printable).
875 #define Buf ((u_char *)buf)
876 printf("Dump buf 0x%x len 0x%x\n", buf
, len
);
877 for (i
= 0; i
< len
; i
+= MAX_COLUMNS
) {
879 for (j
= 0; j
< MAX_COLUMNS
; j
++) {
881 printf("%x/%d\t", Buf
[i
+j
], Buf
[i
+j
]);
887 for (j
= 0; j
< MAX_COLUMNS
; j
++) {
889 if (((Buf
[i
+j
]) > 31) && ((Buf
[i
+j
]) < 128))
890 printf("%c", Buf
[i
+j
]);
898 #endif /* ARGO_DEBUG */