SCCS-vsn: sys/netccitt/ccitt_proto.c 7.4
SCCS-vsn: sys/netccitt/hd_input.c 7.3
SCCS-vsn: sys/netccitt/hd_output.c 7.3
SCCS-vsn: sys/netccitt/hd_subr.c 7.3
SCCS-vsn: sys/netccitt/hd_var.h 7.3
SCCS-vsn: sys/netccitt/pk_input.c 7.4
SCCS-vsn: sys/netccitt/pk_output.c 7.4
SCCS-vsn: sys/netccitt/pk_subr.c 7.5
SCCS-vsn: sys/netccitt/pk_usrreq.c 7.6
SCCS-vsn: sys/netccitt/pk_var.h 7.5
SCCS-vsn: sys/netccitt/x25.h 7.4
SCCS-vsn: sys/netccitt/if_x25subr.c 7.5
*
* %sccs.include.redist.c%
*
*
* %sccs.include.redist.c%
*
- * @(#)ccitt_proto.c 7.3 (Berkeley) %G%
+ * @(#)ccitt_proto.c 7.4 (Berkeley) %G%
*/
#include "../h/param.h"
*/
#include "../h/param.h"
#ifdef HDLC
int hd_output (), hd_ctlinput (), hd_init (), hd_timer ();
#endif
#ifdef HDLC
int hd_output (), hd_ctlinput (), hd_init (), hd_timer ();
#endif
-int pk_usrreq (), pk_timer ();
+int pk_usrreq (), pk_timer (), pk_init ();
struct protosw ccittsw[] = {
#ifdef XE
struct protosw ccittsw[] = {
#ifdef XE
{ SOCK_STREAM, DOMAIN, CCITTPROTO_X25, PR_CONNREQUIRED|PR_ATOMIC|PR_WANTRCVD,
0, 0, 0, 0,
pk_usrreq,
{ SOCK_STREAM, DOMAIN, CCITTPROTO_X25, PR_CONNREQUIRED|PR_ATOMIC|PR_WANTRCVD,
0, 0, 0, 0,
pk_usrreq,
+ pk_init, 0, pk_timer, 0,
*
* %sccs.include.redist.c%
*
*
* %sccs.include.redist.c%
*
- * @(#)hd_input.c 7.2 (Berkeley) %G%
+ * @(#)hd_input.c 7.3 (Berkeley) %G%
*/
#include "../h/param.h"
*/
#include "../h/param.h"
hdp->hd_rrtimer = hd_t3;
/* Forward iframe to packet level of X.25. */
hdp->hd_rrtimer = hd_t3;
/* Forward iframe to packet level of X.25. */
- fbuf -> m_off += HDHEADERLN;
+ fbuf -> m_data += HDHEADERLN;
fbuf -> m_len -= HDHEADERLN;
#ifdef BSD4_3
fbuf->m_act = 0; /* probably not necessary */
fbuf -> m_len -= HDHEADERLN;
#ifdef BSD4_3
fbuf->m_act = 0; /* probably not necessary */
*
* %sccs.include.redist.c%
*
*
* %sccs.include.redist.c%
*
- * @(#)hd_output.c 7.2 (Berkeley) %G%
+ * @(#)hd_output.c 7.3 (Berkeley) %G%
*/
#include "../h/param.h"
*/
#include "../h/param.h"
* by the input and control routines of the HDLC layer.
*/
* by the input and control routines of the HDLC layer.
*/
-hd_output (m, xcp)
-struct x25config *xcp;
- register struct hdcb *hdp;
- static struct x25config *lastxcp;
- static struct hdcb *lasthdp;
+ register struct hdcb *hdp = (struct hdcb *)info;
+ struct x25config *xcp;
if (m == NULL)
panic ("hd_output");
if (m == NULL)
panic ("hd_output");
- if (xcp == lastxcp)
- hdp = lasthdp;
- else {
- for (hdp = hdcbhead; ; hdp = hdp->hd_next) {
- if (hdp == 0) {
- printf("hd_output: can't find hdcb for %X\n", xcp);
- m_freem (m);
- return;
- }
- if (hdp->hd_xcp == xcp)
- break;
- }
- lastxcp = xcp;
- lasthdp = hdp;
- }
-
if (hdp->hd_state != ABM) {
m_freem (m);
return;
if (hdp->hd_state != ABM) {
m_freem (m);
return;
* of the first mbuf in the mbuf chain.
*/
* of the first mbuf in the mbuf chain.
*/
- if (m->m_off < MMINOFF + HDHEADERLN) {
- register struct mbuf *m0;
-
- m0 = m_get (M_DONTWAIT, MT_DATA);
- if (m0 == NULL) {
- m_freem (m);
- return;
- }
- m0->m_next = m;
- m0->m_len = HDHEADERLN;
- m = m0;
- } else {
- m->m_off -= HDHEADERLN;
- m->m_len += HDHEADERLN;
- }
+ M_PREPEND(m, M_DONTWAIT, HDHEADERLN);
+ if (m == NULL)
+ return;
hd_append (&hdp->hd_txq, m);
hd_start (hdp);
hd_append (&hdp->hd_txq, m);
hd_start (hdp);
int poll_bit;
{
register struct Hdlc_iframe *iframe;
int poll_bit;
{
register struct Hdlc_iframe *iframe;
- register struct ifnet *ifp = hdp->hd_ifp;
printf("hdlc: out of mbufs\n");
return;
}
printf("hdlc: out of mbufs\n");
return;
}
- (*ifp -> if_output) (ifp, m, (struct sockaddr *)hdp->hd_xcp);
-
+ (*hdp->hd_output)(hdp, m);
+hd_ifoutput(hdp, m)
+register struct hdcb *hdp;
+register struct mbuf *m;
+{
+ /*
+ * Queue message on interface, and start output if interface
+ * not yet active.
+ */
+ register struct ifnet *ifp = hdp->hdp_ifp;
+ int s = splimp();
+ if (IF_QFULL(&ifp->if_snd)) {
+ IF_DROP(&ifp->if_snd);
+ printf("%s%d: HDLC says OK to send but queue full, may hang\n",
+ ifp->if_name, ifp->if_unit);
+ m_freem(m);
+ } else {
+ IF_ENQUEUE(&ifp->if_snd, m);
+ if ((ifp->if_flags & IFF_OACTIVE) == 0)
+ (*ifp->if_start)(ifp);
+ }
+ splx(s);
+}
+
+
/*
* This routine gets control when the timer expires because we have not
* received an acknowledgement for a iframe.
/*
* This routine gets control when the timer expires because we have not
* received an acknowledgement for a iframe.
*
* %sccs.include.redist.c%
*
*
* %sccs.include.redist.c%
*
- * @(#)hd_subr.c 7.2 (Berkeley) %G%
+ * @(#)hd_subr.c 7.3 (Berkeley) %G%
*/
#include "../h/param.h"
*/
#include "../h/param.h"
uframe -> pf = pf;
hd_trace (hdp, TX, frame);
uframe -> pf = pf;
hd_trace (hdp, TX, frame);
- (*hdp -> hd_ifp -> if_output) (hdp -> hd_ifp, buf,
- (struct sockaddr *)hdp->hd_xcp);
-
+ (*hdp->hd_output)(hdp, buf);
*
* %sccs.include.redist.c%
*
*
* %sccs.include.redist.c%
*
- * @(#)hd_var.h 7.2 (Berkeley) %G%
+ * @(#)hd_var.h 7.3 (Berkeley) %G%
#define KILL_TIMER(hdp) hdp->hd_timer = 0
char hd_dontcopy; /* if-driver doesn't free I-frames */
struct ifnet *hd_ifp; /* device's network visible interface */
#define KILL_TIMER(hdp) hdp->hd_timer = 0
char hd_dontcopy; /* if-driver doesn't free I-frames */
struct ifnet *hd_ifp; /* device's network visible interface */
+ struct ifaddr *hd_ifa; /* device's X.25 network address */
+ int (*hd_output)(); /* separate entry for HDLC direct output */
struct x25config *hd_xcp; /* copy of &hdp->hd_if->if_addr */
/* link statistics */
struct x25config *hd_xcp; /* copy of &hdp->hd_if->if_addr */
/* link statistics */
*
* %sccs.include.redist.c%
*
*
* %sccs.include.redist.c%
*
- * @(#)if_x25subr.c 7.4 (Berkeley) %G%
+ * @(#)if_x25subr.c 7.5 (Berkeley) %G%
rtx->rtx_lcd = lcp;
rtx->rtx_rt = rt;
rtx->rtx_ia = ia;
rtx->rtx_lcd = lcp;
rtx->rtx_rt = rt;
rtx->rtx_ia = ia;
- lcp->lcd_upq.pq_next = (caddr_t)rtx;
- lcp->lcd_upq.pq_put = x25_ifinput;
+ lcp->lcd_upnext = (caddr_t)rtx;
+ lcp->lcd_upper = x25_ifinput;
switch (rtx->rtx_state) {
case XRS_CONNECTED:
lcd->lcd_dg_timer = ia->ia_xc.xc_dg_idletimo;
/* FALLTHROUGH */
case XRS_CONNECTING:
switch (rtx->rtx_state) {
case XRS_CONNECTED:
lcd->lcd_dg_timer = ia->ia_xc.xc_dg_idletimo;
/* FALLTHROUGH */
case XRS_CONNECTING:
+ if (sbspace(&lcp->lcd_sb) < 0)
ia->xc_if.if_type == IFT_DDN &&
rt->rt_gateway->sa_family != AF_CCITT)
x25_ddnip_to_ccitt(dst, rt->rt_gateway);
ia->xc_if.if_type == IFT_DDN &&
rt->rt_gateway->sa_family != AF_CCITT)
x25_ddnip_to_ccitt(dst, rt->rt_gateway);
- pq->pq_space = 2048; /* XXX: bogus pq before if_start called */
lcp->lcd_flags |= X25_DG_CIRCUIT;
rtx->rtx_state = XRS_FREE;
if (rt->rt_gateway->sa_family != AF_CCITT) {
lcp->lcd_flags |= X25_DG_CIRCUIT;
rtx->rtx_state = XRS_FREE;
if (rt->rt_gateway->sa_family != AF_CCITT) {
rtx->rtx_state = XRS_RESOLVING;
/* FALLTHROUGH */
case XRS_RESOLVING:
rtx->rtx_state = XRS_RESOLVING;
/* FALLTHROUGH */
case XRS_RESOLVING:
+ if (sbspace(&lcp->lcd_sb) < 0)
- pq->pq_space -= m->m_pkthdr.len;
- if (pq->pq_data == 0)
- pq->pq_data = m;
- else {
- for (m = pq->pq_data; m->m_nextpkt; )
- m = m->m_nextpkt;
- m->m_nextpkt = m0;
- }
+ sbappendrecord(&lcp->lcd_sb, m);
break;
}
/* FALLTHROUGH */
case XRS_FREE:
break;
}
/* FALLTHROUGH */
case XRS_FREE:
- lcp->lcd_downq.pq_data = m;
+ sbappendrecord(&lcp->lcd_sb, m);
lcp->lcd_pkcb = &(rtx->rtx_ia->ia_pkcb);
pk_connect(lcp, (struct mbuf *)0,
(struct sockaddr_x25 *)rt->rt_gateway);
lcp->lcd_pkcb = &(rtx->rtx_ia->ia_pkcb);
pk_connect(lcp, (struct mbuf *)0,
(struct sockaddr_x25 *)rt->rt_gateway);
register struct rtextension_x25 *rtx;
pk_disconnect(lcp);
rtx = (struct rtextension_x25 *)
register struct rtextension_x25 *rtx;
pk_disconnect(lcp);
rtx = (struct rtextension_x25 *)
if (rtx)
rtx->rtx_state = XRS_DISCONNECTING;
}
if (rtx)
rtx->rtx_state = XRS_DISCONNECTING;
}
/*
* Process a x25 packet as datagram;
*/
/*
* Process a x25 packet as datagram;
*/
-x25_ifinput(pq, m)
-struct pq *pq;
+x25_ifinput(lcp, m)
+struct pklcd *lcp;
- struct rtentry *rt = (struct rtentry *)pq->pq_next;
- struct pklcd *xl = (struct pklcd *)rt->rt_llinfo;
- register struct ifnet *ifp = &xl->xl_xc.xc_if;
- register struct llc *l;
+ struct rtextension *rtx = (struct rtentry *)lcp->lcd_upnext;
+ register struct ifnet *ifp = &rtx->rtx_rt->rt_ifp;
int s;
ifp->if_lastchange = time;
int s;
ifp->if_lastchange = time;
register struct x25_ifaddr *ia;
register struct sockaddr *sa2;
struct mbuf *m, *mold;
register struct x25_ifaddr *ia;
register struct sockaddr *sa2;
struct mbuf *m, *mold;
case caseof(XRS_CONNECTING, RTM_DELETE):
case caseof(XRS_CONNECTING, RTM_CHANGE):
pk_disconnect(lcp);
case caseof(XRS_CONNECTING, RTM_DELETE):
case caseof(XRS_CONNECTING, RTM_CHANGE):
pk_disconnect(lcp);
- lcp->lcd_upq.pq_unblock = x25_ifrtfree;
+ lcp->lcd_upper = x25_ifrtfree;
break;
case caseof(XRS_RESOLVING, RTM_DELETE):
break;
case caseof(XRS_RESOLVING, RTM_DELETE):
- for (m = lcp->lcd_downq.pq_data; m;) {
- mold = m;
- m = m->m_nextpkt;
- m_freem(mold);
- }
- m_free(dtom(rtx->rtx_lcd));
+ sbflush(&(rtx->rtx_lcd->lcd_sb));
+ free((caddr_t)rtx->rtx_lcd, M_PCB);
sa2 = SA(rt->rt_key);
if (cmd == RTM_CHANGE) {
if (sa->sa_family == AF_CCITT) {
sa2 = SA(rt->rt_key);
if (cmd == RTM_CHANGE) {
if (sa->sa_family == AF_CCITT) {
- sa->sa_rfamily = sa2->sa_family;
+ sa->x25_opts.op_speed = sa2->sa_family;
(void) rtrequest(RTM_DELETE, SA(sa), sa2,
SA(0), RTF_HOST, (struct rtentry **)0);
}
(void) rtrequest(RTM_DELETE, SA(sa), sa2,
SA(0), RTF_HOST, (struct rtentry **)0);
}
cmd = RTM_ADD;
}
if (sa->sa_family == AF_CCITT) {
cmd = RTM_ADD;
}
if (sa->sa_family == AF_CCITT) {
- sa->sa_rfamily = sa2->sa_family;
+ sa->x25_opts.op_speed = sa2->sa_family;
(void) rtrequest(cmd, SA(sa), sa2, SA(0), RTF_HOST,
(struct rtentry **)0);
(void) rtrequest(cmd, SA(sa), sa2, SA(0), RTF_HOST,
(struct rtentry **)0);
+ sa->x25_opts.op_speed = 0;
static struct sockaddr sin = {sizeof(sin), AF_INET};
/*
* This is a utility routine to be called by x25 devices when a
static struct sockaddr sin = {sizeof(sin), AF_INET};
/*
* This is a utility routine to be called by x25 devices when a
* This uses the X25 routing table to do inverse
* lookup of x25 address to sockaddr.
*/
* This uses the X25 routing table to do inverse
* lookup of x25 address to sockaddr.
*/
+ dst->x25_opts.op_speed = af;
if (rt = rtalloc1(dst, 0)) {
sa = rt->rt_gateway;
rt->rt_refcnt--;
}
if (rt = rtalloc1(dst, 0)) {
sa = rt->rt_gateway;
rt->rt_refcnt--;
}
+ dst->x25_opts.op_speed = 0;
}
/*
* Call to rtalloc1 will create rtentry for reverse path
}
/*
* Call to rtalloc1 will create rtentry for reverse path
if (sa && rt = rtalloc1(sa, 1))
rt->rt_refcnt--;
}
if (sa && rt = rtalloc1(sa, 1))
rt->rt_refcnt--;
}
+
+struct radix_tree_head *x25_rnhead;
+
+pk_init()
+{
+ /*
+ * warning, sizeof (struct sockaddr_x25) > 32,
+ * but contains no data of interest beyond 32
+ */
+ rn_inithead(&x25_rnhead, 16, AF_CCITT);
+}
*
* %sccs.include.redist.c%
*
*
* %sccs.include.redist.c%
*
- * @(#)pk_input.c 7.3 (Berkeley) %G%
+ * @(#)pk_input.c 7.4 (Berkeley) %G%
*/
#include "../h/param.h"
*/
#include "../h/param.h"
- m -> m_off += PKHEADERLN;
+ m -> m_data += PKHEADERLN;
m -> m_len -= PKHEADERLN;
if (lcp -> lcd_flags & X25_MQBIT) {
octet *t;
m -> m_len -= PKHEADERLN;
if (lcp -> lcd_flags & X25_MQBIT) {
octet *t;
m -> m_len += 1;
t = mtod (m, octet *);
*t = 0x00;
m -> m_len += 1;
t = mtod (m, octet *);
*t = 0x00;
errstr = "server malfunction";
break;
}
errstr = "server malfunction";
break;
}
- lcp -> lcd_upq.pq_put = lcp -> lcd_upq.pq_put;
+ lcp -> lcd_upper = l -> lcd_upper;
+ lcp -> lcd_upnext = l -> lcd_upnext;
lcp -> lcd_lcn = lcn;
lcp -> lcd_state = RECEIVED_CALL;
lcp -> lcd_craddr = sa;
lcp -> lcd_lcn = lcn;
lcp -> lcd_state = RECEIVED_CALL;
lcp -> lcd_craddr = sa;
~X25_REVERSE_CHARGE;
pk_assoc (pkp, lcp, sa);
lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_CALL_ACCEPTED);
~X25_REVERSE_CHARGE;
pk_assoc (pkp, lcp, sa);
lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_CALL_ACCEPTED);
- pk_output (lcp);
- if (so)
+ if (so) {
+ pk_output (lcp);
+ } else if (lcp->lcd_upper)
+ (*lcp->lcd_upper)(lcp);
*
* %sccs.include.redist.c%
*
*
* %sccs.include.redist.c%
*
- * @(#)pk_output.c 7.3 (Berkeley) %G%
+ * @(#)pk_output.c 7.4 (Berkeley) %G%
*/
#include "../h/param.h"
*/
#include "../h/param.h"
pk_trace (pkp -> pk_xcp, xp, "P-Out");
/* Pass the packet on down to the link layer */
pk_trace (pkp -> pk_xcp, xp, "P-Out");
/* Pass the packet on down to the link layer */
- (*pkp -> pk_lloutput) (m, pkp -> pk_xcp);
+ (*pkp -> pk_lloutput) (m, pkp -> llnext);
nextpk (lcp)
struct pklcd *lcp;
{
nextpk (lcp)
struct pklcd *lcp;
{
- register struct socket *so = lcp -> lcd_so;
- register struct mbuf *m = 0, *n;
+ register struct mbuf *m, *n;
+ struct socket *so = lcp -> lcd_so;
+ register struct sockbuf *sb = & (so ? so -> so_snd : lcp -> lcd_sb);
if (lcp -> lcd_template) {
m = dtom (lcp -> lcd_template);
if (lcp -> lcd_template) {
m = dtom (lcp -> lcd_template);
lcp -> lcd_reset_condition)
return (NULL);
lcp -> lcd_reset_condition)
return (NULL);
- if (so == 0) {
- if ((m = lcp->lcd_downq.pq_data) == 0)
- return (NULL);
- lcp->lcd_downq.pq_data = m->m_nextpkt;
- lcp->lcd_downq.pq_space += m->m_pkthdr.len;
- m->m_nextpkt = 0;
- return (m);
- }
-
- if ((m = so -> so_snd.sb_mb) == 0)
+ if ((m = sb -> sb_mb) == 0)
- n = m;
- while (n) {
- sbfree (&so -> so_snd, n);
- n = n -> m_next;
- }
-
- so->so_snd.sb_mb = m->m_act;
+ sb -> sb_mb = m -> m_nextpkt;
+ for (n = m; n; n = n -> m_next)
+ sbfree (sb, n);
*
* %sccs.include.redist.c%
*
*
* %sccs.include.redist.c%
*
- * @(#)pk_subr.c 7.4 (Berkeley) %G%
+ * @(#)pk_subr.c 7.5 (Berkeley) %G%
bzero((caddr_t)lcp, sizeof(*lcp));
if (so) {
error = soreserve (so, pk_sendspace, pk_recvspace);
bzero((caddr_t)lcp, sizeof(*lcp));
if (so) {
error = soreserve (so, pk_sendspace, pk_recvspace);
- so -> so_snd.sb_mbmax = pk_sendspace;
lcp -> lcd_so = so;
if (so -> so_options & SO_ACCEPTCONN)
lcp -> lcd_state = LISTEN;
else
lcp -> lcd_state = READY;
lcp -> lcd_so = so;
if (so -> so_options & SO_ACCEPTCONN)
lcp -> lcd_state = LISTEN;
else
lcp -> lcd_state = READY;
+ } else
+ sbreserve (&lcp -> lcd_sb, pk_sendpace);
}
if (so) {
so -> so_pcb = (caddr_t) lcp;
}
if (so) {
so -> so_pcb = (caddr_t) lcp;
if (so && ((so -> so_snd.sb_flags & SB_WAIT) || so -> so_snd.sb_sel))
sowwakeup (so);
if (so && ((so -> so_snd.sb_flags & SB_WAIT) || so -> so_snd.sb_sel))
sowwakeup (so);
- if (lcp -> lcd_downq.pq_unblock)
- (*lcp -> lcd_downq.pq_unblock)(lcp);
+ if (lcp -> lcd_upper)
+ (*lcp -> lcd_upper)(lcp, 0);
*
* %sccs.include.redist.c%
*
*
* %sccs.include.redist.c%
*
- * @(#)pk_usrreq.c 7.5 (Berkeley) %G%
+ * @(#)pk_usrreq.c 7.6 (Berkeley) %G%
- lcp -> lcp_downq.pq_put = pk_send;
+ lcp -> lcp_send = pk_send;
return (pk_output(lcp));
}
return (pk_output(lcp));
}
if (lcp -> lcd_so)
sbappendrecord (&lcp -> lcd_so -> so_snd, m0);
else
if (lcp -> lcd_so)
sbappendrecord (&lcp -> lcd_so -> so_snd, m0);
else
- pq_appendrecord (&lcp -> lcd_downq, m0);
+ sbappendrecord (&lcp -> lcd_sb, m0);
lcp -> lcd_template = 0;
lcp -> lcd_txcnt++;
pk_output (lcp);
lcp -> lcd_template = 0;
lcp -> lcd_txcnt++;
pk_output (lcp);
*
* %sccs.include.redist.c%
*
*
* %sccs.include.redist.c%
*
- * @(#)pk_var.h 7.4 (Berkeley) %G%
+ * @(#)pk_var.h 7.5 (Berkeley) %G%
-/*
- * Protocol-Protocol Packet Buffer.
- * (Eventually will be replace by system-wide structure).
- */
-
-struct pq {
- int (*pq_put)(); /* How to process data */
- struct mbuf *pq_data; /* Queued data */
- int pq_space; /* For accounting */
- int pq_flags;
- int (*pq_unblock)();/* called & cleared when unblocking */
- caddr_t pq_proto; /* for other service entries */
- caddr_t pq_next; /* next q, or route, or pcb */
-};
- struct pq lcd_downq, lcd_upq; /* protocol glue for datagram service */
+ int (*lcd_send)(); /* if X.25 front end, direct connect */
+ int (*lcd_upper)(); /* switch to socket vs datagram vs ...*/
+ caddr_t lcd_upnext; /* reference for lcd_upper() */
short lcd_lcn; /* Logical channel number */
short lcd_state; /* Logical Channel state */
bool lcd_intrconf_pending; /* Interrupt confirmation pending */
short lcd_lcn; /* Logical channel number */
short lcd_state; /* Logical Channel state */
bool lcd_intrconf_pending; /* Interrupt confirmation pending */
struct pkcb *lcd_pkp; /* Network this lcd is attached to */
struct sockaddr_x25 lcd_faddr /* Remote Address (Calling) */
struct sockaddr_x25 lcd_laddr /* Local Address (Called) */
struct pkcb *lcd_pkp; /* Network this lcd is attached to */
struct sockaddr_x25 lcd_faddr /* Remote Address (Calling) */
struct sockaddr_x25 lcd_laddr /* Local Address (Called) */
+ struct sockbuf lcd_sb; /* alternate for datagram service */
};
#define X25_DG_CIRCUIT 0x10 /* lcd_flag: used for datagrams */
};
#define X25_DG_CIRCUIT 0x10 /* lcd_flag: used for datagrams */
struct pkcb *pk_next;
struct x25_ifaddr *pk_ia; /* backpointer to ifaddr */
int (*pk_lloutput) (); /* link level output procedure */
struct pkcb *pk_next;
struct x25_ifaddr *pk_ia; /* backpointer to ifaddr */
int (*pk_lloutput) (); /* link level output procedure */
+ caddr_t pk_llnext; /* handle for next level down */
int (*pk_start) (); /* connect, confirm method */
struct x25config *pk_xcp; /* network specific configuration */
short pk_state; /* packet level status */
int (*pk_start) (); /* connect, confirm method */
struct x25config *pk_xcp; /* network specific configuration */
short pk_state; /* packet level status */