Kill netccitt. The code is ancient, nobody wants to maintain it, and it

doesn't compile cleanly.
This commit is contained in:
Garrett Wollman 1996-02-06 21:07:22 +00:00
parent 8df32b19de
commit 1df738d453
30 changed files with 0 additions and 11721 deletions

View File

@ -1,50 +0,0 @@
/*
* Copyright (c) University of British Columbia, 1984
*
* @(#)README.hdlc 8.1 (Berkeley) 6/10/93
*
* X.25 HDLC DATA LINK LEVEL:
*
*
* This module implements the Link Level of the Open Systems Interconnect
* Model. The implementation is based on the ISO High-Level Data Link
* Control (HDLC). These procedures subscribe to the principles of the
* ISO-Class of Procedures for point-to-point. These procedures implement
* two-way asynchronous balanced mode (LAPB) as recommented by the CCITT.
*
* The HDLC protocol layer interface consists of the following procedures:
* Hd_init (pr_init)
* Hd_ouput (pr_output)
* Hd_input (pr_input)
* Hd_timer (pr_slowtimo)
*
* Note: Supervisory commands RR, RNR and REJ are not transmitted by this
* station.
*
* This station never enters a busy (RNR) condition.
*
* The "Generate_rr" variable can be set to FALSE. This means that
* we NEVER send an RR. This works just fine if the network level
* is X.25 packet protocol -- which it is.
*
* Currently, this is only a DTE implementation.
*
* Think about:
* If the remote is busy, no iframes are sent. The remote sends a RR
* to clear this condition. However, this RR may be damaged, causing
* a possible deadlock. A solution is to poll with iframe (P(S)==P(R)
* of RNR) indefinitly.
*
*
* Date: February 1984
*
* Author: Gerald W. Neufeld
*
* Installation: Department of Computer Science
* University of British Columbia
* Vancouver, BC, CANADA.
*
* History:
*
*
*/

View File

@ -1,36 +0,0 @@
/*
* @(#)README.packet 8.1 (Berkeley) 6/10/93
*
* X.25 NETWORK PACKET LEVEL:
*
* This implementation is based on Recommentation X.25 as agreed at the
* March 1976 and the February 1980 meetings of CCITT Study Group VII.
* However, not all aspects are implemented. The following is a list of
* features which are not yet or may never be implemented:
*
* 1. D bit
* 2. PVC
* 3. fast select
*
*
* Note: This implementation is for DTEs only.
*
* Currently, only the 1976 verison is implemented.
*
*
* Date: February, 1984
*
* Author: Gerald W. Neufeld
*
* Installation: Department of Computer Science
* University of British Columbia
* Vancouver, BC, CANADA
*
* To Do: Find some reasonable heuristic for piggybacking packet
* level acks.
*
* Bugs: Clear might be sent before data is all out.
*
* History:
*
*/

View File

@ -1,97 +0,0 @@
/*
* Copyright (c) University of British Columbia, 1984
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* the Laboratory for Computation Vision and the Computer Science Department
* of the University of British Columbia.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)ccitt_proto.c 8.1 (Berkeley) 6/10/93
* $Id: ccitt_proto.c,v 1.2 1994/08/02 07:46:54 davidg Exp $
*/
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/socket.h>
#include <sys/protosw.h>
#include <sys/domain.h>
#include <netccitt/x25.h>
#include <net/radix.h>
/*
* Definitions of protocols supported in the CCITT domain.
*/
extern struct domain ccittdomain;
#define DOMAIN &ccittdomain
#ifdef LLC
int llc_output();
void llc_ctlinput(), llc_init(), llc_timer();
#endif
#ifdef HDLC
int hd_output();
void hd_ctlinput(), hd_init(), hd_timer();
#endif
int pk_usrreq(), pk_ctloutput();
void pk_timer(), pk_init(), pk_input(), pk_ctlinput();
struct protosw ccittsw[] = {
#ifdef LLC
{ 0, DOMAIN, IEEEPROTO_802LLC,0,
0, llc_output, llc_ctlinput, 0,
0,
llc_init, 0, llc_timer, 0,
},
#endif
#ifdef HDLC
{ 0, DOMAIN, CCITTPROTO_HDLC,0,
0, hd_output, hd_ctlinput, 0,
0,
hd_init, 0, hd_timer, 0,
},
#endif
{ SOCK_STREAM, DOMAIN, CCITTPROTO_X25, PR_CONNREQUIRED|PR_ATOMIC|PR_WANTRCVD,
pk_input, 0, pk_ctlinput, pk_ctloutput,
pk_usrreq,
pk_init, 0, pk_timer, 0,
}
};
struct domain ccittdomain =
{ AF_CCITT, "ccitt", 0, 0, 0, ccittsw,
&ccittsw[sizeof(ccittsw)/sizeof(ccittsw[0])], 0,
rn_inithead, 32, sizeof (struct sockaddr_x25) };
DOMAIN_SET(ccitt);

View File

@ -1,89 +0,0 @@
/*
* Copyright (C) Dirk Husemann, Computer Science Department IV,
* University of Erlangen-Nuremberg, Germany, 1990, 1991, 1992
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)dll.h 8.1 (Berkeley) 6/10/93
* $Id: dll.h,v 1.3 1994/08/21 05:44:06 paul Exp $
*/
#ifndef _NETCCITT_DLL_H_
#define _NETCCITT_DLL_H_
/*
* We define the additional PRC_* codes in here
*/
#ifdef KERNEL
#ifndef PRC_IFUP
#define PRC_IFUP 3
#endif
#define PRC_CONNECT_INDICATION 8
#define PRC_CONNECT_REQUEST 9
#define PRC_DISCONNECT_REQUEST 10
#define PRC_DISCONNECT_INDICATION 11
#define PRC_RESET_REQUEST 12
#endif
/*
* Data link layer configuration --- basically a copy of the relevant parts
* of x25config, implemented to become a little bit more network
* layer independent. (Probably only used for casting et al.)
*/
struct dllconfig {
u_short dllcfg_unused0:4,
dllcfg_unused1:4,
dllcfg_trace:1, /* link level tracing flag */
dllcfg_window:7; /* link level window size */
u_short dllcfg_xchxid:1, /* exchange XID (not yet) */
dllcfg_unused2:7; /* here be dragons */
};
struct dll_ctlinfo {
union {
struct {
struct dllconfig *dctli_up_cfg;
u_char dctli_up_lsap;
} CTLI_UP;
struct {
caddr_t dctli_down_pcb;
struct rtentry *dctli_down_rt;
struct dllconfig *dctli_down_llconf;
} CTLI_DOWN;
} CTLIun;
};
#define dlcti_cfg CTLIun.CTLI_UP.dctli_up_cfg
#define dlcti_lsap CTLIun.CTLI_UP.dctli_up_lsap
#define dlcti_pcb CTLIun.CTLI_DOWN.dctli_down_pcb
#define dlcti_rt CTLIun.CTLI_DOWN.dctli_down_rt
#define dlcti_conf CTLIun.CTLI_DOWN.dctli_down_llconf
#endif

View File

@ -1,215 +0,0 @@
/*
* Copyright (c) University of British Columbia, 1984
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* the Laboratory for Computation Vision and the Computer Science Department
* of the University of British Columbia.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)hd_debug.c 8.1 (Berkeley) 6/10/93
* $Id: hd_debug.c,v 1.3 1995/02/15 06:29:42 jkh Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/domain.h>
#include <sys/socket.h>
#include <sys/protosw.h>
#include <sys/errno.h>
#include <sys/time.h>
#include <sys/kernel.h>
#include <net/if.h>
#include <netccitt/hdlc.h>
#include <netccitt/hd_var.h>
#include <netccitt/x25.h>
#ifdef HDLCDEBUG
#define NTRACE 32
struct hdlctrace {
struct hdcb *ht_hdp;
short ht_dir;
struct mbuf *ht_frame;
struct timeval ht_time;
} hdtrace[NTRACE];
int lasttracelogged, freezetrace;
#endif
void
hd_trace (hdp, direction, frame)
struct hdcb *hdp;
int direction;
register struct Hdlc_frame *frame;
{
register char *s;
register int nr, pf, ns, i;
struct Hdlc_iframe *iframe = (struct Hdlc_iframe *) frame;
#ifdef HDLCDEBUG
hd_savetrace (hdp, direction, frame);
#endif
if (hdp -> hd_xcp -> xc_ltrace) {
if (direction == RX)
printf ("F-In: ");
else if (direction == 2)
printf ("F-Xmt: ");
else
printf ("F-Out: ");
nr = iframe -> nr;
pf = iframe -> pf;
ns = iframe -> ns;
switch (hd_decode (hdp, frame)) {
case SABM:
printf ("SABM : PF=%d\n", pf);
break;
case DISC:
printf ("DISC : PF=%d\n", pf);
break;
case DM:
printf ("DM : PF=%d\n", pf);
break;
case FRMR:
{
register struct Frmr_frame *f = (struct Frmr_frame *)frame;
printf ("FRMR : PF=%d, TEXT=", pf);
for (s = (char *) frame, i = 0; i < 5; ++i, ++s)
printf ("%x ", (int) * s & 0xff);
printf ("\n");
printf ("control=%x v(s)=%d v(r)=%d w%d x%d y%d z%d\n",
f->frmr_control, f->frmr_ns, f->frmr_nr,
f->frmr_w, f->frmr_x, f->frmr_y, f->frmr_z);
break;
}
case UA:
printf ("UA : PF=%d\n", pf);
break;
case RR:
printf ("RR : N(R)=%d, PF=%d\n", nr, pf);
break;
case RNR:
printf ("RNR : N(R)=%d, PF=%d\n", nr, pf);
break;
case REJ:
printf ("REJ : N(R)=%d, PF=%d\n", nr, pf);
break;
case IFRAME:
{
register struct mbuf *m;
register int len = 0;
for(m = dtom (frame); m; m = m -> m_next)
len += m -> m_len;
len -= HDHEADERLN;
printf ("IFRAME : N(R)=%d, PF=%d, N(S)=%d, DATA(%d)=",
nr, pf, ns, len);
for (s = (char *)iframe->i_field, i = 0; i < 3; ++i, ++s)
printf ("%x ", (int) *s & 0xff);
printf ("\n");
break;
}
default:
printf ("ILLEGAL: ");
for (s = (char *) frame, i = 0; i < 5; ++i, ++s)
printf ("%x ", (int) *s & 0xff);
printf ("\n");
}
}
}
#ifdef HDLCDEBUG
static
hd_savetrace (hdp, dir, frame)
struct hdcb *hdp;
struct Hdlc_frame *frame;
{
register struct hdlctrace *htp;
register struct mbuf *m;
if (freezetrace)
return;
htp = &hdtrace[lasttracelogged];
lasttracelogged = (lasttracelogged + 1) % NTRACE;
if (m = htp->ht_frame)
m_freem (m);
m = dtom (frame);
htp->ht_frame = m_copy (m, 0, m->m_len);
htp->ht_hdp = hdp;
htp->ht_dir = dir;
htp->ht_time = time;
}
hd_dumptrace (hdp)
struct hdcb *hdp;
{
register int i, ltrace;
register struct hdlctrace *htp;
freezetrace = 1;
hd_status (hdp);
printf ("retransmit queue:");
for (i = 0; i < 8; i++)
printf (" %x", hdp -> hd_retxq[i]);
printf ("\n");
ltrace = hdp -> hd_xcp -> xc_ltrace;
hdp -> hd_xcp -> xc_ltrace = 1;
for (i = 0; i < NTRACE; i++) {
htp = &hdtrace[(lasttracelogged + i) % NTRACE];
if (htp->ht_hdp != hdp || htp->ht_frame == 0)
continue;
printf ("%d/%d ", htp->ht_time.tv_sec & 0xff,
htp->ht_time.tv_usec / 10000);
hd_trace (htp->ht_hdp, htp->ht_dir,
mtod (htp->ht_frame, struct Hdlc_frame *));
m_freem (htp->ht_frame);
htp->ht_frame = 0;
}
hdp -> hd_xcp -> xc_ltrace = ltrace;
freezetrace = 0;
}
#endif

View File

@ -1,678 +0,0 @@
/*
* Copyright (c) University of British Columbia, 1984
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* the Laboratory for Computation Vision and the Computer Science Department
* of the University of British Columbia.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)hd_input.c 8.1 (Berkeley) 6/10/93
* $Id: hd_input.c,v 1.4 1995/05/11 19:26:39 rgrimes Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/domain.h>
#include <sys/socket.h>
#include <sys/protosw.h>
#include <sys/errno.h>
#include <sys/time.h>
#include <sys/kernel.h>
#include <net/if.h>
#include <netccitt/hdlc.h>
#include <netccitt/hd_var.h>
#include <netccitt/x25.h>
static void frame_reject();
static void rej_routine();
static void free_iframes();
void process_sframe ();
/*
* HDLC INPUT INTERFACE
*
* This routine is called when the HDLC physical device has
* completed reading a frame.
*/
void
hdintr ()
{
register struct mbuf *m;
register struct hdcb *hdp;
register struct ifnet *ifp;
register int s;
static struct ifnet *lastifp;
static struct hdcb *lasthdp;
for (;;) {
s = splimp ();
IF_DEQUEUE (&hdintrq, m);
splx (s);
if (m == 0)
break;
if (m->m_len < HDHEADERLN) {
printf ("hdintr: packet too short (len=%d)\n",
m->m_len);
m_freem (m);
continue;
}
if ((m->m_flags & M_PKTHDR) == 0)
panic("hdintr");
ifp = m->m_pkthdr.rcvif;
/*
* look up the appropriate hdlc control block
*/
if (ifp == lastifp)
hdp = lasthdp;
else {
for (hdp = hdcbhead; hdp; hdp = hdp->hd_next)
if (hdp->hd_ifp == ifp)
break;
if (hdp == 0) {
printf ("hdintr: unknown interface %p\n", ifp);
m_freem (m);
continue;
}
lastifp = ifp;
lasthdp = hdp;
}
/* Process_rxframe returns FALSE if the frame was NOT queued
for the next higher layers. */
if (process_rxframe (hdp, m) == FALSE)
m_freem (m);
}
}
int
process_rxframe (hdp, fbuf)
register struct hdcb *hdp;
register struct mbuf *fbuf;
{
register int queued = FALSE, frametype, pf;
register struct Hdlc_frame *frame;
frame = mtod (fbuf, struct Hdlc_frame *);
pf = ((struct Hdlc_iframe *) frame) -> pf;
hd_trace (hdp, RX, frame);
if (frame -> address != ADDRESS_A && frame -> address != ADDRESS_B)
return (queued);
switch ((frametype = hd_decode (hdp, frame)) + hdp->hd_state) {
case DM + DISC_SENT:
case UA + DISC_SENT:
/*
* Link now closed. Leave timer running
* so hd_timer() can periodically check the
* status of interface driver flag bit IFF_UP.
*/
hdp->hd_state = DISCONNECTED;
break;
case DM + INIT:
case UA + INIT:
/*
* This is a non-standard state change needed for DCEs
* that do dynamic link selection. We can't go into the
* usual "SEND DM" state because a DM is a SARM in LAP.
*/
hd_writeinternal (hdp, SABM, POLLOFF);
hdp->hd_state = SABM_SENT;
SET_TIMER (hdp);
break;
case SABM + DM_SENT:
case SABM + WAIT_SABM:
hd_writeinternal (hdp, UA, pf);
case UA + SABM_SENT:
case UA + WAIT_UA:
KILL_TIMER (hdp);
hd_initvars (hdp);
hdp->hd_state = ABM;
hd_message (hdp, "Link level operational");
/* Notify the packet level - to send RESTART. */
(void) pk_ctlinput (PRC_LINKUP, hdp->hd_pkp);
break;
case SABM + SABM_SENT:
/* Got a SABM collision. Acknowledge the remote's SABM
via UA but still wait for UA. */
hd_writeinternal (hdp, UA, pf);
break;
case SABM + ABM:
/* Request to reset the link from the remote. */
KILL_TIMER (hdp);
hd_message (hdp, "Link reset");
#ifdef HDLCDEBUG
hd_dumptrace (hdp);
#endif
hd_flush (hdp->hd_ifp);
hd_writeinternal (hdp, UA, pf);
hd_initvars (hdp);
(void) pk_ctlinput (PRC_LINKRESET, hdp->hd_pkp);
hdp->hd_resets++;
break;
case SABM + WAIT_UA:
hd_writeinternal (hdp, UA, pf);
break;
case DM + ABM:
hd_message (hdp, "DM received: link down");
#ifdef HDLCDEBUG
hd_dumptrace (hdp);
#endif
(void) pk_ctlinput (PRC_LINKDOWN, hdp->hd_pkp);
hd_flush (hdp->hd_ifp);
case DM + DM_SENT:
case DM + WAIT_SABM:
case DM + WAIT_UA:
hd_writeinternal (hdp, SABM, pf);
hdp->hd_state = SABM_SENT;
SET_TIMER (hdp);
break;
case DISC + INIT:
case DISC + DM_SENT:
case DISC + SABM_SENT:
/* Note: This is a non-standard state change. */
hd_writeinternal (hdp, UA, pf);
hd_writeinternal (hdp, SABM, POLLOFF);
hdp->hd_state = SABM_SENT;
SET_TIMER (hdp);
break;
case DISC + WAIT_UA:
hd_writeinternal (hdp, DM, pf);
SET_TIMER (hdp);
hdp->hd_state = DM_SENT;
break;
case DISC + ABM:
hd_message (hdp, "DISC received: link down");
(void) pk_ctlinput (PRC_LINKDOWN, hdp->hd_pkp);
case DISC + WAIT_SABM:
hd_writeinternal (hdp, UA, pf);
hdp->hd_state = DM_SENT;
SET_TIMER (hdp);
break;
case UA + ABM:
hd_message (hdp, "UA received: link down");
(void) pk_ctlinput (PRC_LINKDOWN, hdp->hd_pkp);
case UA + WAIT_SABM:
hd_writeinternal (hdp, DM, pf);
hdp->hd_state = DM_SENT;
SET_TIMER (hdp);
break;
case FRMR + DM_SENT:
hd_writeinternal (hdp, SABM, pf);
hdp->hd_state = SABM_SENT;
SET_TIMER (hdp);
break;
case FRMR + WAIT_SABM:
hd_writeinternal (hdp, DM, pf);
hdp->hd_state = DM_SENT;
SET_TIMER (hdp);
break;
case FRMR + ABM:
hd_message (hdp, "FRMR received: link down");
(void) pk_ctlinput (PRC_LINKDOWN, hdp->hd_pkp);
#ifdef HDLCDEBUG
hd_dumptrace (hdp);
#endif
hd_flush (hdp->hd_ifp);
hd_writeinternal (hdp, SABM, pf);
hdp->hd_state = WAIT_UA;
SET_TIMER (hdp);
break;
case RR + ABM:
case RNR + ABM:
case REJ + ABM:
process_sframe (hdp, (struct Hdlc_sframe *)frame, frametype);
break;
case IFRAME + ABM:
queued = process_iframe (hdp, fbuf, (struct Hdlc_iframe *)frame);
break;
case IFRAME + SABM_SENT:
case RR + SABM_SENT:
case RNR + SABM_SENT:
case REJ + SABM_SENT:
hd_writeinternal (hdp, DM, POLLON);
hdp->hd_state = DM_SENT;
SET_TIMER (hdp);
break;
case IFRAME + WAIT_SABM:
case RR + WAIT_SABM:
case RNR + WAIT_SABM:
case REJ + WAIT_SABM:
hd_writeinternal (hdp, FRMR, POLLOFF);
SET_TIMER (hdp);
break;
case ILLEGAL + SABM_SENT:
hdp->hd_unknown++;
hd_writeinternal (hdp, DM, POLLOFF);
hdp->hd_state = DM_SENT;
SET_TIMER (hdp);
break;
case ILLEGAL + ABM:
hd_message (hdp, "Unknown frame received: link down");
(void) pk_ctlinput (PRC_LINKDOWN, hdp->hd_pkp);
case ILLEGAL + WAIT_SABM:
hdp->hd_unknown++;
#ifdef HDLCDEBUG
hd_dumptrace (hdp);
#endif
hd_writeinternal (hdp, FRMR, POLLOFF);
hdp->hd_state = WAIT_SABM;
SET_TIMER (hdp);
break;
}
return (queued);
}
int
process_iframe (hdp, fbuf, frame)
register struct hdcb *hdp;
struct mbuf *fbuf;
register struct Hdlc_iframe *frame;
{
register int nr = frame -> nr,
ns = frame -> ns,
pf = frame -> pf;
register int queued = FALSE;
/*
* Validate the iframe's N(R) value. It's N(R) value must be in
* sync with our V(S) value and our "last received nr".
*/
if (valid_nr (hdp, nr, FALSE) == FALSE) {
frame_reject (hdp, Z, frame);
return (queued);
}
/*
* This section tests the IFRAME for proper sequence. That is, it's
* sequence number N(S) MUST be equal to V(S).
*/
if (ns != hdp->hd_vr) {
hdp->hd_invalid_ns++;
if (pf || (hdp->hd_condition & REJ_CONDITION) == 0) {
hdp->hd_condition |= REJ_CONDITION;
/*
* Flush the transmit queue. This is ugly but we
* have no choice. A reject response must be
* immediately sent to the DCE. Failure to do so
* may result in another out of sequence iframe
* arriving (and thus sending another reject)
* before the first reject is transmitted. This
* will cause the DCE to receive two or more
* rejects back to back, which must never happen.
*/
hd_flush (hdp->hd_ifp);
hd_writeinternal (hdp, REJ, pf);
}
return (queued);
}
hdp->hd_condition &= ~REJ_CONDITION;
/*
* This section finally tests the IFRAME's sequence number against
* the window size (K) and the sequence number of the last frame
* we have acknowledged. If the IFRAME is completely correct then
* it is queued for the packet level.
*/
if (ns != (hdp -> hd_lasttxnr + hdp -> hd_xcp -> xc_lwsize) % MODULUS) {
hdp -> hd_vr = (hdp -> hd_vr + 1) % MODULUS;
if (pf == 1) {
/* Must generate a RR or RNR with final bit on. */
hd_writeinternal (hdp, RR, POLLON);
} else
/*
* Hopefully we can piggyback the RR, if not we will generate
* a RR when T3 timer expires.
*/
if (hdp -> hd_rrtimer == 0)
hdp->hd_rrtimer = hd_t3;
/* Forward iframe to packet level of X.25. */
fbuf -> m_data += HDHEADERLN;
fbuf -> m_len -= HDHEADERLN;
fbuf -> m_pkthdr.len -= HDHEADERLN;
fbuf -> m_pkthdr.rcvif = (struct ifnet *)hdp -> hd_pkp;
#ifdef BSD4_3
fbuf->m_act = 0; /* probably not necessary */
#else
{
register struct mbuf *m;
for (m = fbuf; m -> m_next; m = m -> m_next)
m -> m_act = (struct mbuf *) 0;
m -> m_act = (struct mbuf *) 1;
}
#endif
pk_input (fbuf);
queued = TRUE;
hd_start (hdp);
} else {
/*
* Here if the remote station has transmitted more iframes then
* the number which have been acknowledged plus K.
*/
hdp->hd_invalid_ns++;
frame_reject (hdp, W, frame);
}
return (queued);
}
/*
* This routine is used to determine if a value (the middle parameter)
* is between two other values. The low value is the first parameter
* the high value is the last parameter. The routine checks the middle
* value to see if it is within the range of the first and last values.
* The reason we need this routine is the values are modulo some base
* hence a simple test for greater or less than is not sufficient.
*/
bool
range_check (rear, value, front)
int rear,
value,
front;
{
register bool result = FALSE;
if (front > rear)
result = (rear <= value) && (value <= front);
else
result = (rear <= value) || (value <= front);
return (result);
}
/*
* This routine handles all the frame reject conditions which can
* arise as a result of secondary processing. The frame reject
* condition Y (frame length error) are handled elsewhere.
*/
static void
frame_reject (hdp, rejectcode, frame)
struct hdcb *hdp;
int rejectcode;
struct Hdlc_iframe *frame;
{
register struct Frmr_frame *frmr = &hd_frmr;
frmr -> frmr_control = ((struct Hdlc_frame *) frame) -> control;
frmr -> frmr_ns = frame -> ns;
frmr -> frmr_f1_0 = 0;
frmr -> frmr_nr = frame -> nr;
frmr -> frmr_f2_0 = 0;
frmr -> frmr_0000 = 0;
frmr -> frmr_w = frmr -> frmr_x = frmr -> frmr_y =
frmr -> frmr_z = 0;
switch (rejectcode) {
case Z:
frmr -> frmr_z = 1;/* invalid N(R). */
break;
case Y:
frmr -> frmr_y = 1;/* iframe length error. */
break;
case X:
frmr -> frmr_x = 1;/* invalid information field. */
frmr -> frmr_w = 1;
break;
case W:
frmr -> frmr_w = 1;/* invalid N(S). */
}
hd_writeinternal (hdp, FRMR, POLLOFF);
hdp->hd_state = WAIT_SABM;
SET_TIMER (hdp);
}
/*
* This procedure is invoked when ever we receive a supervisor
* frame such as RR, RNR and REJ. All processing for these
* frames is done here.
*/
void
process_sframe (hdp, frame, frametype)
register struct hdcb *hdp;
register struct Hdlc_sframe *frame;
int frametype;
{
register int nr = frame -> nr, pf = frame -> pf, pollbit = 0;
if (valid_nr (hdp, nr, pf) == TRUE) {
switch (frametype) {
case RR:
hdp->hd_condition &= ~REMOTE_RNR_CONDITION;
break;
case RNR:
hdp->hd_condition |= REMOTE_RNR_CONDITION;
hdp->hd_retxcnt = 0;
break;
case REJ:
hdp->hd_condition &= ~REMOTE_RNR_CONDITION;
rej_routine (hdp, nr);
}
if (pf == 1) {
hdp->hd_retxcnt = 0;
hdp->hd_condition &= ~TIMER_RECOVERY_CONDITION;
if (frametype == RR && hdp->hd_lastrxnr == hdp->hd_vs
&& hdp->hd_timer == 0 && hdp->hd_txq.head == 0)
hd_writeinternal(hdp, RR, pf);
else
/* If any iframes have been queued because of the
timer condition, transmit then now. */
if (hdp->hd_condition & REMOTE_RNR_CONDITION) {
/* Remote is busy or timer condition, so only
send one. */
if (hdp->hd_vs != hdp->hd_retxqi)
hd_send_iframe (hdp, hdp->hd_retxq[hdp->hd_vs], pollbit);
}
else /* Flush the retransmit list first. */
while (hdp->hd_vs != hdp->hd_retxqi)
hd_send_iframe (hdp, hdp->hd_retxq[hdp->hd_vs], POLLOFF);
}
hd_start (hdp);
} else
frame_reject (hdp, Z, (struct Hdlc_iframe *)frame); /* Invalid N(R). */
}
/*
* This routine tests the validity of the N(R) which we have received.
* If it is ok, then all the iframes which it acknowledges (if any)
* will be freed.
*/
bool
valid_nr (hdp, nr, finalbit)
register struct hdcb *hdp;
int nr;
register int finalbit;
{
/* Make sure it really does acknowledge something. */
if (hdp->hd_lastrxnr == nr)
return (TRUE);
/*
* This section validates the frame's N(R) value. It's N(R) value
* must be in syncronization with our V(S) value and our "last
* received nr" variable. If it is correct then we are able to send
* more IFRAME's, else frame reject condition is entered.
*/
if (range_check (hdp->hd_lastrxnr, nr, hdp->hd_vs) == FALSE) {
if ((hdp->hd_condition & TIMER_RECOVERY_CONDITION) &&
range_check (hdp->hd_vs, nr, hdp->hd_xx) == TRUE)
hdp->hd_vs = nr;
else {
hdp->hd_invalid_nr++;
return (FALSE);
}
}
/*
* If we get to here, we do have a valid frame but it might be out
* of sequence. However, we should still accept the receive state
* number N(R) since it has already passed our previous test and it
* does acknowledge frames which we are sending.
*/
KILL_TIMER (hdp);
free_iframes (hdp, &nr, finalbit);/* Free all acknowledged iframes */
if (nr != hdp->hd_vs)
SET_TIMER (hdp);
return (TRUE);
}
/*
* This routine determines how many iframes need to be retransmitted.
* It then resets the Send State Variable V(S) to accomplish this.
*/
static void
rej_routine (hdp, rejnr)
register struct hdcb *hdp;
register int rejnr;
{
register int anchor;
/*
* Flush the output queue. Any iframes queued for
* transmission will be out of sequence.
*/
hd_flush (hdp->hd_ifp);
/*
* Determine how many frames should be re-transmitted. In the case
* of a normal REJ this should be 1 to K. In the case of a timer
* recovery REJ (ie. a REJ with the Final Bit on) this could be 0.
*/
anchor = hdp->hd_vs;
if (hdp->hd_condition & TIMER_RECOVERY_CONDITION)
anchor = hdp->hd_xx;
anchor = (anchor - rejnr + 8) % MODULUS;
if (anchor > 0) {
/* There is at least one iframe to retransmit. */
KILL_TIMER (hdp);
hdp->hd_vs = rejnr;
while (hdp->hd_vs != hdp->hd_retxqi)
hd_send_iframe (hdp, hdp->hd_retxq[hdp->hd_vs], POLLOFF);
}
hd_start (hdp);
}
/*
* This routine frees iframes from the retransmit queue. It is called
* when a previously written iframe is acknowledged.
*/
static void
free_iframes (hdp, nr, finalbit)
register struct hdcb *hdp;
int *nr;
register int finalbit;
{
register int i, k;
/*
* We need to do the following because of a funny quirk in the
* protocol. This case occures when in Timer recovery condition
* we get a N(R) which acknowledges all the outstanding iframes
* but with the Final Bit off. In this case we need to save the last
* iframe for possible retransmission even though it has already been
* acknowledged!
*/
if ((hdp->hd_condition & TIMER_RECOVERY_CONDITION) && *nr == hdp->hd_xx && finalbit == 0) {
*nr = (*nr - 1 + 8) % MODULUS;
/* printf ("QUIRK\n"); */
}
k = (*nr - hdp->hd_lastrxnr + 8) % MODULUS;
/* Loop here freeing all acknowledged iframes. */
for (i = 0; i < k; ++i) {
m_freem (hdp->hd_retxq[hdp->hd_lastrxnr]);
hdp->hd_retxq[hdp->hd_lastrxnr] = 0;
hdp->hd_lastrxnr = (hdp->hd_lastrxnr + 1) % MODULUS;
}
}

View File

@ -1,253 +0,0 @@
/*
* Copyright (c) University of British Columbia, 1984
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* the Laboratory for Computation Vision and the Computer Science Department
* of the University of British Columbia.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)hd_output.c 8.1 (Berkeley) 6/10/93
* $Id: hd_output.c,v 1.3 1995/02/15 06:29:44 jkh Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/domain.h>
#include <sys/socket.h>
#include <sys/syslog.h>
#include <sys/protosw.h>
#include <sys/errno.h>
#include <sys/time.h>
#include <sys/kernel.h>
#include <net/if.h>
#include <netccitt/hdlc.h>
#include <netccitt/hd_var.h>
#include <netccitt/x25.h>
/*
* HDLC OUTPUT INTERFACE
*
* This routine is called when the X.25 packet layer output routine
* has a information frame (iframe) to write. It is also called
* by the input and control routines of the HDLC layer.
*/
void
hd_start (hdp)
register struct hdcb *hdp;
{
register struct mbuf *m;
/*
* The iframe is only transmitted if all these conditions are FALSE.
* The iframe remains queued (hdp->hd_txq) however and will be
* transmitted as soon as these conditions are cleared.
*/
while (!(hdp->hd_condition & (TIMER_RECOVERY_CONDITION | REMOTE_RNR_CONDITION | REJ_CONDITION))) {
if (hdp->hd_vs == (hdp->hd_lastrxnr + hdp->hd_xcp->xc_lwsize) % MODULUS) {
/* We have now exceeded the maximum number of
outstanding iframes. Therefore, we must wait
until at least one is acknowledged if this
condition is not turned off before we are
requested to write another iframe. */
hdp->hd_window_condition++;
break;
}
/* hd_remove top iframe from transmit queue. */
if ((m = hd_remove (&hdp->hd_txq)) == NULL)
break;
hd_send_iframe (hdp, m, POLLOFF);
}
}
void
hd_output (hdp, m0)
register struct hdcb *hdp;
struct mbuf *m0;
{
struct x25config *xcp;
register struct mbuf *m = m0;
int len;
if (m == NULL)
panic ("hd_output");
if ((m->m_flags & M_PKTHDR) == 0)
panic ("hd_output 2");
if (hdp->hd_state != ABM) {
m_freem (m);
return;
}
/*
* Make room for the hdlc header either by prepending
* another mbuf, or by adjusting the offset and length
* of the first mbuf in the mbuf chain.
*/
M_PREPEND(m, HDHEADERLN, M_DONTWAIT);
if (m == NULL)
return;
for (len = 0; m; m = m->m_next)
len += m->m_len;
m = m0;
m->m_pkthdr.len = len;
hd_append (&hdp->hd_txq, m);
hd_start (hdp);
}
/*
* This procedure is passed a buffer descriptor for an iframe. It builds
* the rest of the control part of the frame and then writes it out. It
* also starts the acknowledgement timer and keeps the iframe in the
* Retransmit queue (Retxq) just in case we have to do this again.
*
* Note: This routine is also called from hd_input.c when retransmission
* of old frames is required.
*/
void
hd_send_iframe (hdp, buf, poll_bit)
register struct hdcb *hdp;
register struct mbuf *buf;
int poll_bit;
{
register struct Hdlc_iframe *iframe;
struct mbuf *m;
KILL_TIMER (hdp);
if (buf == 0) {
printf ("hd_send_iframe: zero arg\n");
#ifdef HDLCDEBUG
hd_status (hdp);
hd_dumptrace (hdp);
#endif
hdp->hd_vs = (hdp->hd_vs + 7) % MODULUS;
return;
}
iframe = mtod (buf, struct Hdlc_iframe *);
iframe -> hdlc_0 = 0;
iframe -> nr = hdp->hd_vr;
iframe -> pf = poll_bit;
iframe -> ns = hdp->hd_vs;
iframe -> address = ADDRESS_B;
hdp->hd_lasttxnr = hdp->hd_vr;
hdp->hd_rrtimer = 0;
if (hdp->hd_vs == hdp->hd_retxqi) {
/* Check for retransmissions. */
/* Put iframe only once in the Retransmission queue. */
hdp->hd_retxq[hdp->hd_retxqi] = buf;
hdp->hd_retxqi = (hdp->hd_retxqi + 1) % MODULUS;
hdp->hd_iframes_out++;
}
hdp->hd_vs = (hdp->hd_vs + 1) % MODULUS;
hd_trace (hdp, TX, (struct Hdlc_frame *)iframe);
/* Write buffer on device. */
m = hdp->hd_dontcopy ? buf : m_copy(buf, 0, (int)M_COPYALL);
if (m == 0) {
printf("hdlc: out of mbufs\n");
return;
}
(*hdp->hd_output)(hdp, m);
SET_TIMER (hdp);
}
void
hd_ifoutput(hdp, m)
register struct mbuf *m;
register struct hdcb *hdp;
{
/*
* Queue message on interface, and start output if interface
* not yet active.
*/
register struct ifnet *ifp = hdp->hd_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.
*/
void
hd_resend_iframe (hdp)
register struct hdcb *hdp;
{
if (hdp->hd_retxcnt++ < hd_n2) {
if (!(hdp->hd_condition & TIMER_RECOVERY_CONDITION)) {
hdp->hd_xx = hdp->hd_vs;
hdp->hd_condition |= TIMER_RECOVERY_CONDITION;
}
hdp->hd_vs = hdp->hd_lastrxnr;
hd_send_iframe (hdp, hdp->hd_retxq[hdp->hd_vs], POLLON);
} else {
/* At this point we have not received a RR even after N2
retries - attempt to reset link. */
hd_initvars (hdp);
hd_writeinternal (hdp, SABM, POLLOFF);
hdp->hd_state = WAIT_UA;
SET_TIMER (hdp);
hd_message (hdp, "Timer recovery failed: link down");
(void) pk_ctlinput (PRC_LINKDOWN, hdp->hd_pkp);
}
}

View File

@ -1,413 +0,0 @@
/*
* Copyright (c) University of British Columbia, 1984
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* the Laboratory for Computation Vision and the Computer Science Department
* of the University of British Columbia.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)hd_subr.c 8.1 (Berkeley) 6/10/93
* $Id: hd_subr.c,v 1.4 1995/05/30 08:08:43 rgrimes Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/domain.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/protosw.h>
#include <sys/errno.h>
#include <sys/time.h>
#include <sys/kernel.h>
#include <net/if.h>
#include <netccitt/hdlc.h>
#include <netccitt/hd_var.h>
#include <netccitt/x25.h>
#include <netccitt/pk_var.h>
struct hdcb *hdcbhead;
struct Frmr_frame hd_frmr;
struct ifqueue hdintrq;
int hd_t1;
int hd_t3;
int hd_n2;
void
hd_init ()
{
hdintrq.ifq_maxlen = IFQ_MAXLEN;
}
int
hd_ctlinput (prc, addr)
int prc;
struct sockaddr *addr;
{
register struct x25config *xcp = (struct x25config *)addr;
register struct hdcb *hdp;
register struct ifaddr *ifa;
struct ifnet *ifp;
caddr_t pk_newlink();
void hd_writeinternal();
void hd_message();
if (addr->sa_family != AF_CCITT)
return (EAFNOSUPPORT);
if (xcp->xc_lptype != HDLCPROTO_LAPB)
return (EPROTONOSUPPORT);
ifa = ifa_ifwithaddr(addr);
if (ifa == 0 || ifa->ifa_addr->sa_family != AF_CCITT ||
(ifp = ifa->ifa_ifp) == 0)
panic ("hd_ctlinput");
for (hdp = hdcbhead; hdp; hdp = hdp->hd_next)
if (hdp->hd_ifp == ifp)
break;
if (hdp == 0) { /* new interface */
int error, hd_ifoutput(), hd_output();
/* an hdcb is now too big to fit in an mbuf */
MALLOC(hdp, struct hdcb *, sizeof (*hdp), M_PCB, M_DONTWAIT);
if (hdp == 0)
return (ENOBUFS);
bzero((caddr_t)hdp, sizeof(*hdp));
hdp->hd_pkp =
(caddr_t) pk_newlink ((struct x25_ifaddr *) ifa,
(caddr_t) hdp);
((struct x25_ifaddr *)ifa)->ia_pkcb =
(struct pkcb *) hdp->hd_pkp;
if (hdp -> hd_pkp == 0) {
free(hdp, M_PCB);
return (ENOBUFS);
}
hdp->hd_ifp = ifp;
hdp->hd_ifa = ifa;
hdp->hd_xcp = xcp;
hdp->hd_state = INIT;
hdp->hd_output = hd_ifoutput;
hdp->hd_next = hdcbhead;
hdcbhead = hdp;
} else if (hdp->hd_pkp == 0) { /* interface got reconfigured */
hdp->hd_pkp =
(caddr_t) pk_newlink ((struct x25_ifaddr *) ifa,
(caddr_t) hdp);
((struct x25_ifaddr *)ifa)->ia_pkcb =
(struct pkcb *) hdp->hd_pkp;
if (hdp -> hd_pkp == 0) {
free(hdp, M_PCB);
return (ENOBUFS);
}
}
switch (prc) {
case PRC_IFUP:
if (xcp->xc_lwsize == 0 ||
xcp->xc_lwsize > MAX_WINDOW_SIZE)
xcp->xc_lwsize = MAX_WINDOW_SIZE;
if (hdp->hd_state == INIT)
SET_TIMER (hdp);
break;
case PRC_IFDOWN:
if (hdp->hd_state == ABM)
hd_message (hdp, "Operator shutdown: link closed");
(void) pk_ctlinput (PRC_LINKDOWN, hdp->hd_pkp);
/* fall thru to ... */
case PRC_DISCONNECT_REQUEST:
/* drop reference to pkcb --- it's dead meat */
hdp->hd_pkp = (caddr_t) 0;
((struct x25_ifaddr *)ifa)->ia_pkcb = (struct pkcb *) 0;
hd_writeinternal (hdp, DISC, POLLON);
hdp->hd_state = DISC_SENT;
SET_TIMER (hdp);
}
return (0);
}
void
hd_initvars (hdp)
register struct hdcb *hdp;
{
register struct mbuf *m;
register int i;
/* Clear Transmit queue. */
while ((m = hd_remove (&hdp->hd_txq)) != NULL)
m_freem (m);
/* Clear Retransmit queue. */
i = hdp->hd_lastrxnr;
while (i != hdp->hd_retxqi) {
m_freem (hdp->hd_retxq[i]);
i = (i + 1) % MODULUS;
}
hdp->hd_retxqi = 0;
hdp->hd_vs = hdp->hd_vr = 0;
hdp->hd_lasttxnr = hdp->hd_lastrxnr = 0;
hdp->hd_rrtimer = 0;
KILL_TIMER(hdp);
hdp->hd_retxcnt = 0;
hdp->hd_condition = 0;
}
int
hd_decode (hdp, frame)
register struct hdcb *hdp;
struct Hdlc_frame *frame;
{
register int frametype = ILLEGAL;
register struct Hdlc_iframe *iframe = (struct Hdlc_iframe *) frame;
register struct Hdlc_sframe *sframe = (struct Hdlc_sframe *) frame;
register struct Hdlc_uframe *uframe = (struct Hdlc_uframe *) frame;
if (iframe -> hdlc_0 == 0) {
frametype = IFRAME;
hdp->hd_iframes_in++;
}
else if (sframe -> hdlc_01 == 1) {
/* Supervisory format. */
switch (sframe -> s2) {
case 0:
frametype = RR;
hdp->hd_rrs_in++;
break;
case 1:
frametype = RNR;
hdp->hd_rnrs_in++;
break;
case 2:
frametype = REJ;
hdp->hd_rejs_in++;
}
}
else if (uframe -> hdlc_11 == 3) {
/* Unnumbered format. */
switch (uframe -> m3) {
case 0:
frametype = DM;
break;
case 1:
frametype = SABM;
break;
case 2:
frametype = DISC;
break;
case 3:
frametype = UA;
break;
case 4:
frametype = FRMR;
hdp->hd_frmrs_in++;
}
}
return (frametype);
}
/*
* This routine is called when the HDLC layer internally generates a
* command or response for the remote machine ( eg. RR, UA etc. ).
* Only supervisory or unnumbered frames are processed.
*/
void
hd_writeinternal (hdp, frametype, pf)
register struct hdcb *hdp;
register int frametype, pf;
{
register struct mbuf *buf;
struct Hdlc_frame *frame;
register struct Hdlc_sframe *sframe;
register struct Hdlc_uframe *uframe;
void hd_flush();
MGETHDR (buf, M_DONTWAIT, MT_HEADER);
if (buf == 0)
return;
frame = mtod (buf, struct Hdlc_frame *);
sframe = mtod (buf, struct Hdlc_sframe *);
uframe = mtod (buf, struct Hdlc_uframe *);
/* Assume a response - address structure for DTE */
frame -> address = ADDRESS_A;
buf -> m_len = 2;
buf -> m_act = buf -> m_next = NULL;
switch (frametype) {
case RR:
frame -> control = RR_CONTROL;
hdp->hd_rrs_out++;
break;
case RNR:
frame -> control = RNR_CONTROL;
hdp->hd_rnrs_out++;
break;
case REJ:
frame -> control = REJ_CONTROL;
hdp->hd_rejs_out++;
break;
case SABM:
frame -> control = SABM_CONTROL;
frame -> address = ADDRESS_B;
break;
case DISC:
if ((hdp->hd_ifp->if_flags & IFF_UP) == 0) {
hdp->hd_state = DISCONNECTED;
(void) m_freem (buf);
hd_flush (hdp->hd_ifp);
return;
}
frame -> control = DISC_CONTROL;
frame -> address = ADDRESS_B;
break;
case DM:
frame -> control = DM_CONTROL;
break;
case UA:
frame -> control = UA_CONTROL;
break;
case FRMR:
frame -> control = FRMR_CONTROL;
bcopy ((caddr_t)&hd_frmr, (caddr_t)frame -> info, 3);
buf -> m_len = 5;
hdp->hd_frmrs_out++;
}
if (sframe -> hdlc_01 == 1) {
/* Supervisory format - RR, REJ, or RNR. */
sframe -> nr = hdp->hd_vr;
sframe -> pf = pf;
hdp->hd_lasttxnr = hdp->hd_vr;
hdp->hd_rrtimer = 0;
}
else
uframe -> pf = pf;
hd_trace (hdp, TX, frame);
buf -> m_pkthdr.len = buf -> m_len;
(*hdp->hd_output) (hdp, buf);
}
struct mbuf *
hd_remove (q)
struct hdtxq *q;
{
register struct mbuf *m;
m = q -> head;
if (m) {
if ((q -> head = m -> m_act) == NULL)
q -> tail = NULL;
m -> m_act = 0;
}
return (m);
}
void
hd_append (q, m)
register struct hdtxq *q;
register struct mbuf *m;
{
m -> m_act = NULL;
if (q -> tail == NULL)
q -> head = m;
else
q -> tail -> m_act = m;
q -> tail = m;
}
void
hd_flush (ifp)
struct ifnet *ifp;
{
register struct mbuf *m;
register int s;
while (1) {
s = splimp ();
IF_DEQUEUE (&ifp->if_snd, m);
splx (s);
if (m == 0)
break;
m_freem (m);
}
}
void
hd_message (hdp, msg)
struct hdcb *hdp;
char *msg;
{
char *format_ntn ();
if (hdcbhead -> hd_next)
printf ("HDLC(%s): %s\n", format_ntn (hdp->hd_xcp), msg);
else
printf ("HDLC: %s\n", msg);
}
#ifdef HDLCDEBUG
void
hd_status (hdp)
struct hdcb *hdp;
{
printf ("HDLC STATUS:\n V(S)=%d, V(R)=%d, retxqi=%d,\n",
hdp->hd_vs, hdp->hd_vr, hdp->hd_retxqi);
printf ("Last_rx_nr=%d, Last_tx_nr=%d,\n Condition=%d, Xx=%d\n",
hdp->hd_lastrxnr, hdp->hd_lasttxnr, hdp->hd_condition, hdp->hd_xx);
}
#endif

View File

@ -1,145 +0,0 @@
/*
* Copyright (c) University of British Columbia, 1984
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* the Laboratory for Computation Vision and the Computer Science Department
* of the University of British Columbia.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)hd_timer.c 8.1 (Berkeley) 6/10/93
* $Id: hd_timer.c,v 1.3 1995/02/15 06:29:46 jkh Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/domain.h>
#include <sys/socket.h>
#include <sys/protosw.h>
#include <sys/errno.h>
#include <sys/time.h>
#include <sys/kernel.h>
#include <net/if.h>
#include <netccitt/hdlc.h>
#include <netccitt/hd_var.h>
#include <netccitt/x25.h>
/*
* these can be patched with adb if the
* default values are inappropriate
*/
/*
* HDLC TIMER
*
* This routine is called every 500ms by the kernel. Decrement timer by this
* amount - if expired then process the event.
*/
void
hd_timer ()
{
register struct hdcb *hdp;
register int s = splimp ();
for (hdp = hdcbhead; hdp; hdp = hdp->hd_next) {
if (hdp->hd_rrtimer && (--hdp->hd_rrtimer == 0)) {
if (hdp->hd_lasttxnr != hdp->hd_vr)
hd_writeinternal (hdp, RR, POLLOFF);
}
if (!(hdp->hd_timer && --hdp->hd_timer == 0))
continue;
switch (hdp->hd_state) {
case INIT:
case DISC_SENT:
hd_writeinternal (hdp, DISC, POLLON);
break;
case ABM:
if (hdp->hd_lastrxnr != hdp->hd_vs) { /* XXX */
hdp->hd_timeouts++;
hd_resend_iframe (hdp);
}
break;
case WAIT_SABM:
hd_writeinternal (hdp, FRMR, POLLOFF);
if (++hdp->hd_retxcnt == hd_n2) {
hdp->hd_retxcnt = 0;
hd_writeinternal (hdp, SABM, POLLOFF);
hdp->hd_state = WAIT_UA;
}
break;
case DM_SENT:
if (++hdp->hd_retxcnt == hd_n2) {
/* Notify the packet level. */
(void) pk_ctlinput (PRC_LINKDOWN, hdp->hd_pkp);
hdp->hd_retxcnt = 0;
hdp->hd_state = SABM_SENT;
hd_writeinternal (hdp, SABM, POLLOFF);
} else
hd_writeinternal (hdp, DM, POLLOFF);
break;
case WAIT_UA:
if (++hdp->hd_retxcnt == hd_n2) {
hdp->hd_retxcnt = 0;
hd_writeinternal (hdp, DM, POLLOFF);
hdp->hd_state = DM_SENT;
} else
hd_writeinternal (hdp, SABM, POLLOFF);
break;
case SABM_SENT:
/* Do this indefinitely. */
hd_writeinternal (hdp, SABM, POLLON);
break;
case DISCONNECTED:
/*
* Poll the interface driver flags waiting
* for the IFF_UP bit to come on.
*/
if (hdp->hd_ifp->if_flags & IFF_UP)
hdp->hd_state = INIT;
}
SET_TIMER (hdp);
}
splx (s);
}

View File

@ -1,113 +0,0 @@
/*
* Copyright (c) University of British Columbia, 1984
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* the Laboratory for Computation Vision and the Computer Science Department
* of the University of British Columbia.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)hd_var.h 8.1 (Berkeley) 6/10/93
* $Id: hd_var.h,v 1.3 1994/08/21 05:44:06 paul Exp $
*/
#ifndef _NETCCITT_HD_VAR_H_
#define _NETCCITT_HD_VAR_H_
/*
*
* hdlc control block
*
*/
struct hdtxq {
struct mbuf *head;
struct mbuf *tail;
};
struct hdcb {
struct hdcb *hd_next; /* pointer to next hdlc control block */
char hd_state; /* link state */
char hd_vs; /* send state variable */
char hd_vr; /* receive state variable */
char hd_lastrxnr; /* last received N(R) */
char hd_lasttxnr; /* last transmitted N(R) */
char hd_condition;
#define TIMER_RECOVERY_CONDITION 0x01
#define REJ_CONDITION 0x02
#define REMOTE_RNR_CONDITION 0X04
char hd_retxcnt;
char hd_xx;
struct hdtxq hd_txq;
struct mbuf *hd_retxq[MODULUS];
char hd_retxqi;
char hd_rrtimer;
char hd_timer;
#define SET_TIMER(hdp) hdp->hd_timer = hd_t1
#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 */
struct x25config *hd_xcp;
caddr_t hd_pkp; /* Level III junk */
int (*hd_output)(); /* separate entry for HDLC direct output */
/* link statistics */
long hd_iframes_in;
long hd_iframes_out;
long hd_rrs_in;
long hd_rrs_out;
short hd_rejs_in;
short hd_rejs_out;
long hd_window_condition;
short hd_invalid_ns;
short hd_invalid_nr;
short hd_timeouts;
short hd_resets;
short hd_unknown;
short hd_frmrs_in;
short hd_frmrs_out;
short hd_rnrs_in;
short hd_rnrs_out;
};
#ifdef KERNEL
extern struct hdcb *hdcbhead; /* head of linked list of hdcb's */
extern struct Frmr_frame hd_frmr; /* rejected frame diagnostic info */
extern struct ifqueue hdintrq; /* hdlc packet input queue */
extern int hd_t1; /* timer T1 value */
extern int hd_t3; /* RR send timer */
extern int hd_n2; /* frame retransmission limit */
#endif
#endif

View File

@ -1,162 +0,0 @@
/*-
* Copyright (c) University of British Columbia, 1984
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by the
* Laboratory for Computation Vision and the Computer Science Department
* of the University of British Columbia.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)hdlc.h 8.1 (Berkeley) 6/10/93
* $Id: hdlc.h,v 1.2 1994/08/02 07:47:12 davidg Exp $
*/
#ifndef _NETCCITT_HDLC_H_
#define _NETCCITT_HDLC_H_
#ifndef ORDER4
#define FALSE 0
#define TRUE 1
typedef u_char octet;
typedef char bool;
/*
* HDLC Packet format definitions
* This will eventually have to be rewritten without reference
* to bit fields, to be compliant with ANSI C and alignment safe.
*/
#if BYTE_ORDER == BIG_ENDIAN
#define ORDER4(a, b, c, d) a , b , c , d
#define ORDER5(a, b, c, d, e) a , b , c , d , e
#endif
#if BYTE_ORDER == LITTLE_ENDIAN
#define ORDER4(a, b, c, d) d , c , b , a
#define ORDER5(a, b, c, d, e) e , d , c , b , a
#endif
#endif
#define MAX_INFO_LEN 4096+3+4
#define ADDRESS_A 3 /* B'00000011' */
#define ADDRESS_B 1 /* B'00000001' */
struct Hdlc_iframe {
octet address;
octet ORDER4(nr:3, pf:1, ns:3, hdlc_0:1);
octet i_field[MAX_INFO_LEN];
};
struct Hdlc_sframe {
octet address;
octet ORDER4(nr:3, pf:1, s2:2, hdlc_01:2);
};
struct Hdlc_uframe {
octet address;
octet ORDER4(m3:3, pf:1, m2:2, hdlc_11:2);
};
struct Frmr_frame {
octet address;
octet control;
octet frmr_control;
octet ORDER4(frmr_nr:3, frmr_f1_0:1, frmr_ns:3, frmr_f2_0:1);
octet ORDER5(frmr_0000:4, frmr_z:1, frmr_y:1, frmr_x:1, frmr_w:1);
};
#define HDHEADERLN 2
#define MINFRLN 2 /* Minimum frame length. */
struct Hdlc_frame {
octet address;
octet control;
octet info[3]; /* min for FRMR */
};
#define SABM_CONTROL 057 /* B'00101111' */
#define UA_CONTROL 0143 /* B'01100011' */
#define DISC_CONTROL 0103 /* B'01000011' */
#define DM_CONTROL 017 /* B'00001111' */
#define FRMR_CONTROL 0207 /* B'10000111' */
#define RR_CONTROL 01 /* B'00000001' */
#define RNR_CONTROL 05 /* B'00000101' */
#define REJ_CONTROL 011 /* B'00001001' */
#define POLLOFF 0
#define POLLON 1
/* Define Link State constants. */
#define INIT 0
#define DM_SENT 1
#define SABM_SENT 2
#define ABM 3
#define WAIT_SABM 4
#define WAIT_UA 5
#define DISC_SENT 6
#define DISCONNECTED 7
#define MAXSTATE 8
/* The following constants are used in a switch statement to process
frames read from the communications line. */
#define SABM 0 * MAXSTATE
#define DM 1 * MAXSTATE
#define DISC 2 * MAXSTATE
#define UA 3 * MAXSTATE
#define FRMR 4 * MAXSTATE
#define RR 5 * MAXSTATE
#define RNR 6 * MAXSTATE
#define REJ 7 * MAXSTATE
#define IFRAME 8 * MAXSTATE
#define ILLEGAL 9 * MAXSTATE
#define T1 (3 * PR_SLOWHZ) /* IFRAME TIMEOUT - 3 seconds */
#define T3 (T1 / 2) /* RR generate timeout - 1.5 seconds */
#define N2 10
#define MODULUS 8
#define MAX_WINDOW_SIZE 7
#define Z 0
#define Y 1
#define X 2
#define W 3
#define A 4
#define TX 0
#define RX 1
bool range_check ();
bool valid_nr ();
struct mbuf *hd_remove ();
#endif

View File

@ -1,826 +0,0 @@
/*
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)if_x25subr.c 8.1 (Berkeley) 6/10/93
* $Id: if_x25subr.c,v 1.8 1995/10/26 20:30:34 julian Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/ioctl.h>
#include <sys/errno.h>
#include <sys/syslog.h>
#include <machine/mtpr.h>
#include <net/if.h>
#include <net/if_types.h>
#include <net/netisr.h>
#include <net/route.h>
#include <netccitt/x25.h>
#include <netccitt/x25err.h>
#include <netccitt/pk.h>
#include <netccitt/pk_var.h>
#ifdef INET
#include <netinet/in.h>
#include <netinet/in_var.h>
#endif
#ifdef IPX
#include <netipx/ipx.h>
#include <netipx/ipx_if.h>
#endif
#ifdef NS
#include <netns/ns.h>
#include <netns/ns_if.h>
#endif
#ifdef ISO
int tp_incoming();
#include <netiso/argo_debug.h>
#include <netiso/iso.h>
#include <netiso/iso_var.h>
#endif
struct llinfo_x25 llinfo_x25 = {&llinfo_x25, &llinfo_x25};
#ifndef _offsetof
#define _offsetof(t, m) ((int)((caddr_t)&((t *)0)->m))
#endif
struct sockaddr *x25_dgram_sockmask;
struct sockaddr_x25 x25_dgmask = {
_offsetof(struct sockaddr_x25, x25_udata[1]), /* _len */
0, /* _family */
0, /* _net */
{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* _addr */
{0}, /* opts */
-1, /* _udlen */
{-1} /* _udata */
};
struct if_x25stats {
int ifx_wrongplen;
int ifx_nophdr;
} if_x25stats;
int x25_autoconnect = 0;
#define senderr(x) {error = x; goto bad;}
/*
* Ancillary routines
*/
static struct llinfo_x25 *
x25_lxalloc(rt)
register struct rtentry *rt;
{
register struct llinfo_x25 *lx;
register struct sockaddr *dst = rt_key(rt);
register struct ifaddr *ifa;
MALLOC(lx, struct llinfo_x25 *, sizeof (*lx), M_PCB, M_NOWAIT);
if (lx == 0)
return lx;
Bzero(lx, sizeof(*lx));
lx->lx_rt = rt;
lx->lx_family = dst->sa_family;
rt->rt_refcnt++;
if (rt->rt_llinfo)
insque(lx, (struct llinfo_x25 *)rt->rt_llinfo);
else {
rt->rt_llinfo = (caddr_t)lx;
insque(lx, &llinfo_x25);
}
for (ifa = rt->rt_ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {
if (ifa->ifa_addr->sa_family == AF_CCITT)
lx->lx_ia = (struct x25_ifaddr *)ifa;
}
return lx;
}
static void
x25_lxfree(lx)
register struct llinfo_x25 *lx;
{
register struct rtentry *rt = lx->lx_rt;
register struct pklcd *lcp = lx->lx_lcd;
if (lcp) {
lcp->lcd_upper = 0;
pk_disconnect(lcp);
}
if ((rt->rt_llinfo == (caddr_t)lx) && (lx->lx_next->lx_rt == rt))
rt->rt_llinfo = (caddr_t)lx->lx_next;
else
rt->rt_llinfo = 0;
RTFREE(rt);
remque(lx);
FREE(lx, M_PCB);
}
/*
* Process a x25 packet as datagram;
*/
static void
x25_ifinput(lcp, m)
struct pklcd *lcp;
register struct mbuf *m;
{
struct llinfo_x25 *lx = (struct llinfo_x25 *)lcp->lcd_upnext;
register struct ifnet *ifp;
struct ifqueue *inq;
extern struct timeval time;
int s, len, isr;
void x25_connect_callback();
if (m == 0 || lcp->lcd_state != DATA_TRANSFER) {
x25_connect_callback(lcp, 0);
return;
}
pk_flowcontrol(lcp, 0, 1); /* Generate RR */
ifp = m->m_pkthdr.rcvif;
ifp->if_lastchange = time;
switch (m->m_type) {
default:
if (m)
m_freem(m);
return;
case MT_DATA:
/* FALLTHROUGH */;
}
switch (lx->lx_family) {
#ifdef INET
case AF_INET:
isr = NETISR_IP;
inq = &ipintrq;
break;
#endif
#ifdef IPX
case AF_IPX:
isr = NETISR_IPX;
inq = &ipxintrq;
break;
#endif
#ifdef NS
case AF_NS:
isr = NETISR_NS;
inq = &nsintrq;
break;
#endif
#ifdef ISO
case AF_ISO:
isr = NETISR_ISO;
inq = &clnlintrq;
break;
#endif
default:
m_freem(m);
ifp->if_noproto++;
return;
}
s = splimp();
schednetisr(isr);
if (IF_QFULL(inq)) {
IF_DROP(inq);
m_freem(m);
} else {
IF_ENQUEUE(inq, m);
ifp->if_ibytes += m->m_pkthdr.len;
}
splx(s);
}
static void
x25_connect_callback(lcp, m)
register struct pklcd *lcp;
register struct mbuf *m;
{
register struct llinfo_x25 *lx = (struct llinfo_x25 *)lcp->lcd_upnext;
int do_clear = 1;
if (m == 0)
goto refused;
if (m->m_type != MT_CONTROL) {
printf("x25_connect_callback: should panic\n");
goto refused;
}
switch (pk_decode(mtod(m, struct x25_packet *))) {
case CALL_ACCEPTED:
lcp->lcd_upper = x25_ifinput;
if (lcp->lcd_sb.sb_mb)
lcp->lcd_send(lcp); /* XXX start queued packets */
return;
default:
do_clear = 0;
refused:
lcp->lcd_upper = 0;
lx->lx_lcd = 0;
if (do_clear)
pk_disconnect(lcp);
return;
}
}
#define SA(p) ((struct sockaddr *)(p))
#define RT(p) ((struct rtentry *)(p))
static void
x25_dgram_incoming(lcp, m0)
register struct pklcd *lcp;
struct mbuf *m0;
{
register struct rtentry *rt, *nrt;
register struct mbuf *m = m0->m_next; /* m0 has calling sockaddr_x25 */
void x25_rtrequest();
rt = rtalloc1(SA(&lcp->lcd_faddr), 0, 0UL);
if (rt == 0) {
refuse: lcp->lcd_upper = 0;
pk_close(lcp);
return;
}
rt->rt_refcnt--;
if ((nrt = RT(rt->rt_llinfo)) == 0 || rt_mask(rt) != x25_dgram_sockmask)
goto refuse;
if ((nrt->rt_flags & RTF_UP) == 0) {
rt->rt_llinfo = (caddr_t)rtalloc1(rt->rt_gateway, 0, 0UL);
rtfree(nrt);
if ((nrt = RT(rt->rt_llinfo)) == 0)
goto refuse;
nrt->rt_refcnt--;
}
if (nrt->rt_ifa == 0 || nrt->rt_ifa->ifa_rtrequest != x25_rtrequest)
goto refuse;
lcp->lcd_send(lcp); /* confirm call */
x25_rtattach(lcp, nrt);
m_freem(m);
}
/*
* X.25 output routine.
*/
static int
x25_ifoutput(ifp, m0, dst, rt)
struct ifnet *ifp;
struct mbuf *m0;
struct sockaddr *dst;
register struct rtentry *rt;
{
register struct mbuf *m = m0;
register struct llinfo_x25 *lx;
struct pklcd *lcp;
int s, error = 0;
int plen;
for (plen = 0; m; m = m->m_next)
plen += m->m_len;
m = m0;
if ((ifp->if_flags & IFF_UP) == 0)
senderr(ENETDOWN);
while (rt == 0 || (rt->rt_flags & RTF_GATEWAY)) {
if (rt) {
if (rt->rt_llinfo) {
rt = (struct rtentry *)rt->rt_llinfo;
continue;
}
dst = rt->rt_gateway;
}
if ((rt = rtalloc1(dst, 1, 0UL)) == 0)
senderr(EHOSTUNREACH);
rt->rt_refcnt--;
}
/*
* Sanity checks.
*/
if ((rt->rt_ifp != ifp) ||
(rt->rt_flags & (RTF_CLONING | RTF_GATEWAY)) ||
((lx = (struct llinfo_x25 *)rt->rt_llinfo) == 0)) {
senderr(ENETUNREACH);
}
if ((m->m_flags & M_PKTHDR) == 0) {
if_x25stats.ifx_nophdr++;
m = m_gethdr(M_NOWAIT, MT_HEADER);
if (m == 0)
senderr(ENOBUFS);
m->m_pkthdr.len = plen;
m->m_next = m0;
}
if (plen != m->m_pkthdr.len) {
if_x25stats.ifx_wrongplen++;
m->m_pkthdr.len = plen;
}
next_circuit:
lcp = lx->lx_lcd;
if (lcp == 0) {
lx->lx_lcd = lcp = pk_attach((struct socket *)0);
if (lcp == 0)
senderr(ENOBUFS);
lcp->lcd_upper = x25_connect_callback;
lcp->lcd_upnext = (caddr_t)lx;
lcp->lcd_packetsize = lx->lx_ia->ia_xc.xc_psize;
lcp->lcd_flags = X25_MBS_HOLD;
}
switch (lcp->lcd_state) {
case READY:
if (dst->sa_family == AF_INET &&
ifp->if_type == IFT_X25DDN &&
rt->rt_gateway->sa_family != AF_CCITT)
x25_ddnip_to_ccitt(dst, rt);
if (rt->rt_gateway->sa_family != AF_CCITT) {
if ((rt->rt_flags & RTF_XRESOLVE) == 0)
senderr(EHOSTUNREACH);
} else if (x25_autoconnect)
error = pk_connect(lcp,
(struct sockaddr_x25 *)rt->rt_gateway);
if (error)
senderr(error);
/* FALLTHROUGH */
case SENT_CALL:
case DATA_TRANSFER:
if (sbspace(&lcp->lcd_sb) < 0) {
lx = lx->lx_next;
if (lx->lx_rt != rt)
senderr(ENOSPC);
goto next_circuit;
}
if (lx->lx_ia)
lcp->lcd_dg_timer =
lx->lx_ia->ia_xc.xc_dg_idletimo;
pk_send(lcp, m);
break;
default:
/*
* We count on the timer routine to close idle
* connections, if there are not enough circuits to go
* around.
*
* So throw away data for now.
* After we get it all working, we'll rewrite to handle
* actively closing connections (other than by timers),
* when circuits get tight.
*
* In the DDN case, the imp itself closes connections
* under heavy load.
*/
error = ENOBUFS;
bad:
if (m)
m_freem(m);
}
return (error);
}
/*
* Simpleminded timer routine.
*/
static void
x25_iftimeout(ifp)
struct ifnet *ifp;
{
register struct pkcb *pkcb = 0;
register struct pklcd **lcpp, *lcp;
int s = splimp();
FOR_ALL_PKCBS(pkcb)
if (pkcb->pk_ia->ia_ifp == ifp)
for (lcpp = pkcb->pk_chan + pkcb->pk_maxlcn;
--lcpp > pkcb->pk_chan;)
if ((lcp = *lcpp) &&
lcp->lcd_state == DATA_TRANSFER &&
(lcp->lcd_flags & X25_DG_CIRCUIT) &&
(lcp->lcd_dg_timer && --lcp->lcd_dg_timer == 0)) {
lcp->lcd_upper(lcp, 0);
}
splx(s);
}
/*
* This routine gets called when validating additions of new routes
* or deletions of old ones.
*/
static void
x25_rtrequest(cmd, rt, dst)
int cmd;
register struct rtentry *rt;
struct sockaddr *dst;
{
register struct llinfo_x25 *lx = (struct llinfo_x25 *)rt->rt_llinfo;
register struct sockaddr_x25 *sa =(struct sockaddr_x25 *)rt->rt_gateway;
register struct pklcd *lcp;
/* would put this pk_init, except routing table doesn't
exist yet. */
if (x25_dgram_sockmask == 0) {
x25_dgram_sockmask =
SA(rn_addmask((caddr_t)&x25_dgmask, 0, 4)->rn_key);
}
if (rt->rt_flags & RTF_GATEWAY) {
if (rt->rt_llinfo)
RTFREE((struct rtentry *)rt->rt_llinfo);
rt->rt_llinfo = (cmd == RTM_ADD) ?
(caddr_t)rtalloc1(rt->rt_gateway, 1, 0UL) : 0;
return;
}
if ((rt->rt_flags & RTF_HOST) == 0)
return;
if (cmd == RTM_DELETE) {
while (rt->rt_llinfo)
x25_lxfree((struct llinfo *)rt->rt_llinfo);
x25_rtinvert(RTM_DELETE, rt->rt_gateway, rt);
return;
}
if (lx == 0 && (lx = x25_lxalloc(rt)) == 0)
return;
if ((lcp = lx->lx_lcd) && lcp->lcd_state != READY) {
/*
* This can only happen on a RTM_CHANGE operation
* though cmd will be RTM_ADD.
*/
if (lcp->lcd_ceaddr &&
Bcmp(rt->rt_gateway, lcp->lcd_ceaddr,
lcp->lcd_ceaddr->x25_len) != 0) {
x25_rtinvert(RTM_DELETE, lcp->lcd_ceaddr, rt);
lcp->lcd_upper = 0;
pk_disconnect(lcp);
}
lcp = 0;
}
x25_rtinvert(RTM_ADD, rt->rt_gateway, rt);
}
int x25_dont_rtinvert = 0;
static void
x25_rtinvert(cmd, sa, rt)
register struct sockaddr *sa;
register struct rtentry *rt;
{
struct rtentry *rt2 = 0;
/*
* rt_gateway contains PID indicating which proto
* family on the other end, so will be different
* from general host route via X.25.
*/
if (rt->rt_ifp->if_type == IFT_X25DDN || x25_dont_rtinvert)
return;
if (sa->sa_family != AF_CCITT)
return;
if (cmd != RTM_DELETE) {
rtrequest(RTM_ADD, sa, rt_key(rt), x25_dgram_sockmask,
RTF_PROTO2, &rt2);
if (rt2) {
rt2->rt_llinfo = (caddr_t) rt;
rt->rt_refcnt++;
}
return;
}
rt2 = rt;
if ((rt = rtalloc1(sa, 0, 0UL)) == 0 ||
(rt->rt_flags & RTF_PROTO2) == 0 ||
rt->rt_llinfo != (caddr_t)rt2) {
printf("x25_rtchange: inverse route screwup\n");
return;
} else
rt2->rt_refcnt--;
rtrequest(RTM_DELETE, sa, rt_key(rt2), x25_dgram_sockmask,
0, (struct rtentry **) 0);
}
static struct sockaddr_x25 blank_x25 = {sizeof blank_x25, AF_CCITT};
/*
* IP to X25 address routine copyright ACC, used by permission.
*/
union imp_addr {
struct in_addr ip;
struct imp {
u_char s_net;
u_char s_host;
u_char s_lh;
u_char s_impno;
} imp;
};
/*
* The following is totally bogus and here only to preserve
* the IP to X.25 translation.
*/
static int
x25_ddnip_to_ccitt(src, rt)
struct sockaddr_in *src;
register struct rtentry *rt;
{
register struct sockaddr_x25 *dst = (struct sockaddr_x25 *)rt->rt_gateway;
union imp_addr imp_addr;
int imp_no, imp_port, temp;
char *x25addr = dst->x25_addr;
imp_addr.ip = src->sin_addr;
*dst = blank_x25;
if ((imp_addr.imp.s_net & 0x80) == 0x00) { /* class A */
imp_no = imp_addr.imp.s_impno;
imp_port = imp_addr.imp.s_host;
} else if ((imp_addr.imp.s_net & 0xc0) == 0x80) { /* class B */
imp_no = imp_addr.imp.s_impno;
imp_port = imp_addr.imp.s_lh;
} else { /* class C */
imp_no = imp_addr.imp.s_impno / 32;
imp_port = imp_addr.imp.s_impno % 32;
}
x25addr[0] = 12; /* length */
/* DNIC is cleared by struct copy above */
if (imp_port < 64) { /* Physical: 0000 0 IIIHH00 [SS] *//* s_impno
* -> III, s_host -> HH */
x25addr[5] = 0; /* set flag bit */
x25addr[6] = imp_no / 100;
x25addr[7] = (imp_no % 100) / 10;
x25addr[8] = imp_no % 10;
x25addr[9] = imp_port / 10;
x25addr[10] = imp_port % 10;
} else { /* Logical: 0000 1 RRRRR00 [SS] *//* s
* _host * 256 + s_impno -> RRRRR */
temp = (imp_port << 8) + imp_no;
x25addr[5] = 1;
x25addr[6] = temp / 10000;
x25addr[7] = (temp % 10000) / 1000;
x25addr[8] = (temp % 1000) / 100;
x25addr[9] = (temp % 100) / 10;
x25addr[10] = temp % 10;
}
}
/*
* This routine is a sketch and is not to be believed!!!!!
*
* This is a utility routine to be called by x25 devices when a
* call request is honored with the intent of starting datagram forwarding.
*/
static int
x25_dg_rtinit(dst, ia, af)
struct sockaddr_x25 *dst;
register struct x25_ifaddr *ia;
{
struct sockaddr *sa = 0;
struct rtentry *rt;
struct in_addr my_addr;
static struct sockaddr_in sin = {sizeof(sin), AF_INET};
if (ia->ia_ifp->if_type == IFT_X25DDN && af == AF_INET) {
/*
* Inverse X25 to IP mapping copyright and courtesy ACC.
*/
int imp_no, imp_port, temp;
union imp_addr imp_addr;
{
/*
* First determine our IP addr for network
*/
register struct in_ifaddr *ina;
for (ina = in_ifaddr; ina; ina = ina->ia_next)
if (ina->ia_ifp == ia->ia_ifp) {
my_addr = ina->ia_addr.sin_addr;
break;
}
}
{
register char *x25addr = dst->x25_addr;
switch (x25addr[5] & 0x0f) {
case 0: /* Physical: 0000 0 IIIHH00 [SS] */
imp_no =
((int) (x25addr[6] & 0x0f) * 100) +
((int) (x25addr[7] & 0x0f) * 10) +
((int) (x25addr[8] & 0x0f));
imp_port =
((int) (x25addr[9] & 0x0f) * 10) +
((int) (x25addr[10] & 0x0f));
break;
case 1: /* Logical: 0000 1 RRRRR00 [SS] */
temp = ((int) (x25addr[6] & 0x0f) * 10000)
+ ((int) (x25addr[7] & 0x0f) * 1000)
+ ((int) (x25addr[8] & 0x0f) * 100)
+ ((int) (x25addr[9] & 0x0f) * 10)
+ ((int) (x25addr[10] & 0x0f));
imp_port = temp >> 8;
imp_no = temp & 0xff;
break;
default:
return (0L);
}
imp_addr.ip = my_addr;
if ((imp_addr.imp.s_net & 0x80) == 0x00) {
/* class A */
imp_addr.imp.s_host = imp_port;
imp_addr.imp.s_impno = imp_no;
imp_addr.imp.s_lh = 0;
} else if ((imp_addr.imp.s_net & 0xc0) == 0x80) {
/* class B */
imp_addr.imp.s_lh = imp_port;
imp_addr.imp.s_impno = imp_no;
} else {
/* class C */
imp_addr.imp.s_impno = (imp_no << 5) + imp_port;
}
}
sin.sin_addr = imp_addr.ip;
sa = (struct sockaddr *)&sin;
} else {
/*
* This uses the X25 routing table to do inverse
* lookup of x25 address to sockaddr.
*/
if (rt = rtalloc1(SA(dst), 0, 0UL)) {
sa = rt->rt_gateway;
rt->rt_refcnt--;
}
}
/*
* Call to rtalloc1 will create rtentry for reverse path
* to callee by virtue of cloning magic and will allocate
* space for local control block.
*/
if (sa && (rt = rtalloc1(sa, 1, 0UL)))
rt->rt_refcnt--;
}
int x25_startproto = 1;
pk_init()
{
/*
* warning, sizeof (struct sockaddr_x25) > 32,
* but contains no data of interest beyond 32
*/
if (x25_startproto) {
pk_protolisten(0xcc, 1, x25_dgram_incoming);
pk_protolisten(0x81, 1, x25_dgram_incoming);
}
}
struct x25_dgproto {
u_char spi;
u_char spilen;
int (*f)();
} x25_dgprototab[] = {
#if defined(ISO) && defined(TPCONS)
{ 0x0, 0, tp_incoming},
#endif
{ 0xcc, 1, x25_dgram_incoming},
{ 0xcd, 1, x25_dgram_incoming},
{ 0x81, 1, x25_dgram_incoming},
};
pk_user_protolisten(info)
register u_char *info;
{
register struct x25_dgproto *dp = x25_dgprototab
+ ((sizeof x25_dgprototab) / (sizeof *dp));
register struct pklcd *lcp;
while (dp > x25_dgprototab)
if ((--dp)->spi == info[0])
goto gotspi;
return ESRCH;
gotspi: if (info[1])
return pk_protolisten(dp->spi, dp->spilen, dp->f);
for (lcp = pk_listenhead; lcp; lcp = lcp->lcd_listen)
if (lcp->lcd_laddr.x25_udlen == dp->spilen &&
Bcmp(&dp->spi, lcp->lcd_laddr.x25_udata, dp->spilen) == 0) {
pk_disconnect(lcp);
return 0;
}
return ESRCH;
}
/*
* This routine transfers an X.25 circuit to or from a routing entry.
* If the supplied circuit is * in DATA_TRANSFER state, it is added to the
* routing entry. If freshly allocated, it glues back the vc from
* the rtentry to the socket.
*/
pk_rtattach(so, m0)
register struct socket *so;
struct mbuf *m0;
{
register struct pklcd *lcp = (struct pklcd *)so->so_pcb;
register struct mbuf *m = m0;
struct sockaddr *dst = mtod(m, struct sockaddr *);
register struct rtentry *rt = rtalloc1(dst, 0, 0UL);
register struct llinfo_x25 *lx;
caddr_t cp;
#define ROUNDUP(a) \
((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
#define transfer_sockbuf(s, f, l) \
while (m = (s)->sb_mb)\
{(s)->sb_mb = m->m_act; m->m_act = 0; sbfree((s), m); f(l, m);}
if (rt)
rt->rt_refcnt--;
cp = (dst->sa_len < m->m_len) ? ROUNDUP(dst->sa_len) + (caddr_t)dst : 0;
while (rt &&
((cp == 0 && rt_mask(rt) != 0) ||
(cp != 0 && (rt_mask(rt) == 0 ||
Bcmp(cp, rt_mask(rt), rt_mask(rt)->sa_len)) != 0)))
rt = (struct rtentry *)rt->rt_nodes->rn_dupedkey;
if (rt == 0 || (rt->rt_flags & RTF_GATEWAY) ||
(lx = (struct llinfo_x25 *)rt->rt_llinfo) == 0)
return ESRCH;
if (lcp == 0)
return ENOTCONN;
switch (lcp->lcd_state) {
default:
return ENOTCONN;
case READY:
/* Detach VC from rtentry */
if (lx->lx_lcd == 0)
return ENOTCONN;
lcp->lcd_so = 0;
pk_close(lcp);
lcp = lx->lx_lcd;
if (lx->lx_next->lx_rt == rt)
x25_lxfree(lx);
lcp->lcd_so = so;
lcp->lcd_upper = 0;
lcp->lcd_upnext = 0;
transfer_sockbuf(&lcp->lcd_sb, sbappendrecord, &so->so_snd);
soisconnected(so);
return 0;
case DATA_TRANSFER:
/* Add VC to rtentry */
lcp->lcd_so = 0;
lcp->lcd_sb = so->so_snd; /* structure copy */
bzero((caddr_t)&so->so_snd, sizeof(so->so_snd)); /* XXXXXX */
so->so_pcb = 0;
x25_rtattach(lcp, rt);
transfer_sockbuf(&so->so_rcv, x25_ifinput, lcp);
soisdisconnected(so);
}
return 0;
}
static int
x25_rtattach(lcp0, rt)
register struct pklcd *lcp0;
struct rtentry *rt;
{
register struct llinfo_x25 *lx = (struct llinfo_x25 *)rt->rt_llinfo;
register struct pklcd *lcp;
register struct mbuf *m;
if (lcp = lx->lx_lcd) { /* adding an additional VC */
if (lcp->lcd_state == READY) {
transfer_sockbuf(&lcp->lcd_sb, pk_output, lcp0);
lcp->lcd_upper = 0;
pk_close(lcp);
} else {
lx = x25_lxalloc(rt);
if (lx == 0)
return ENOBUFS;
}
}
lx->lx_lcd = lcp = lcp0;
lcp->lcd_upper = x25_ifinput;
lcp->lcd_upnext = (caddr_t)lx;
}

View File

@ -1,470 +0,0 @@
/*
* Copyright (C) Dirk Husemann, Computer Science Department IV,
* University of Erlangen-Nuremberg, Germany, 1990, 1991, 1992
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Dirk Husemann and the Computer Science Department (IV) of
* the University of Erlangen-Nuremberg, Germany.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)llc_input.c 8.1 (Berkeley) 6/10/93
* $Id: llc_input.c,v 1.3 1994/12/13 22:32:13 wollman Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/domain.h>
#include <sys/socket.h>
#include <sys/protosw.h>
#include <sys/errno.h>
#include <sys/time.h>
#include <sys/kernel.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <net/if_llc.h>
#include <net/route.h>
#include <netccitt/dll.h>
#include <netccitt/llc_var.h>
/*
* This module implements LLC as specified by ISO 8802-2.
*/
/*
* llcintr() handles all LLC frames (except ISO CLNS ones for the time being)
* and tries to pass them on to the appropriate network layer entity.
*/
void
llcintr()
{
register struct mbuf *m;
register int i;
register int frame_kind;
register u_char cmdrsp;
struct llc_linkcb *linkp;
struct rtentry *sirt;
struct npaidbentry *sapinfo;
struct sdl_hdr *sdlhdr;
struct llc *frame;
char *c;
long expected_len;
struct ifnet *ifp;
struct rtentry *llrt;
struct rtentry *nlrt;
for (;;) {
i = splimp();
IF_DEQUEUE(&llcintrq, m);
splx(i);
if (m == 0)
break;
#ifdef DIAGNOSTIC
if ((m->m_flags & M_PKTHDR) == 0)
panic("llcintr no HDR");
#endif
/*
* Get ifp this packet was received on
*/
ifp = m->m_pkthdr.rcvif;
sdlhdr = mtod(m, struct sdl_hdr *);
/*
* [Copied from net/ip_input.c]
*
* Check that the amount of data in the buffers is
* at least as much as the LLC header tells us.
* Trim mbufs if longer than expected.
* Drop packets if shorter than we think they are.
*
* Layout of mbuf chain at this point:
*
* +-------------------------------+----+ -\
* | sockaddr_dl src - sdlhdr_src | 20 | \
* +-------------------------------+----+ |
* | sockaddr_dl dst - sdlhdr_dst | 20 | > sizeof(struct sdl_hdr) == 44
* +-------------------------------+----+ |
* | LLC frame len - sdlhdr_len | 04 | /
* +-------------------------------+----+ -/
* /
* | m_next
* \
* +----------------------------+----+ -\
* | llc DSAP | 01 | \
* +----------------------------+----+ |
* | llc SSAP | 01 | |
* +----------------------------+----+ > sdlhdr_len
* | llc control | 01 | |
* +----------------------------+----+ |
* | ... | | /
* -/
*
* Thus the we expect to have exactly
* (sdlhdr->sdlhdr_len+sizeof(struct sdl_hdr)) in the mbuf chain
*/
expected_len = sdlhdr->sdlhdr_len + sizeof(struct sdl_hdr);
if (m->m_pkthdr.len < expected_len) {
m_freem(m);
continue;
}
if (m->m_pkthdr.len > expected_len) {
if (m->m_len == m->m_pkthdr.len) {
m->m_len = expected_len;
m->m_pkthdr.len = expected_len;
} else
m_adj(m, expected_len - m->m_pkthdr.len);
}
/*
* Get llc header
*/
if (m->m_len > sizeof(struct sdl_hdr))
frame = mtod((struct mbuf *)((struct sdl_hdr*)(m+1)),
struct llc *);
else frame = mtod(m->m_next, struct llc *);
if (frame == (struct llc *) NULL)
panic("llcintr no llc header");
/*
* Now check for bogus I/S frame, i.e. those with a control
* field telling us they're an I/S frame yet their length
* is less than the established I/S frame length (DSAP + SSAP +
* control + N(R)&P/F = 4) --- we drop those suckers
*/
if (((frame->llc_control & 0x03) != 0x03)
&& ((expected_len - sizeof(struct sdl_hdr)) < LLC_ISFRAMELEN)) {
m_freem(m);
printf("llc: hurz error\n");
continue;
}
/*
* Get link control block for the addressed link connection.
* If there is none we take care of it later on.
*/
cmdrsp = (frame->llc_ssap & 0x01);
frame->llc_ssap &= ~0x01;
if (llrt = rtalloc1((struct sockaddr *)&sdlhdr->sdlhdr_src, 0,
0UL))
llrt->rt_refcnt--;
#ifdef notyet
else llrt = npaidb_enter(&sdlhdr->sdlhdr_src, 0, 0, 0);
#endif /* notyet */
else {
/*
* We cannot do anything currently here as we
* don't `know' this link --- drop it
*/
m_freem(m);
continue;
}
linkp = ((struct npaidbentry *)(llrt->rt_llinfo))->np_link;
nlrt = ((struct npaidbentry *)(llrt->rt_llinfo))->np_rt;
/*
* If the link is not existing right now, we can try and look up
* the SAP info block.
*/
if ((linkp == 0) && frame->llc_ssap)
sapinfo = llc_getsapinfo(frame->llc_dsap, ifp);
/*
* Handle XID and TEST frames
* XID: if DLSAP == 0, return type-of-services
* window-0
* DLSAP-0
* format-identifier-?
* if DLSAP != 0, locate sapcb and return
* type-of-services
* SAP-window
* format-identifier-?
* TEST: swap (snpah_dst, snpah_src) and return frame
*
* Also toggle the CMD/RESP bit
*
* Is this behaviour correct? Check ISO 8802-2 (90)!
*/
frame_kind = llc_decode(frame, (struct llc_linkcb *)0);
switch(frame_kind) {
case LLCFT_XID:
if (linkp || sapinfo) {
if (linkp)
frame->llc_window = linkp->llcl_window;
else frame->llc_window = sapinfo->si_window;
frame->llc_fid = 9; /* XXX */
frame->llc_class = sapinfo->si_class;
frame->llc_ssap = frame->llc_dsap;
} else {
frame->llc_window = 0;
frame->llc_fid = 9;
frame->llc_class = 1;
frame->llc_dsap = frame->llc_ssap = 0;
}
/* fall thru to */
case LLCFT_TEST:
sdl_swapaddr(&(mtod(m, struct sdl_hdr *)->sdlhdr_dst),
&(mtod(m, struct sdl_hdr *)->sdlhdr_src));
/* Now set the CMD/RESP bit */
frame->llc_ssap |= (cmdrsp == 0x0 ? 0x1 : 0x0);
/* Ship it out again */
(*ifp->if_output)(ifp, m,
(struct sockaddr *) &(mtod(m, struct sdl_hdr *)->sdlhdr_dst),
(struct rtentry *) 0);
continue;
}
/*
* Create link control block in case it is not existing
*/
if (linkp == 0 && sapinfo) {
if ((linkp = llc_newlink(&sdlhdr->sdlhdr_src, ifp, nlrt,
(nlrt == 0) ? 0 : nlrt->rt_llinfo,
llrt)) == 0) {
printf("llcintr: couldn't create new link\n");
m_freem(m);
continue;
}
((struct npaidbentry *)llrt->rt_llinfo)->np_link = linkp;
} else if (linkp == 0) {
/* The link is not known to us, drop the frame and continue */
m_freem(m);
continue;
}
/*
* Drop SNPA header and get rid of empty mbuf at the
* front of the mbuf chain (I don't like 'em)
*/
m_adj(m, sizeof(struct sdl_hdr));
/*
* LLC_UFRAMELEN is sufficient, m_pullup() will pull up
* the min(m->m_len, maxprotohdr_len [=40]) thus doing
* the trick ...
*/
if ((m = m_pullup(m, LLC_UFRAMELEN)))
/*
* Pass it on thru the elements of procedure
*/
llc_input(linkp, m, cmdrsp);
}
return;
}
/*
* llc_input() --- We deal with the various incoming frames here.
* Basically we (indirectly) call the appropriate
* state handler function that's pointed to by
* llcl_statehandler.
*
* The statehandler returns an action code ---
* further actions like
* o notify network layer
* o block further sending
* o deblock link
* o ...
* are then enacted accordingly.
*/
llc_input(struct llc_linkcb *linkp, struct mbuf *m, u_char cmdrsp)
{
int frame_kind;
int pollfinal;
int action = 0;
struct llc *frame;
struct ifnet *ifp = linkp->llcl_if;
if ((frame = mtod(m, struct llc *)) == (struct llc *) 0) {
m_freem(m);
return 0;
}
pollfinal = ((frame->llc_control & 0x03) == 0x03) ?
LLCGBITS(frame->llc_control, u_pf) :
LLCGBITS(frame->llc_control_ext, s_pf);
/*
* first decode the frame
*/
frame_kind = llc_decode(frame, linkp);
switch (action = llc_statehandler(linkp, frame, frame_kind, cmdrsp,
pollfinal)) {
case LLC_DATA_INDICATION:
m_adj(m, LLC_ISFRAMELEN);
if (m = m_pullup(m, NLHDRSIZEGUESS)) {
m->m_pkthdr.rcvif = (struct ifnet *)linkp->llcl_nlnext;
(*linkp->llcl_sapinfo->si_input)(m);
}
break;
}
/* release mbuf if not an info frame */
if (action != LLC_DATA_INDICATION && m)
m_freem(m);
/* try to get frames out ... */
llc_start(linkp);
return 0;
}
/*
* This routine is called by configuration setup. It sets up a station control
* block and notifies all registered upper level protocols.
*/
caddr_t
llc_ctlinput(int prc, struct sockaddr *addr, caddr_t info)
{
struct ifnet *ifp;
struct ifaddr *ifa;
struct dll_ctlinfo *ctlinfo = (struct dll_ctlinfo *)info;
u_char sap;
struct dllconfig *config;
caddr_t pcb;
struct rtentry *nlrt;
struct rtentry *llrt;
struct llc_linkcb *linkp;
register int i;
/* info must point to something valid at all times */
if (info == 0)
return 0;
if (prc == PRC_IFUP || prc == PRC_IFDOWN) {
/* we use either this set ... */
ifa = ifa_ifwithaddr(addr);
ifp = ifa ? ifa->ifa_ifp : 0;
if (ifp == 0)
return 0;
sap = ctlinfo->dlcti_lsap;
config = ctlinfo->dlcti_cfg;
pcb = (caddr_t) 0;
nlrt = (struct rtentry *) 0;
} else {
/* or this one */
sap = 0;
config = (struct dllconfig *) 0;
pcb = ctlinfo->dlcti_pcb;
nlrt = ctlinfo->dlcti_rt;
if ((llrt = rtalloc1(nlrt->rt_gateway, 0, 0UL)))
llrt->rt_refcnt--;
else return 0;
linkp = ((struct npaidbentry *)llrt->rt_llinfo)->np_link;
}
switch (prc) {
case PRC_IFUP:
(void) llc_setsapinfo(ifp, addr->sa_family, sap, config);
return 0;
case PRC_IFDOWN: {
register struct llc_linkcb *linkp;
register struct llc_linkcb *nlinkp;
register int i;
/*
* All links are accessible over the doubly linked list llccb_q
*/
if (!LQEMPTY) {
/*
* A for-loop is not that great an idea as the linkp
* will get deleted by llc_timer()
*/
linkp = LQFIRST;
while (LQVALID(linkp)) {
nlinkp = LQNEXT(linkp);
if (linkp->llcl_if = ifp) {
i = splimp();
(void)llc_statehandler(linkp, (struct llc *)0,
NL_DISCONNECT_REQUEST,
0, 1);
splx(i);
}
linkp = nlinkp;
}
}
}
case PRC_CONNECT_REQUEST:
if (linkp == 0) {
if ((linkp = llc_newlink((struct sockaddr_dl *) nlrt->rt_gateway,
nlrt->rt_ifp, nlrt,
pcb, llrt)) == 0)
return (0);
((struct npaidbentry *)llrt->rt_llinfo)->np_link = linkp;
i = splimp();
(void)llc_statehandler(linkp, (struct llc *) 0,
NL_CONNECT_REQUEST, 0, 1);
splx(i);
}
return ((caddr_t)linkp);
case PRC_DISCONNECT_REQUEST:
if (linkp == 0)
panic("no link control block!");
i = splimp();
(void)llc_statehandler(linkp, (struct llc *) 0,
NL_DISCONNECT_REQUEST, 0, 1);
splx(i);
/*
* The actual removal of the link control block is done by the
* cleaning neutrum (i.e. llc_timer()).
*/
break;
case PRC_RESET_REQUEST:
if (linkp == 0)
panic("no link control block!");
i = splimp();
(void)llc_statehandler(linkp, (struct llc *) 0,
NL_RESET_REQUEST, 0, 1);
splx(i);
break;
}
return 0;
}

View File

@ -1,305 +0,0 @@
/*
* Copyright (C) Dirk Husemann, Computer Science Department IV,
* University of Erlangen-Nuremberg, Germany, 1990, 1991, 1992
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Dirk Husemann and the Computer Science Department (IV) of
* the University of Erlangen-Nuremberg, Germany.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)llc_output.c 8.1 (Berkeley) 6/10/93
* $Id: llc_output.c,v 1.3 1995/03/19 14:29:00 davidg Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/domain.h>
#include <sys/socket.h>
#include <sys/protosw.h>
#include <sys/errno.h>
#include <sys/time.h>
#include <sys/kernel.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <net/if_llc.h>
#include <net/route.h>
#include <netccitt/dll.h>
#include <netccitt/llc_var.h>
/*
* llc_output() --- called by an upper layer (network layer) entity whenever
* there is an INFO frame to be transmitted. We enqueue the
* info frame and call llc_start() to do the actual sending.
*/
llc_output(struct llc_linkcb *linkp, struct mbuf *m)
{
register int i;
i = splimp();
LLC_ENQUEUE(linkp, m);
llc_start(linkp);
splx(i);
}
/*
* llc_start() --- We try to subsequently dequeue all the frames available and
* send them out.
*/
void
llc_start(struct llc_linkcb *linkp)
{
register int i;
register struct mbuf *m;
int action;
while ((LLC_STATEEQ(linkp, NORMAL) || LLC_STATEEQ(linkp, BUSY) ||
LLC_STATEEQ(linkp, REJECT)) &&
(linkp->llcl_slotsfree > 0) &&
(LLC_GETFLAG(linkp, REMOTE_BUSY) == 0)) {
LLC_DEQUEUE(linkp, m);
if (m == NULL)
break;
LLC_SETFRAME(linkp, m);
(void)llc_statehandler(linkp, (struct llc *) 0, NL_DATA_REQUEST,
0, 0);
}
}
/*
* llc_send() --- Handles single frames. If dealing with INFO frames we need to
* prepend the LLC header, otherwise we just allocate an mbuf.
* In both cases the actual send is done by llc_rawsend().
*/
llc_send(struct llc_linkcb *linkp, int frame_kind, int cmdrsp, int pollfinal)
{
register struct mbuf *m = (struct mbuf *)0;
register struct llc *frame;
if (frame_kind == LLCFT_INFO)
m = linkp->llcl_output_buffers[llc_seq2slot(linkp,
linkp->llcl_vs)];
LLC_GETHDR(frame, m);
/* pass it on to llc_rawsend() */
llc_rawsend(linkp, m, frame, frame_kind, linkp->llcl_vs, cmdrsp, pollfinal);
if (frame_kind == LLCFT_INFO)
LLC_INC(linkp->llcl_vs);
return 0;
}
/*
* llc_resend() --- llc_resend() retransmits all unacknowledged INFO frames.
*/
llc_resend(struct llc_linkcb *linkp, int cmdrsp, int pollfinal)
{
register struct llc *frame;
register struct mbuf *m;
register int seq, slot;
if (linkp->llcl_slotsfree < linkp->llcl_window)
/* assert lock between nr_received & V(S) */
if (linkp->llcl_nr_received != linkp->llcl_vs)
panic("llc: V(S) != N(R) received");
for (slot = llc_seq2slot(linkp, linkp->llcl_vs);
slot != linkp->llcl_freeslot;
LLC_INC(linkp->llcl_vs),
slot = llc_seq2slot(linkp, linkp->llcl_vs)) {
m = linkp->llcl_output_buffers[slot];
LLC_GETHDR(frame, m);
llc_rawsend(linkp, m, frame, LLCFT_INFO, linkp->llcl_vs,
cmdrsp, pollfinal);
pollfinal = 0;
}
return 0;
}
/*
* llc_rawsend() --- constructs an LLC frame and sends it out via the
* associated interface of the link control block.
*
* We need to make sure that outgoing frames have the correct length,
* in particular the 4 byte ones (RR, RNR, REJ) as LLC_GETHDR() will
* set the mbuf len to 3 as default len for non INFO frames ...
*
* Frame kind Length (w/o MAC header, {D,S}SAP incl.)
* --------------------------------------------------------------
* DISC, SABME, UA, DM 3 bytes ({D,S}SAP + CONTROL)
* RR, RNR, REJ 4 bytes ({D,S}SAP + CONTROL0 + CONTROL1)
* XID 6 bytes ({D,S}SAP + CONTROL0 + FI,CLASS,WINDOW)
* FRMR 7 bytes ({D,S}SAP + CONTROL0 + REJ CONTROL,V(S),V(R),CAUSE)
* INFO 4 -- MTU
* UI, TEST 3 -- MTU
*
*/
#define LLC_SETLEN(m, l) (m)->m_pkthdr.len = (m)->m_len = (l)
llc_rawsend(struct llc_linkcb *linkp, struct mbuf *m, struct llc *frame,
int frame_kind, int vs, int cmdrsp, int pollfinal)
{
register short adjust = LLC_UFRAMELEN;
struct ifnet *ifp;
switch (frame_kind) {
/* supervisory and information frames */
case LLCFT_INFO:
frame->llc_control = LLC_INFO;
LLCSBITS(frame->llc_control, i_ns, vs);
LLCSBITS(frame->llc_control_ext, i_nr, linkp->llcl_vr);
adjust = LLC_ISFRAMELEN;
break;
case LLCFT_RR:
frame->llc_control = LLC_RR;
LLC_SETLEN(m, LLC_ISFRAMELEN);
LLCSBITS(frame->llc_control_ext, s_nr, linkp->llcl_vr);
adjust = LLC_ISFRAMELEN;
break;
case LLCFT_RNR:
frame->llc_control = LLC_RNR;
LLC_SETLEN(m, LLC_ISFRAMELEN);
LLCSBITS(frame->llc_control_ext, s_nr, linkp->llcl_vr);
adjust = LLC_ISFRAMELEN;
break;
case LLCFT_REJ:
frame->llc_control = LLC_REJ;
LLC_SETLEN(m, LLC_ISFRAMELEN);
LLCSBITS(frame->llc_control_ext, s_nr, linkp->llcl_vr);
adjust = LLC_ISFRAMELEN;
break;
/* unnumbered frames */
case LLCFT_DM:
frame->llc_control = LLC_DM;
break;
case LLCFT_SABME:
frame->llc_control = LLC_SABME;
break;
case LLCFT_DISC:
frame->llc_control = LLC_DISC;
break;
case LLCFT_UA:
frame->llc_control = LLC_UA;
break;
case LLCFT_UI:
frame->llc_control = LLC_UI;
break;
case LLCFT_FRMR:
frame->llc_control = LLC_FRMR;
/* get more space --- FRMR frame are longer then usual */
LLC_SETLEN(m, LLC_FRMRLEN);
bcopy((caddr_t) &linkp->llcl_frmrinfo,
(caddr_t) &frame->llc_frmrinfo,
sizeof(struct frmrinfo));
break;
default:
/*
* We don't send {XID, TEST} frames
*/
if (m)
m_freem(m);
return;
}
/*
* Fill in DSAP/SSAP
*/
frame->llc_dsap = frame->llc_ssap = LLSAPADDR(&linkp->llcl_addr);
frame->llc_ssap |= cmdrsp;
/*
* Check for delayed action pending. ISO 8802-2, 7.9.2 (5)
* and ISO 8802-2, 7.9.2.3 (32), (34), (36) pertain to this
* piece of code --- hopefully we got it right here (i.e.
* in the spirit of (32), (34), and (36) ...
*/
switch (frame_kind) {
case LLCFT_RR:
case LLCFT_RNR:
case LLCFT_REJ:
case LLCFT_INFO:
switch (LLC_GETFLAG(linkp, DACTION)) {
case LLC_DACKCMD:
case LLC_DACKRSP:
LLC_STOPTIMER(linkp, DACTION);
break;
case LLC_DACKCMDPOLL:
if (cmdrsp == LLC_CMD) {
pollfinal = 1;
LLC_STOPTIMER(linkp, DACTION);
}
break;
case LLC_DACKRSPFINAL:
if (cmdrsp == LLC_RSP) {
pollfinal = 1;
LLC_STOPTIMER(linkp, DACTION);
}
break;
}
break;
}
if (adjust == LLC_UFRAMELEN)
LLCSBITS(frame->llc_control, u_pf, pollfinal);
else LLCSBITS(frame->llc_control_ext, s_pf, pollfinal);
/*
* Get interface to send frame onto
*/
ifp = linkp->llcl_if;
if (frame_kind == LLCFT_INFO) {
/*
* send out a copy of the frame, retain the
* original
*/
(*ifp->if_output)(ifp, m_copy(m, 0, (int)M_COPYALL),
rt_key(linkp->llcl_nlrt),
linkp->llcl_nlrt);
/*
* Account for the LLC header and let it ``disappear''
* as the raw info frame payload is what we hold in
* the output_buffers of the link.
*/
m_adj(m, LLC_ISFRAMELEN);
} else (*ifp->if_output)(ifp, m,
rt_key(linkp->llcl_nlrt),
linkp->llcl_nlrt);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,181 +0,0 @@
/*
* Copyright (C) Dirk Husemann, Computer Science Department IV,
* University of Erlangen-Nuremberg, Germany, 1990, 1991, 1992
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Dirk Husemann and the Computer Science Department (IV) of
* the University of Erlangen-Nuremberg, Germany.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)llc_timer.c 8.1 (Berkeley) 6/10/93
* $Id: llc_timer.c,v 1.2 1994/08/02 07:47:23 davidg Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/domain.h>
#include <sys/socket.h>
#include <sys/protosw.h>
#include <sys/errno.h>
#include <sys/time.h>
#include <sys/kernel.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <net/if_llc.h>
#include <netccitt/dll.h>
#include <netccitt/llc_var.h>
/*
* Various timer values. They can be adjusted
* by patching the binary with adb if necessary.
*/
/* ISO 8802-2 timers */
int llc_n2 = LLC_N2_VALUE;
int llc_ACK_timer = LLC_ACK_TIMER;
int llc_P_timer = LLC_P_TIMER;
int llc_BUSY_timer = LLC_BUSY_TIMER;
int llc_REJ_timer = LLC_REJ_TIMER;
/* Implementation specific timers */
int llc_AGE_timer = LLC_AGE_TIMER;
int llc_DACTION_timer = LLC_DACTION_TIMER;
/*
* The timer routine. We are called every 500ms by the kernel.
* Handle the various virtual timers.
*/
void
llc_timer()
{
register struct llc_linkcb *linkp;
register struct llc_linkcb *nlinkp;
register int timer;
register int action;
register int s = splimp();
/*
* All links are accessible over the doubly linked list llccb_q
*/
if (!LQEMPTY) {
/*
* A for-loop is not that great an idea as the linkp
* might get deleted if the age timer has expired ...
*/
linkp = LQFIRST;
while (LQVALID(linkp)) {
nlinkp = LQNEXT(linkp);
/*
* Check implementation specific timers first
*/
/* The delayed action/acknowledge idle timer */
switch (LLC_TIMERXPIRED(linkp, DACTION)) {
case LLC_TIMER_RUNNING:
LLC_AGETIMER(linkp, DACTION);
break;
case LLC_TIMER_EXPIRED: {
register int cmdrsp;
register int pollfinal;
switch (LLC_GETFLAG(linkp, DACTION)) {
case LLC_DACKCMD:
cmdrsp = LLC_CMD, pollfinal = 0;
break;
case LLC_DACKCMDPOLL:
cmdrsp = LLC_CMD, pollfinal = 1;
break;
case LLC_DACKRSP:
cmdrsp = LLC_RSP, pollfinal = 0;
break;
case LLC_DACKRSPFINAL:
cmdrsp = LLC_RSP, pollfinal = 1;
break;
}
llc_send(linkp, LLCFT_RR, cmdrsp, pollfinal);
LLC_STOPTIMER(linkp, DACTION);
break;
}
}
/* The link idle timer */
switch (LLC_TIMERXPIRED(linkp, AGE)) {
case LLC_TIMER_RUNNING:
LLC_AGETIMER(linkp, AGE);
break;
case LLC_TIMER_EXPIRED:
/*
* Only crunch the link when really no
* timers are running any more.
*/
if (llc_anytimersup(linkp) == 0) {
llc_dellink(linkp);
LLC_STOPTIMER(linkp, AGE);
goto gone;
} else {
LLC_STARTTIMER(linkp, AGE);
}
break;
}
/*
* Now, check all the ISO 8802-2 timers
*/
FOR_ALL_LLC_TIMERS(timer) {
action = 0;
if ((linkp->llcl_timerflags & (1<<timer)) &&
(linkp->llcl_timers[timer] == 0)) {
switch (timer) {
case LLC_ACK_SHIFT:
action = LLC_ACK_TIMER_EXPIRED;
break;
case LLC_P_SHIFT:
action = LLC_P_TIMER_EXPIRED;
break;
case LLC_BUSY_SHIFT:
action = LLC_BUSY_TIMER_EXPIRED;
break;
case LLC_REJ_SHIFT:
action = LLC_REJ_TIMER_EXPIRED;
break;
}
linkp->llcl_timerflags &= ~(1<<timer);
(void)llc_statehandler(linkp, (struct llc *)0, action, 0, 1);
} else if (linkp->llcl_timers[timer] > 0)
linkp->llcl_timers[timer]--;
}
gone: linkp = nlinkp;
}
}
splx (s);
}

View File

@ -1,640 +0,0 @@
/*
* Copyright (C) Dirk Husemann, Computer Science Department IV,
* University of Erlangen-Nuremberg, Germany, 1990, 1991, 1992
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Dirk Husemann and the Computer Science Department (IV) of
* the University of Erlangen-Nuremberg, Germany.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)llc_var.h 8.1 (Berkeley) 6/10/93
* $Id: llc_var.h,v 1.5 1995/07/29 11:41:24 bde Exp $
*/
#ifndef _NETCCITT_LLC_VAR_H_
#define _NETCCITT_LLC_VAR_H_
#ifdef __STDC__
/*
* Forward structure declarations for function prototypes [sic].
*/
struct llc;
#endif
#define NPAIDB_LINK 0
struct npaidbentry {
union {
/* MAC,DLSAP -> CONS */
struct {
struct llc_linkcb *NE_link;
struct rtentry *NE_rt;
} NE;
/* SAP info for unconfigured incoming calls */
struct {
u_short SI_class;
#define LLC_CLASS_I 0x1
#define LLC_CLASS_II 0x3
#define LLC_CLASS_III 0x4 /* Future */
#define LLC_CLASS_IV 0x7 /* Future */
u_short SI_window;
u_short SI_trace;
u_short SI_xchxid;
void (*SI_input)
__P((struct mbuf *));
caddr_t (*SI_ctlinput)
__P((int, struct sockaddr *, caddr_t));
} SI;
} NESIun;
};
#define np_link NESIun.NE.NE_link
#define np_rt NESIun.NE.NE_rt
#define si_class NESIun.SI.SI_class
#define si_window NESIun.SI.SI_window
#define si_trace NESIun.SI.SI_trace
#define si_xchxid NESIun.SI.SI_xchxid
#define si_input NESIun.SI.SI_input
#define si_ctlinput NESIun.SI.SI_ctlinput
#define NPDL_SAPNETMASK 0x7e
/*
* Definitions for accessing bitfields/bitslices inside
* LLC2 headers
*/
struct bitslice {
unsigned int bs_mask;
unsigned int bs_shift;
};
#define i_z 0
#define i_ns 1
#define i_pf 0
#define i_nr 1
#define s_oz 2
#define s_selector 3
#define s_pf 0
#define s_nr 1
#define u_bb 2
#define u_select_other 3
#define u_pf 4
#define u_select 5
#define f_vs 1
#define f_cr 0
#define f_vr 1
#define f_wxyzv 6
#define LLCGBITS(Arg, Index) (((Arg) & llc_bitslice[(Index)].bs_mask) >> llc_bitslice[(Index)].bs_shift)
#define LLCSBITS(Arg, Index, Val) (Arg) |= (((Val) << llc_bitslice[(Index)].bs_shift) & llc_bitslice[(Index)].bs_mask)
#define LLCCSBITS(Arg, Index, Val) (Arg) = (((Val) << llc_bitslice[(Index)].bs_shift) & llc_bitslice[(Index)].bs_mask)
extern struct bitslice llc_bitslice[];
#define LLC_CMD 0
#define LLC_RSP 1
#define LLC_MAXCMDRSP 2
/*
* LLC events --- These events may either be frames received from the
* remote LLC DSAP, request from the network layer user,
* timer events from llc_timer(), or diagnostic events from
* llc_input().
*/
/* LLC frame types */
#define LLCFT_INFO 0 * LLC_MAXCMDRSP
#define LLCFT_RR 1 * LLC_MAXCMDRSP
#define LLCFT_RNR 2 * LLC_MAXCMDRSP
#define LLCFT_REJ 3 * LLC_MAXCMDRSP
#define LLCFT_DM 4 * LLC_MAXCMDRSP
#define LLCFT_SABME 5 * LLC_MAXCMDRSP
#define LLCFT_DISC 6 * LLC_MAXCMDRSP
#define LLCFT_UA 7 * LLC_MAXCMDRSP
#define LLCFT_FRMR 8 * LLC_MAXCMDRSP
#define LLCFT_UI 9 * LLC_MAXCMDRSP
#define LLCFT_XID 10 * LLC_MAXCMDRSP
#define LLCFT_TEST 11 * LLC_MAXCMDRSP
/* LLC2 timer events */
#define LLC_ACK_TIMER_EXPIRED 12 * LLC_MAXCMDRSP
#define LLC_P_TIMER_EXPIRED 13 * LLC_MAXCMDRSP
#define LLC_REJ_TIMER_EXPIRED 14 * LLC_MAXCMDRSP
#define LLC_BUSY_TIMER_EXPIRED 15 * LLC_MAXCMDRSP
/* LLC2 diagnostic events */
#define LLC_INVALID_NR 16 * LLC_MAXCMDRSP
#define LLC_INVALID_NS 17 * LLC_MAXCMDRSP
#define LLC_BAD_PDU 18 * LLC_MAXCMDRSP
#define LLC_LOCAL_BUSY_DETECTED 19 * LLC_MAXCMDRSP
#define LLC_LOCAL_BUSY_CLEARED 20 * LLC_MAXCMDRSP
/* Network layer user requests */
/*
* NL_CONNECT_REQUEST --- The user has requested that a data link connection
* be established with a remote LLC DSAP.
*/
#define NL_CONNECT_REQUEST 21 * LLC_MAXCMDRSP
/*
* NL_CONNECT_RESPONSE --- The user has accepted the data link connection.
*/
#define NL_CONNECT_RESPONSE 22 * LLC_MAXCMDRSP
/*
* NL_RESET_REQUEST --- The user has requested that the data link with the
* remote LLC DSAP be reset.
*/
#define NL_RESET_REQUEST 23 * LLC_MAXCMDRSP
/*
* NL_RESET_RESPONSE --- The user has accepted the reset of the data link
* connection.
*/
#define NL_RESET_RESPONSE 24 * LLC_MAXCMDRSP
/*
* NL_DISCONNECT_REQUEST --- The user has requested that the data link
* connection with remote LLC DSAP be terminated.
*/
#define NL_DISCONNECT_REQUEST 25 * LLC_MAXCMDRSP
/*
* NL_DATA_REQUEST --- The user has requested that a data unit be sent ot the
* remote LLC DSAP.
*/
#define NL_DATA_REQUEST 26 * LLC_MAXCMDRSP
/*
* NL_INITIATE_PF_CYCLE --- The local LLC wants to initiate a P/F cycle.
*/
#define NL_INITIATE_PF_CYCLE 27 * LLC_MAXCMDRSP
/*
* NL_LOCAL_BUSY_DETECTED --- The local entity has encountered a busy condition
*/
#define NL_LOCAL_BUSY_DETECTED 28 * LLC_MAXCMDRSP
#define LLCFT_NONE 255
/* return message from state handlers */
/*
* LLC_CONNECT_INDICATION --- Inform the user that a connection has been
* requested by a remote LLC SSAP.
*/
#define LLC_CONNECT_INDICATION 1
/*
* LLC_CONNECT_CONFIRM --- The connection service component indicates that the
* remote network entity has accepted the connection.
*/
#define LLC_CONNECT_CONFIRM 2
/*
* LLC_DISCONNECT_INDICATION --- Inform the user that the remote network
* entity has intiated disconnection of the data
* link connection.
*/
#define LLC_DISCONNECT_INDICATION 3
/*
* LLC_RESET_CONFIRM --- The connection service component indicates that the
* remote network entity has accepted the reset.
*/
#define LLC_RESET_CONFIRM 4
/*
* LLC_RESET_INDICATION_REMOTE --- The remote network entity or remote peer
* has initiated a reset of the data link
* connection.
*/
#define LLC_RESET_INDICATION_REMOTE 5
/*
* LLC_RESET_INDICATION_LOCAL --- The local LLC has determined that the data
* link connection is in need of
* reinitialization.
*/
#define LLC_RESET_INDICATION_LOCAL 6
/*
* LLC_FRMR_RECEIVED --- The local connection service component has received a
* FRMR response PDU.
*/
#define LLC_FRMR_RECEIVED 7
/*
* LLC_FRMR_SENT --- The local connection component has received an ivalid
* PDU, and has sent a FRMR response PDU.
*/
#define LLC_FRMR_SENT 8
/*
* LLC_DATA_INDICATION --- The connection service component passes the data
* unit from the received I PDU to the user.
*/
#define LLC_DATA_INDICATION 9
/*
* LLC_REMOTE_NOT_BUSY --- The remote LLC DSAP is no longer busy. The local
* connection service component will now accept a
* DATA_REQUEST.
*/
#define LLC_REMOTE_NOT_BUSY 10
/*
* LLC_REMOTE_BUSY --- The remote LLC DSAP is busy. The local connection
* service component will not accept a DATA_REQUEST.
*/
#define LLC_REMOTE_BUSY 11
/* Internal return code */
#define LLC_PASSITON 255
#define INFORMATION_CONTROL 0x00
#define SUPERVISORY_CONTROL 0x02
#define UNUMBERED_CONTROL 0x03
/*
* Other necessary definitions
*/
#define LLC_MAX_SEQUENCE 128
#define LLC_MAX_WINDOW 127
#define LLC_WINDOW_SIZE 7
/*
* Don't we love this one? CCITT likes to suck on bits 8=)
*/
#define NLHDRSIZEGUESS 3
/*
* LLC control block
*/
struct llc_linkcb {
struct llccb_q {
struct llccb_q *q_forw; /* admin chain */
struct llccb_q *q_backw;
} llcl_q;
struct npaidbentry *llcl_sapinfo; /* SAP information */
struct sockaddr_dl llcl_addr; /* link snpa address */
struct rtentry *llcl_nlrt; /* layer 3 -> LLC */
struct rtentry *llcl_llrt; /* LLC -> layer 3 */
struct ifnet *llcl_if; /* our interface */
caddr_t llcl_nlnext; /* cb for network layer */
struct mbuf *llcl_writeqh; /* Write queue head */
struct mbuf *llcl_writeqt; /* Write queue tail */
struct mbuf **llcl_output_buffers;
short llcl_timers[6]; /* timer array */
long llcl_timerflags; /* flags signalling running timers */
int (*llcl_statehandler)
__P((struct llc_linkcb *, struct llc *, int, int, int));
int llcl_P_flag;
int llcl_F_flag;
int llcl_S_flag;
int llcl_DATA_flag;
int llcl_REMOTE_BUSY_flag;
int llcl_DACTION_flag; /* delayed action */
int llcl_retry;
/*
* The following components deal --- in one way or the other ---
* with the LLC2 window. Indicated by either [L] or [W] is the
* domain of the specific component:
*
* [L] The domain is 0--LLC_MAX_WINDOW
* [W] The domain is 0--llcl_window
*/
short llcl_vr; /* next to receive [L] */
short llcl_vs; /* next to send [L] */
short llcl_nr_received; /* next frame to b ack'd [L] */
short llcl_freeslot; /* next free slot [W] */
short llcl_projvs; /* V(S) associated with freeslot */
short llcl_slotsfree; /* free slots [W] */
short llcl_window; /* window size */
/*
* In llcl_frmrinfo we jot down the last frmr info field, which we
* need to do as we need to be able to resend it in the ERROR state.
*/
struct frmrinfo llcl_frmrinfo; /* last FRMR info field */
};
#define llcl_frmr_pdu0 llcl_frmrinfo.rej_pdu_0
#define llcl_frmr_pdu1 llcl_frmrinfo.rej_pdu_1
#define llcl_frmr_control llcl_frmrinfo.frmr_control
#define llcl_frmr_control_ext llcl_frmrinfo.frmr_control_ext
#define llcl_frmr_cause llcl_frmrinfo.frmr_cause
#define LQNEXT(l) (struct llc_linkcb *)((l)->llcl_q.q_forw)
#define LQEMPTY (llccb_q.q_forw == &llccb_q)
#define LQFIRST (struct llc_linkcb *)(llccb_q.q_forw)
#define LQVALID(l) (!((struct llccb_q *)(l) == &llccb_q))
#define LLC_ENQUEUE(l, m) if ((l)->llcl_writeqh == NULL) { \
(l)->llcl_writeqh = (m); \
(l)->llcl_writeqt = (m); \
} else { \
(l)->llcl_writeqt->m_nextpkt = (m); \
(l)->llcl_writeqt = (m); \
}
#define LLC_DEQUEUE(l, m) if ((l)->llcl_writeqh == NULL) \
(m) = NULL; \
else { \
(m) = (l)->llcl_writeqh; \
(l)->llcl_writeqh = (l)->llcl_writeqh->m_nextpkt; \
}
#define LLC_SETFRAME(l, m) { \
if ((l)->llcl_slotsfree > 0) { \
(l)->llcl_slotsfree--; \
(l)->llcl_output_buffers[(l)->llcl_freeslot] = (m); \
(l)->llcl_freeslot = ((l)->llcl_freeslot+1) % (l)->llcl_window; \
LLC_INC((l)->llcl_projvs); \
} \
}
/*
* handling of sockaddr_dl's
*/
#define LLADDRLEN(s) ((s)->sdl_alen + (s)->sdl_nlen)
#define LLSAPADDR(s) ((s)->sdl_data[LLADDRLEN(s)-1] & 0xff)
#define LLSAPLOC(s, if) ((s)->sdl_nlen + (if)->if_addrlen)
struct sdl_hdr {
struct sockaddr_dl sdlhdr_dst;
struct sockaddr_dl sdlhdr_src;
long sdlhdr_len;
};
#define LLC_GETHDR(f,m) { \
struct mbuf *_m = (struct mbuf *) (m); \
if (_m) { \
M_PREPEND(_m, LLC_ISFRAMELEN, M_DONTWAIT); \
bzero(mtod(_m, caddr_t), LLC_ISFRAMELEN); \
} else { \
MGETHDR (_m, M_DONTWAIT, MT_HEADER); \
if (_m != NULL) { \
_m->m_pkthdr.len = _m->m_len = LLC_UFRAMELEN; \
_m->m_next = _m->m_act = NULL; \
bzero(mtod(_m, caddr_t), LLC_UFRAMELEN); \
} else return; \
} \
(m) = _m; \
(f) = mtod(m, struct llc *); \
}
#define LLC_NEWSTATE(l, LLCstate) (l)->llcl_statehandler = llc_state_##LLCstate
#define LLC_STATEEQ(l, LLCstate) ((l)->llcl_statehandler == llc_state_##LLCstate ? 1 : 0)
#define LLC_ACK_SHIFT 0
#define LLC_P_SHIFT 1
#define LLC_BUSY_SHIFT 2
#define LLC_REJ_SHIFT 3
#define LLC_AGE_SHIFT 4
#define LLC_DACTION_SHIFT 5
#define LLC_TIMER_NOTRUNNING 0
#define LLC_TIMER_RUNNING 1
#define LLC_TIMER_EXPIRED 2
#define LLC_STARTTIMER(l, LLCtimer) { \
(l)->llcl_timers[LLC_##LLCtimer##_SHIFT] = llc_##LLCtimer##_timer; \
(l)->llcl_timerflags |= (1<<LLC_##LLCtimer##_SHIFT); \
}
#define LLC_STOPTIMER(l, LLCtimer) { \
(l)->llcl_timers[LLC_##LLCtimer##_SHIFT] = 0; \
(l)->llcl_timerflags &= ~(1<<LLC_##LLCtimer##_SHIFT); \
}
#define LLC_AGETIMER(l, LLCtimer) if ((l)->llcl_timers[LLC_##LLCtimer##_SHIFT] > 0) \
(l)->llcl_timers[LLC_##LLCtimer##_SHIFT]--;
#define LLC_TIMERXPIRED(l, LLCtimer) \
(((l)->llcl_timerflags & (1<<LLC_##LLCtimer##_SHIFT)) ? \
(((l)->llcl_timers[LLC_##LLCtimer##_SHIFT] == 0 ) ? \
LLC_TIMER_EXPIRED : LLC_TIMER_RUNNING) : LLC_TIMER_NOTRUNNING)
#define FOR_ALL_LLC_TIMERS(t) for ((t) = LLC_ACK_SHIFT; (t) < LLC_AGE_SHIFT; (t)++)
#define LLC_SETFLAG(l, LLCflag, v) (l)->llcl_##LLCflag##_flag = (v)
#define LLC_GETFLAG(l, LLCflag) (l)->llcl_##LLCflag##_flag
#define LLC_RESETCOUNTER(l) { \
(l)->llcl_vs = (l)->llcl_vr = (l)->llcl_retry = 0; \
llc_resetwindow((l)); \
}
/*
* LLC2 macro definitions
*/
#define LLC_START_ACK_TIMER(l) LLC_STARTTIMER((l), ACK)
#define LLC_STOP_ACK_TIMER(l) LLC_STOPTIMER((l), ACK)
#define LLC_START_REJ_TIMER(l) LLC_STARTTIMER((l), REJ)
#define LLC_STOP_REJ_TIMER(l) LLC_STOPTIMER((l), REJ)
#define LLC_START_P_TIMER(l) { \
LLC_STARTTIMER((l), P); \
if (LLC_GETFLAG((l), P) == 0) \
(l)->llcl_retry = 0; \
LLC_SETFLAG((l), P, 1); \
}
#define LLC_STOP_P_TIMER(l) { \
LLC_STOPTIMER((l), P); \
LLC_SETFLAG((l), P, 0); \
}
#define LLC_STOP_ALL_TIMERS(l) { \
LLC_STOPTIMER((l), ACK); \
LLC_STOPTIMER((l), REJ); \
LLC_STOPTIMER((l), BUSY); \
LLC_STOPTIMER((l), P); \
}
#define LLC_INC(i) (i) = ((i)+1) % LLC_MAX_SEQUENCE
#define LLC_NR_VALID(l, nr) ((l)->llcl_vs < (l)->llcl_nr_received ? \
(((nr) >= (l)->llcl_nr_received) || \
((nr) <= (l)->llcl_vs) ? 1 : 0) : \
(((nr) <= (l)->llcl_vs) && \
((nr) >= (l)->llcl_nr_received) ? 1 : 0))
#define LLC_UPDATE_P_FLAG(l, cr, pf) { \
if ((cr) == LLC_RSP && (pf) == 1) { \
LLC_SETFLAG((l), P, 0); \
LLC_STOPTIMER((l), P); \
} \
}
#define LLC_UPDATE_NR_RECEIVED(l, nr) { \
while ((l)->llcl_nr_received != (nr)) { \
struct mbuf *_m; \
register short seq; \
if (_m = (l)->llcl_output_buffers[seq = llc_seq2slot((l), (l)->llcl_nr_received)]) \
m_freem(_m); \
(l)->llcl_output_buffers[seq] = NULL; \
LLC_INC((l)->llcl_nr_received); \
(l)->llcl_slotsfree++; \
} \
(l)->llcl_retry = 0; \
if ((l)->llcl_slotsfree < (l)->llcl_window) { \
LLC_START_ACK_TIMER(l); \
} else LLC_STOP_ACK_TIMER(l); \
LLC_STARTTIMER((l), DACTION); \
}
#define LLC_SET_REMOTE_BUSY(l,a) { \
if (LLC_GETFLAG((l), REMOTE_BUSY) == 0) { \
LLC_SETFLAG((l), REMOTE_BUSY, 1); \
LLC_STARTTIMER((l), BUSY); \
(a) = LLC_REMOTE_BUSY; \
} else { \
(a) = 0; \
} \
}
#define LLC_CLEAR_REMOTE_BUSY(l,a) { \
if (LLC_GETFLAG((l), REMOTE_BUSY) == 1) { \
LLC_SETFLAG((l), REMOTE_BUSY, 1); \
LLC_STOPTIMER((l), BUSY); \
if (LLC_STATEEQ((l), NORMAL) || \
LLC_STATEEQ((l), REJECT) || \
LLC_STATEEQ((l), BUSY)) \
llc_resend((l), LLC_CMD, 0); \
(a) = LLC_REMOTE_NOT_BUSY; \
} else { \
(a) = 0; \
} \
}
#define LLC_DACKCMD 0x1
#define LLC_DACKCMDPOLL 0x2
#define LLC_DACKRSP 0x3
#define LLC_DACKRSPFINAL 0x4
#define LLC_SENDACKNOWLEDGE(l, cmd, pf) { \
if ((cmd) == LLC_CMD) { \
LLC_SETFLAG((l), DACTION, ((pf) == 0 ? LLC_DACKCMD : LLC_DACKCMDPOLL)); \
} else { \
LLC_SETFLAG((l), DACTION, ((pf) == 0 ? LLC_DACKRSP : LLC_DACKRSPFINAL)); \
} \
}
#define LLC_FRMR_W (1<<0)
#define LLC_FRMR_X (1<<1)
#define LLC_FRMR_Y (1<<2)
#define LLC_FRMR_Z (1<<3)
#define LLC_FRMR_V (1<<4)
#define LLC_SETFRMR(l, f, cr, c) { \
if ((f)->llc_control & 0x3) { \
(l)->llcl_frmr_pdu0 = (f)->llc_control; \
(l)->llcl_frmr_pdu1 = 0; \
} else { \
(l)->llcl_frmr_pdu0 = (f)->llc_control; \
(l)->llcl_frmr_pdu1 = (f)->llc_control_ext; \
} \
LLCCSBITS((l)->llcl_frmr_control, f_vs, (l)->llcl_vs); \
LLCCSBITS((l)->llcl_frmr_control_ext, f_cr, (cr)); \
LLCSBITS((l)->llcl_frmr_control_ext, f_vr, (l)->llcl_vr); \
LLCCSBITS((l)->llcl_frmr_cause, f_wxyzv, (c)); \
}
/*
* LLC tracing levels:
* LLCTR_INTERESTING interesting event, we might care to know about
* it, but then again, we might not ...
* LLCTR_SHOULDKNOW we probably should know about this event
* LLCTR_URGENT something has gone utterly wrong ...
*/
#define LLCTR_INTERESTING 1
#define LLCTR_SHOULDKNOW 2
#define LLCTR_URGENT 3
#ifdef LLCDEBUG
#define LLC_TRACE(lp, l, msg) llc_trace((lp), (l), (msg))
#else /* LLCDEBUG */
#define LLC_TRACE(lp, l, msg) /* NOOP */
#endif /* LLCDEBUG */
#define LLC_N2_VALUE 15 /* up to 15 retries */
#define LLC_ACK_TIMER 10 /* 5 secs */
#define LLC_P_TIMER 4 /* 2 secs */
#define LLC_BUSY_TIMER 12 /* 6 secs */
#define LLC_REJ_TIMER 12 /* 6 secs */
#define LLC_AGE_TIMER 40 /* 20 secs */
#define LLC_DACTION_TIMER 2 /* 1 secs */
#if defined (KERNEL) && defined(LLC)
extern int llc_n2;
extern int llc_ACK_timer;
extern int llc_P_timer;
extern int llc_REJ_timer;
extern int llc_BUSY_timer;
extern int llc_AGE_timer;
extern int llc_DACTION_timer;
extern int af_link_rts_init_done;
#define USES_AF_LINK_RTS { \
if (!af_link_rts_init_done) { \
rn_inithead((void **)&rt_tables[AF_LINK], 32); \
af_link_rts_init_done++; \
} \
}
extern struct ifqueue llcintrq;
extern struct llccb_q llccb_q;
/*
* Function prototypes
*/
int sdl_sethdrif __P((struct ifnet *, u_char *, u_char, u_char *, u_char, u_char,
struct sdl_hdr *));
struct npaidbentry *llc_setsapinfo __P((struct ifnet *, u_char, u_char,
struct dllconfig *));
struct npaidbentry *llc_getsapinfo __P((u_char, struct ifnet *));
struct rtentry *npaidb_enrich __P((short, caddr_t, struct sockaddr_dl *));
int npaidb_destroy __P((struct rtentry *));
short llc_seq2slot __P((struct llc_linkcb *, short));
void sdl_swapaddr __P((struct sockaddr_dl *, struct sockaddr_dl *));
int llc_state_NORMAL __P((struct llc_linkcb *, struct llc *, int, int, int));
int llc_state_BUSY __P((struct llc_linkcb *, struct llc *, int, int, int));
int llc_state_REJECT __P((struct llc_linkcb *, struct llc *, int, int, int));
int llc_statehandler __P((struct llc_linkcb *, struct llc *, int, int, int));
void llc_init __P((void));
struct llc_linkcb *llc_newlink __P((struct sockaddr_dl *, struct ifnet *,
struct rtentry *, caddr_t, struct rtentry *));
void llc_dellink __P((struct llc_linkcb *));
int llc_anytimersup __P((struct llc_linkcb *));
int llc_decode __P((struct llc *, struct llc_linkcb *));
void llc_timer __P((void));
void llcintr __P((void));
int llc_input __P((struct llc_linkcb *, struct mbuf *, u_char));
caddr_t llc_ctlinput __P((int, struct sockaddr *, caddr_t));
int llc_output __P((struct llc_linkcb *, struct mbuf *));
void llc_start __P((struct llc_linkcb *));
int llc_send __P((struct llc_linkcb *, int, int, int));
int llc_resend __P((struct llc_linkcb *, int, int));
int llc_rawsend __P((struct llc_linkcb *, struct mbuf *, struct llc *, int, int,
int, int));
int cons_rtrequest __P((int, struct rtentry *, struct sockaddr *));
int x25_llcglue __P((int, struct sockaddr *));
#endif
#endif

View File

@ -1,213 +0,0 @@
/*
* Copyright (c) University of British Columbia, 1984
* Copyright (c) 1990, 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* the Laboratory for Computation Vision and the Computer Science Department
* of the University of British Columbia.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)pk.h 8.1 (Berkeley) 6/10/93
* $Id: pk.h,v 1.5 1995/11/21 12:54:10 bde Exp $
*/
#ifndef _NETCCITT_PK_H_
#define _NETCITT_PK_H_
/*
*
* X.25 Packet Level Definitions:
*
*/
/* Packet type identifier field definitions. */
#define X25_CALL 11
#define X25_CALL_ACCEPTED 15
#define X25_CLEAR 19
#define X25_CLEAR_CONFIRM 23
#define X25_DATA 0
#define X25_INTERRUPT 35
#define X25_INTERRUPT_CONFIRM 39
#define X25_RR 1
#define X25_RNR 5
#define X25_REJECT 9
#define X25_RESET 27
#define X25_RESET_CONFIRM 31
#define X25_DIAGNOSTIC 241
#define X25_RESTART 251
#define X25_RESTART_CONFIRM 255
/* Restart cause field definitions. */
#define X25_RESTART_DTE_ORIGINATED 0
#define X25_RESTART_LOCAL_PROCEDURE_ERROR 1
#define X25_RESTART_NETWORK_CONGESTION 3
#define X25_RESTART_NETWORK_OPERATIONAL 7
#define X25_RESTART_DTE_ORIGINATED2 128
/* Miscellaneous definitions. */
#define DATA_PACKET_DESIGNATOR 0x01
#define RR_OR_RNR_PACKET_DESIGNATOR 0x02
#define RR_PACKET_DESIGNATOR 0x04
#define DEFAULT_WINDOW_SIZE 2
#define MODULUS 8
#define ADDRLN 1
#define MAXADDRLN 15
#define FACILITIESLN 1
#define MAXFACILITIESLN 10
#define MAXUSERDATA 16
#define MAXCALLINFOLN 1+15+1+10+16
#define PACKET_OK 0
#define IGNORE_PACKET 1
#define ERROR_PACKET 2
typedef char bool;
#define FALSE 0
#define TRUE 1
/*
* X.25 Packet format definitions
* This will eventually have to be rewritten without reference
* to bit fields, to be ansi C compliant and alignment safe.
*/
typedef u_char octet;
struct x25_calladdr {
octet addrlens;
octet address_field[MAXADDRLN];
};
struct x25_packet {
octet bits;
octet logical_channel_number;
octet packet_type;
octet packet_data;
};
#define packet_cause packet_data
struct data_packet {
octet bits;
};
#define FACILITIES_REVERSE_CHARGE 0x1
#define FACILITIES_THROUGHPUT 0x2
#define FACILITIES_PACKETSIZE 0x42
#define FACILITIES_WINDOWSIZE 0x43
#define PKHEADERLN 3
#define DP(xp) (((struct data_packet *)&(xp) -> packet_type) -> bits)
#define PS(xp) X25GBITS(DP(xp), p_s)
#define PR(xp) X25GBITS(DP(xp), p_r)
#define MBIT(xp) X25GBITS(DP(xp), m_bit)
#define SPR(xp, v) X25SBITS(DP(xp), p_r, (v))
#define SPS(xp, v) X25SBITS(DP(xp), p_s, (v))
#define SMBIT(xp, v) X25SBITS(DP(xp), m_bit, (v))
#define LCN(xp) (xp -> logical_channel_number + \
(X25GBITS(xp -> bits, lc_group_number) ? (X25GBITS(xp -> bits, lc_group_number) << 8) : 0))
#define SET_LCN(xp, lcn) ((xp -> logical_channel_number = lcn), \
(X25SBITS(xp -> bits, lc_group_number, lcn > 255 ? lcn >> 8 : 0)))
struct mbuf *pk_template __P((int lcn, int type));
/* Define X.25 packet level states. */
/* Call setup and clearing substates. */
#define LISTEN 0
#define READY 1
#define RECEIVED_CALL 2
#define SENT_CALL 3
#define DATA_TRANSFER 4
#define RECEIVED_CLEAR 5
#define SENT_CLEAR 6
/* DTE states. */
#define DTE_WAITING 7
#define DTE_RECEIVED_RESTART 8
#define DTE_SENT_RESTART 9
#define DTE_READY 0
/* Cleaning out ... */
#define LCN_ZOMBIE 10
#define MAXSTATES 11
/*
* The following definitions are used in a switch statement after
* determining the packet type. These values are returned by the
* pk_decode procedure.
*/
#define CALL 0 * MAXSTATES
#define CALL_ACCEPTED 1 * MAXSTATES
#define CLEAR 2 * MAXSTATES
#define CLEAR_CONF 3 * MAXSTATES
#define DATA 4 * MAXSTATES
#define INTERRUPT 5 * MAXSTATES
#define INTERRUPT_CONF 6 * MAXSTATES
#define RR 7 * MAXSTATES
#define RNR 8 * MAXSTATES
#define RESET 9 * MAXSTATES
#define RESET_CONF 10 * MAXSTATES
#define RESTART 11 * MAXSTATES
#define RESTART_CONF 12 * MAXSTATES
#define REJECT 13 * MAXSTATES
#define DIAG_TYPE 14 * MAXSTATES
#define INVALID_PACKET 15 * MAXSTATES
#define DELETE_PACKET INVALID_PACKET
/*
* The following definitions are used by the restart procedures
* for noting wether the PLE is supposed to behave as DTE or DCE
* (essentially necessary for operation over LLC2)
*/
#define DTE_DXERESOLVING 0x0001
#define DTE_PLAYDTE 0x0002
#define DTE_PLAYDCE 0x0004
#define DTE_CONNECTPENDING 0x0010
#define DTE_PRETENDDTE 0x0020
#define MAXRESTARTCOLLISIONS 10
#endif

View File

@ -1,146 +0,0 @@
/*
* Copyright (c) University of British Columbia, 1984
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* the Laboratory for Computation Vision and the Computer Science Department
* of the University of British Columbia.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)pk_acct.c 8.1 (Berkeley) 6/10/93
* $Id: pk_acct.c,v 1.2 1994/08/02 07:47:29 davidg Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/namei.h>
#include <sys/proc.h>
#include <sys/vnode.h>
#include <sys/kernel.h>
#include <sys/file.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <net/if.h>
#include <netccitt/x25.h>
#include <netccitt/pk.h>
#include <netccitt/pk_var.h>
#include <netccitt/x25acct.h>
struct vnode *pkacctp;
/*
* Turn on packet accounting
*/
pk_accton (path)
char *path;
{
register struct vnode *vp = NULL;
struct nameidata nd;
struct vnode *oacctp = pkacctp;
struct proc *p = curproc;
int error;
if (path == 0)
goto close;
NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, path, p);
if (error = vn_open (&nd, FWRITE, 0644))
return (error);
vp = nd.ni_vp;
VOP_UNLOCK(vp);
if (vp -> v_type != VREG) {
vrele (vp);
return (EACCES);
}
pkacctp = vp;
if (oacctp) {
close:
error = vn_close (oacctp, FWRITE, p -> p_ucred, p);
}
return (error);
}
/*
* Write a record on the accounting file.
*/
pk_acct (lcp)
register struct pklcd *lcp;
{
register struct vnode *vp;
register struct sockaddr_x25 *sa;
register char *src, *dst;
register int len;
register long etime;
static struct x25acct acbuf;
if ((vp = pkacctp) == 0)
return;
bzero ((caddr_t)&acbuf, sizeof (acbuf));
if (lcp -> lcd_ceaddr != 0)
sa = lcp -> lcd_ceaddr;
else if (lcp -> lcd_craddr != 0) {
sa = lcp -> lcd_craddr;
acbuf.x25acct_callin = 1;
} else
return;
if (sa -> x25_opts.op_flags & X25_REVERSE_CHARGE)
acbuf.x25acct_revcharge = 1;
acbuf.x25acct_stime = lcp -> lcd_stime;
acbuf.x25acct_etime = time.tv_sec - acbuf.x25acct_stime;
acbuf.x25acct_uid = curproc -> p_cred -> p_ruid;
acbuf.x25acct_psize = sa -> x25_opts.op_psize;
acbuf.x25acct_net = sa -> x25_net;
/*
* Convert address to bcd
*/
src = sa -> x25_addr;
dst = acbuf.x25acct_addr;
for (len = 0; *src; len++)
if (len & 01)
*dst++ |= *src++ & 0xf;
else
*dst = *src++ << 4;
acbuf.x25acct_addrlen = len;
bcopy (sa -> x25_udata, acbuf.x25acct_udata,
sizeof (acbuf.x25acct_udata));
acbuf.x25acct_txcnt = lcp -> lcd_txcnt;
acbuf.x25acct_rxcnt = lcp -> lcd_rxcnt;
(void) vn_rdwr(UIO_WRITE, vp, (caddr_t)&acbuf, sizeof (acbuf),
(off_t)0, UIO_SYSSPACE, IO_UNIT|IO_APPEND,
curproc -> p_ucred, (int *)0,
(struct proc *)0);
}

View File

@ -1,141 +0,0 @@
/*
* Copyright (c) University of British Columbia, 1984
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* the Laboratory for Computation Vision and the Computer Science Department
* of the University of British Columbia.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)pk_debug.c 8.1 (Berkeley) 6/10/93
* $Id$
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/protosw.h>
#include <sys/socketvar.h>
#include <sys/errno.h>
#include <net/if.h>
#include <netccitt/x25.h>
#include <netccitt/pk.h>
#include <netccitt/pk_var.h>
char *pk_state[] = {
"Listen", "Ready", "Received-Call",
"Sent-Call", "Data-Transfer","Received-Clear",
"Sent-Clear",
};
char *pk_name[] = {
"Call", "Call-Conf", "Clear",
"Clear-Conf", "Data", "Intr", "Intr-Conf",
"Rr", "Rnr", "Reset", "Reset-Conf",
"Restart", "Restart-Conf", "Reject", "Diagnostic",
"Invalid"
};
pk_trace (xcp, m, dir)
struct x25config *xcp;
register struct mbuf *m;
char *dir;
{
register char *s;
struct x25_packet *xp = mtod(m, struct x25_packet *);
register int i, len = 0, cnt = 0;
if (xcp -> xc_ptrace == 0)
return;
i = pk_decode (xp) / MAXSTATES;
for (; m; m = m -> m_next) {
len = len + m -> m_len;
++cnt;
}
printf ("LCN=%d %s: %s #=%d, len=%d ",
LCN(xp), dir, pk_name[i], cnt, len);
for (s = (char *) xp, i = 0; i < 5; ++i, ++s)
printf ("%x ", (int) * s & 0xff);
printf ("\n");
}
mbuf_cache(c, m)
register struct mbuf_cache *c;
struct mbuf *m;
{
register struct mbuf **mp;
if (c->mbc_size != c->mbc_oldsize) {
unsigned zero_size, copy_size;
unsigned new_size = c->mbc_size * sizeof(m);
caddr_t cache = (caddr_t)c->mbc_cache;
if (new_size) {
c->mbc_cache = (struct mbuf **)
malloc(new_size, M_MBUF, M_NOWAIT);
if (c->mbc_cache == 0) {
c->mbc_cache = (struct mbuf **)cache;
return;
}
c->mbc_num %= c->mbc_size;
} else
c->mbc_cache = 0;
if (c->mbc_size < c->mbc_oldsize) {
register struct mbuf **mplim;
mp = c->mbc_size + (struct mbuf **)cache;
mplim = c->mbc_oldsize + (struct mbuf **)cache;
while (mp < mplim)
m_freem(*mp++);
zero_size = 0;
} else
zero_size = (c->mbc_size - c->mbc_oldsize) * sizeof(m);
copy_size = new_size - zero_size;
c->mbc_oldsize = c->mbc_size;
if (copy_size)
bcopy(cache, (caddr_t)c->mbc_cache, copy_size);
if (cache)
free(cache, M_MBUF);
if (zero_size)
bzero(copy_size + (caddr_t)c->mbc_cache, zero_size);
}
if (c->mbc_size == 0)
return;
mp = c->mbc_cache + c->mbc_num;
c->mbc_num = (1 + c->mbc_num) % c->mbc_size;
if (*mp)
m_freem(*mp);
if (*mp = m_copym(m, 0, M_COPYALL, M_DONTWAIT))
(*mp)->m_flags |= m->m_flags & 0x08;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,371 +0,0 @@
/*
* Copyright (C) Dirk Husemann, Computer Science Department IV,
* University of Erlangen-Nuremberg, Germany, 1990, 1991, 1992
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Dirk Husemann and the Computer Science Department (IV) of
* the University of Erlangen-Nuremberg, Germany.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)pk_llcsubr.c 8.1 (Berkeley) 6/10/93
* $Id: pk_llcsubr.c,v 1.3 1994/12/13 22:32:16 wollman Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/domain.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/protosw.h>
#include <sys/errno.h>
#include <sys/time.h>
#include <sys/kernel.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <net/if_llc.h>
#include <net/if_types.h>
#include <net/route.h>
#include <netccitt/dll.h>
#include <netccitt/x25.h>
#include <netccitt/pk.h>
#include <netccitt/pk_var.h>
#include <netccitt/llc_var.h>
/*
* Routing support for X.25
*
* We distinguish between two cases:
* RTF_HOST:
* rt_key(rt) X.25 address of host
* rt_gateway SNPA (MAC+DLSAP) address of host
* rt_llinfo pkcb for rt_key(rt)
*
* RTF_GATEWAY
* rt_key(rt) X.25 address of host or suitably masked network
* rt_gateway X.25 address of next X.25 gateway (switch)
* rt_llinfo rtentry for rt_gateway address
* ought to be of type RTF_HOST
*
*
* Mapping of X.121 to pkcbs:
*
* HDLC uses the DTE-DCE model of X.25, therefore we need a many-to-one
* relationship, i.e.:
*
* {X.121_a, X.121_b, X.121_c, ..., X.121_i} -> pkcb_0
*
* LLC2 utilizes the DTE-DTE model of X.25, resulting effectively in a
* one-to-one relationship, i.e.:
*
* {X.121_j} -> pkcb_1a
* {X.121_k} -> pkcb_1b
* ...
* {X.121_q} -> pkcb_1q
*
* It might make sense to allow a many-to-one relation for LLC2 also,
*
* {X.121_r, X.121_s, X.121_t, X.121_u} -> pkcb_2a
*
* This would make addresses X.121_[r-u] essentially aliases of one
* address ({X.121_[r-u]} would constitute a representative set).
*
* Each one-to-one relation must obviously be entered individually with
* a route add command, whereas a many-to-one relationship can be
* either entered individually or generated by using a netmask.
*
* To facilitate dealings the many-to-one case for LLC2 can only be
* established via a netmask.
*
*/
#define XTRACTPKP(rt) ((rt)->rt_flags & RTF_GATEWAY ? \
((rt)->rt_llinfo ? \
(struct pkcb *) ((struct rtentry *)((rt)->rt_llinfo))->rt_llinfo : \
(struct pkcb *) NULL) : \
(struct pkcb *)((rt)->rt_llinfo))
#define equal(a1, a2) (bcmp((caddr_t)(a1), \
(caddr_t)(a2), \
(a1)->sa_len) == 0)
#define XIFA(rt) ((struct x25_ifaddr *)((rt)->rt_ifa))
#define SA(s) ((struct sockaddr *)s)
int
cons_rtrequest(int cmd, struct rtentry *rt, struct sockaddr *dst)
{
register struct pkcb *pkp;
register int i;
register char one_to_one;
struct pkcb *pk_newlink();
struct rtentry *npaidb_enter();
pkp = XTRACTPKP(rt);
switch(cmd) {
case RTM_RESOLVE:
case RTM_ADD:
if (pkp)
return(EEXIST);
if (rt->rt_flags & RTF_GATEWAY) {
if (rt->rt_llinfo)
RTFREE((struct rtentry *)rt->rt_llinfo);
rt->rt_llinfo = (caddr_t) rtalloc1(rt->rt_gateway, 1,
0UL);
return(0);
}
/*
* Assumptions: (1) ifnet structure is filled in
* (2) at least the pkcb created via
* x25config (ifconfig?) has been
* set up already.
* (3) HDLC interfaces have an if_type of
* IFT_X25{,DDN}, LLC2 interfaces
* anything else (any better way to
* do this?)
*
*/
if (!rt->rt_ifa)
return (ENETDOWN);
/*
* We differentiate between dealing with a many-to-one
* (HDLC: DTE-DCE) and a one-to-one (LLC2: DTE-DTE)
* relationship (by looking at the if type).
*
* Only in case of the many-to-one relationship (HDLC)
* we set the ia->ia_pkcb pointer to the pkcb allocated
* via pk_newlink() as we will use just that one pkcb for
* future route additions (the rtentry->rt_llinfo pointer
* points to the pkcb allocated for that route).
*
* In case of the one-to-one relationship (LLC2) we
* create a new pkcb (via pk_newlink()) for each new rtentry.
*
* NOTE: Only in case of HDLC does ia->ia_pkcb point
* to a pkcb, in the LLC2 case it doesn't (as we don't
* need it here)!
*/
one_to_one = ISISO8802(rt->rt_ifp);
if (!(pkp = XIFA(rt)->ia_pkcb) && !one_to_one)
XIFA(rt)->ia_pkcb = pkp =
pk_newlink(XIFA(rt), (caddr_t) 0);
else if (one_to_one &&
!equal(rt->rt_gateway, rt->rt_ifa->ifa_addr)) {
pkp = pk_newlink(XIFA(rt), (caddr_t) 0);
/*
* We also need another route entry for mapping
* MAC+LSAP->X.25 address
*/
pkp->pk_llrt = npaidb_enter(rt->rt_gateway, rt_key(rt), rt, 0);
}
if (pkp) {
if (!pkp->pk_rt)
pkp->pk_rt = rt;
pkp->pk_refcount++;
}
rt->rt_llinfo = (caddr_t) pkp;
return(0);
case RTM_DELETE:
{
/*
* The pkp might be empty if we are dealing
* with an interface route entry for LLC2, in this
* case we don't need to do anything ...
*/
if (pkp) {
if ( rt->rt_flags & RTF_GATEWAY ) {
if (rt->rt_llinfo)
RTFREE((struct rtentry *)rt->rt_llinfo);
return(0);
}
if (pkp->pk_llrt)
npaidb_destroy(pkp->pk_llrt);
pk_dellink (pkp);
return(0);
}
}
}
}
/*
* Network Protocol Addressing Information DataBase (npaidb)
*
* To speed up locating the entity dealing with an LLC packet use is made
* of a routing tree. This npaidb routing tree is handled
* by the normal rn_*() routines just like (almost) any other routing tree.
*
* The mapping being done by the npaidb_*() routines is as follows:
*
* Key: MAC,LSAP (enhancing struct sockaddr_dl)
* Gateway: sockaddr_x25 (i.e. X.25 address - X.121 or NSAP)
* Llinfo: npaidbentry {
* struct llc_linkcb *npaidb_linkp;
* struct rtentry *npaidb_rt;
* }
*
* Using the npaidbentry provided by llinfo we can then access
*
* o the pkcb by using (struct pkcb *) (npaidb_rt->rt_llinfo)
* o the linkcb via npaidb_linkp
*
* The following functions are provided
*
* o npaidb_enter(struct sockaddr_dl *sdl, struct sockaddr_x25 *sx25,
* struct struct llc_linkcb *link, struct rtentry *rt)
*
* o npaidb_enrich(short type, caddr_t info)
*
*/
struct sockaddr_dl npdl_netmask = {
sizeof(struct sockaddr_dl), /* _len */
0, /* _family */
0, /* _index */
0, /* _type */
-1, /* _nlen */
-1, /* _alen */
-1, /* _slen */
{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* _data */
};
struct sockaddr npdl_dummy;
int npdl_datasize = sizeof(struct sockaddr_dl)-
((int)((caddr_t)&((struct sockaddr_dl *)0)->sdl_data[0]));
struct rtentry *
npaidb_enter(struct sockaddr_dl *key, struct sockaddr *value,
struct rtentry *rt, struct llc_linkcb *link)
{
struct rtentry *nprt; register int i;
USES_AF_LINK_RTS;
if ((nprt = rtalloc1(SA(key), 0, 0UL)) == 0) {
register u_int size = sizeof(struct npaidbentry);
register u_char saploc = LLSAPLOC(key, rt->rt_ifp);
/*
* set up netmask: LLC2 packets have the lowest bit set in
* response packets (e.g. 0x7e for command packets, 0x7f for
* response packets), to facilitate the lookup we use a netmask
* of 11111110 for the SAP position. The remaining positions
* are zeroed out.
*/
npdl_netmask.sdl_data[saploc] = NPDL_SAPNETMASK;
bzero((caddr_t)&npdl_netmask.sdl_data[saploc+1],
npdl_datasize-saploc-1);
if (value == 0)
value = &npdl_dummy;
/* now enter it */
rtrequest(RTM_ADD, SA(key), SA(value),
SA(&npdl_netmask), 0, &nprt);
/* and reset npdl_netmask */
for (i = saploc; i < npdl_datasize; i++)
npdl_netmask.sdl_data[i] = -1;
nprt->rt_llinfo = malloc(size , M_PCB, M_WAITOK);
if (nprt->rt_llinfo) {
bzero (nprt->rt_llinfo, size);
((struct npaidbentry *) (nprt->rt_llinfo))->np_rt = rt;
}
} else nprt->rt_refcnt--;
return nprt;
}
struct rtentry *
npaidb_enrich(short type, caddr_t info, struct sockaddr_dl *sdl)
{
struct rtentry *rt;
USES_AF_LINK_RTS;
if (rt = rtalloc1((struct sockaddr *)sdl, 0, 0UL)) {
rt->rt_refcnt--;
switch (type) {
case NPAIDB_LINK:
((struct npaidbentry *)(rt->rt_llinfo))->np_link =
(struct llc_linkcb *) info;
break;
}
return rt;
}
return ((struct rtentry *) 0);
}
npaidb_destroy(struct rtentry *rt)
{
USES_AF_LINK_RTS;
if (rt->rt_llinfo)
free((caddr_t) rt->rt_llinfo, M_PCB);
return(rtrequest(RTM_DELETE, rt_key(rt), rt->rt_gateway, rt_mask(rt),
0, 0));
}
#ifdef LLC
/*
* Glue between X.25 and LLC2
*/
int
x25_llcglue(int prc, struct sockaddr *addr)
{
register struct sockaddr_x25 *sx25 = (struct sockaddr_x25 *)addr;
register struct x25_ifaddr *x25ifa;
struct dll_ctlinfo ctlinfo;
if((x25ifa = (struct x25_ifaddr *)ifa_ifwithaddr(addr)) == 0)
return 0;
ctlinfo.dlcti_cfg =
(struct dllconfig *)(((struct sockaddr_x25 *)(&x25ifa->ia_xc))+1);
ctlinfo.dlcti_lsap = LLC_X25_LSAP;
return ((int)llc_ctlinput(prc, addr, (caddr_t)&ctlinfo));
}
#endif /* LLC */

View File

@ -1,217 +0,0 @@
/*
* Copyright (c) University of British Columbia, 1984
* Copyright (C) Computer Science Department IV,
* University of Erlangen-Nuremberg, Germany, 1992
* Copyright (c) 1991, 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by the
* Laboratory for Computation Vision and the Computer Science Department
* of the the University of British Columbia and the Computer Science
* Department (IV) of the University of Erlangen-Nuremberg, Germany.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)pk_output.c 8.1 (Berkeley) 6/10/93
* $Id: pk_output.c,v 1.2 1994/08/02 07:47:38 davidg Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/protosw.h>
#include <sys/errno.h>
#include <net/if.h>
#include <netccitt/x25.h>
#include <netccitt/pk.h>
#include <netccitt/pk_var.h>
struct mbuf_cache pk_output_cache = {0 }, pk_input_cache;
struct mbuf *nextpk ();
pk_output (lcp)
register struct pklcd *lcp;
{
register struct x25_packet *xp;
register struct mbuf *m;
register struct pkcb *pkp = lcp -> lcd_pkp;
if (lcp == 0 || pkp == 0) {
printf ("pk_output: zero arg\n");
return;
}
while ((m = nextpk (lcp)) != NULL) {
xp = mtod (m, struct x25_packet *);
switch (pk_decode (xp) + lcp -> lcd_state) {
/*
* All the work is already done - just set the state and
* pass to peer.
*/
case CALL + READY:
lcp -> lcd_state = SENT_CALL;
lcp -> lcd_timer = pk_t21;
break;
/*
* Just set the state to allow packet to flow and send the
* confirmation.
*/
case CALL_ACCEPTED + RECEIVED_CALL:
lcp -> lcd_state = DATA_TRANSFER;
break;
/*
* Just set the state. Keep the LCD around till the clear
* confirmation is returned.
*/
case CLEAR + RECEIVED_CALL:
case CLEAR + SENT_CALL:
case CLEAR + DATA_TRANSFER:
lcp -> lcd_state = SENT_CLEAR;
lcp -> lcd_retry = 0;
/* fall through */
case CLEAR + SENT_CLEAR:
lcp -> lcd_timer = pk_t23;
lcp -> lcd_retry++;
break;
case CLEAR_CONF + RECEIVED_CLEAR:
case CLEAR_CONF + SENT_CLEAR:
case CLEAR_CONF + READY:
lcp -> lcd_state = READY;
break;
case DATA + DATA_TRANSFER:
SPS(xp, lcp -> lcd_ssn);
lcp -> lcd_input_window =
(lcp -> lcd_rsn + 1) % MODULUS;
SPR(xp, lcp -> lcd_input_window);
lcp -> lcd_last_transmitted_pr = lcp -> lcd_input_window;
lcp -> lcd_ssn = (lcp -> lcd_ssn + 1) % MODULUS;
if (lcp -> lcd_ssn == ((lcp -> lcd_output_window + lcp -> lcd_windowsize) % MODULUS))
lcp -> lcd_window_condition = TRUE;
break;
case INTERRUPT + DATA_TRANSFER:
#ifdef ancient_history
xp -> packet_data = 0;
#endif
lcp -> lcd_intrconf_pending = TRUE;
break;
case INTERRUPT_CONF + DATA_TRANSFER:
break;
case RR + DATA_TRANSFER:
case RNR + DATA_TRANSFER:
lcp -> lcd_input_window =
(lcp -> lcd_rsn + 1) % MODULUS;
SPR(xp, lcp -> lcd_input_window);
lcp -> lcd_last_transmitted_pr = lcp -> lcd_input_window;
break;
case RESET + DATA_TRANSFER:
lcp -> lcd_reset_condition = TRUE;
break;
case RESET_CONF + DATA_TRANSFER:
lcp -> lcd_reset_condition = FALSE;
break;
/*
* A restart should be only generated internally. Therefore
* all logic for restart is in the pk_restart routine.
*/
case RESTART + READY:
lcp -> lcd_timer = pk_t20;
break;
/*
* Restarts are all handled internally. Therefore all the
* logic for the incoming restart packet is handled in the
* pk_input routine.
*/
case RESTART_CONF + READY:
break;
default:
m_freem (m);
return;
}
/* Trace the packet. */
pk_trace (pkp -> pk_xcp, m, "P-Out");
/* Pass the packet on down to the link layer */
if (pk_input_cache.mbc_size || pk_input_cache.mbc_oldsize) {
m->m_flags |= 0x08;
mbuf_cache(&pk_input_cache, m);
}
(*pkp -> pk_lloutput) (pkp -> pk_llnext, m, pkp -> pk_rt);
}
}
/*
* This procedure returns the next packet to send or null. A
* packet is composed of one or more mbufs.
*/
struct mbuf *
nextpk (lcp)
struct pklcd *lcp;
{
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 = lcp -> lcd_template;
lcp -> lcd_template = NULL;
} else {
if (lcp -> lcd_rnr_condition || lcp -> lcd_window_condition ||
lcp -> lcd_reset_condition)
return (NULL);
if ((m = sb -> sb_mb) == 0)
return (NULL);
sb -> sb_mb = m -> m_nextpkt;
m->m_act = 0;
for (n = m; n; n = n -> m_next)
sbfree (sb, n);
}
return (m);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,127 +0,0 @@
/*
* Copyright (c) Computing Centre, University of British Columbia, 1984
* Copyright (C) Computer Science Department IV,
* University of Erlangen-Nuremberg, Germany, 1990, 1992
* Copyright (c) 1990, 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by the
* Laboratory for Computation Vision and the Computer Science Department
* of the the University of British Columbia and the Computer Science
* Department (IV) of the University of Erlangen-Nuremberg, Germany.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)pk_timer.c 8.1 (Berkeley) 6/10/93
* $Id: pk_timer.c,v 1.2 1994/08/02 07:47:44 davidg Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/protosw.h>
#include <sys/socketvar.h>
#include <sys/errno.h>
#include <net/if.h>
#include <netccitt/x25.h>
#include <netccitt/pk.h>
#include <netccitt/pk_var.h>
/*
* Various timer values. They can be adjusted
* by patching the binary with adb if necessary.
*/
int pk_t20 = 18 * PR_SLOWHZ; /* restart timer */
int pk_t21 = 20 * PR_SLOWHZ; /* call timer */
/* XXX pk_t22 is never used */
int pk_t22 = 18 * PR_SLOWHZ; /* reset timer */
int pk_t23 = 18 * PR_SLOWHZ; /* clear timer */
pk_timer ()
{
register struct pkcb *pkp;
register struct pklcd *lcp, **pp;
register int lcns_jammed, cant_restart;
FOR_ALL_PKCBS(pkp) {
switch (pkp -> pk_state) {
case DTE_SENT_RESTART:
lcp = pkp -> pk_chan[0];
/*
* If restart failures are common, a link level
* reset should be initiated here.
*/
if (lcp -> lcd_timer && --lcp -> lcd_timer == 0) {
pk_message (0, pkp -> pk_xcp,
"packet level restart failed");
pkp -> pk_state = DTE_WAITING;
}
break;
case DTE_READY:
lcns_jammed = cant_restart = 0;
for (pp = &pkp -> pk_chan[1]; pp <= &pkp -> pk_chan[pkp -> pk_maxlcn]; pp++) {
if ((lcp = *pp) == 0)
continue;
switch (lcp -> lcd_state) {
case SENT_CALL:
if (--lcp -> lcd_timer == 0) {
if (lcp -> lcd_so)
lcp -> lcd_so -> so_error = ETIMEDOUT;
pk_clear (lcp, 49, 1);
}
break;
case SENT_CLEAR:
if (lcp -> lcd_retry >= 3)
lcns_jammed++;
else
if (--lcp -> lcd_timer == 0)
pk_clear (lcp, 50, 1);
break;
case DATA_TRANSFER: /* lcn active */
cant_restart++;
break;
case LCN_ZOMBIE: /* zombie state */
pk_freelcd (lcp);
break;
}
}
if (lcns_jammed > pkp -> pk_maxlcn / 2 && cant_restart == 0) {
pk_message (0, pkp -> pk_xcp, "%d lcns jammed: attempting restart", lcns_jammed);
pk_restart (pkp, 0);
}
}
}
}

View File

@ -1,605 +0,0 @@
/*
* Copyright (c) University of British Columbia, 1984
* Copyright (C) Computer Science Department IV,
* University of Erlangen-Nuremberg, Germany, 1992
* Copyright (c) 1991, 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by the
* Laboratory for Computation Vision and the Computer Science Department
* of the the University of British Columbia and the Computer Science
* Department (IV) of the University of Erlangen-Nuremberg, Germany.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)pk_usrreq.c 8.1 (Berkeley) 6/10/93
* $Id: pk_usrreq.c,v 1.2 1994/08/02 07:47:46 davidg Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/protosw.h>
#include <sys/errno.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <net/if.h>
#include <net/if_types.h>
#include <net/route.h>
#include <netccitt/x25.h>
#include <netccitt/pk.h>
#include <netccitt/pk_var.h>
static old_to_new();
static new_to_old();
/*
*
* X.25 Packet level protocol interface to socket abstraction.
*
* Process an X.25 user request on a logical channel. If this is a send
* request then m is the mbuf chain of the send data. If this is a timer
* expiration (called from the software clock routine) them timertype is
* the particular timer.
*
*/
pk_usrreq (so, req, m, nam, control)
struct socket *so;
int req;
register struct mbuf *m, *nam;
struct mbuf *control;
{
register struct pklcd *lcp = (struct pklcd *) so -> so_pcb;
register int error = 0;
if (req == PRU_CONTROL)
return (pk_control (so, (int)m, (caddr_t)nam,
(struct ifnet *)control));
if (control && control -> m_len) {
error = EINVAL;
goto release;
}
if (lcp == NULL && req != PRU_ATTACH) {
error = EINVAL;
goto release;
}
/*
pk_trace (pkcbhead, TR_USER, (struct pklcd *)0,
req, (struct x25_packet *)0);
*/
switch (req) {
/*
* X.25 attaches to socket via PRU_ATTACH and allocates a logical
* channel descriptor. If the socket is to receive connections,
* then the LISTEN state is entered.
*/
case PRU_ATTACH:
if (lcp) {
error = EISCONN;
/* Socket already connected. */
break;
}
lcp = pk_attach (so);
if (lcp == 0)
error = ENOBUFS;
break;
/*
* Detach a logical channel from the socket. If the state of the
* channel is embryonic, simply discard it. Otherwise we have to
* initiate a PRU_DISCONNECT which will finish later.
*/
case PRU_DETACH:
pk_disconnect (lcp);
break;
/*
* Give the socket an address.
*/
case PRU_BIND:
if (nam -> m_len == sizeof (struct x25_sockaddr))
old_to_new (nam);
error = pk_bind (lcp, nam);
break;
/*
* Prepare to accept connections.
*/
case PRU_LISTEN:
error = pk_listen (lcp);
break;
/*
* Initiate a CALL REQUEST to peer entity. Enter state SENT_CALL
* and mark the socket as connecting. Set timer waiting for
* CALL ACCEPT or CLEAR.
*/
case PRU_CONNECT:
if (nam -> m_len == sizeof (struct x25_sockaddr))
old_to_new (nam);
if (pk_checksockaddr (nam))
return (EINVAL);
error = pk_connect (lcp, mtod (nam, struct sockaddr_x25 *));
break;
/*
* Initiate a disconnect to peer entity via a CLEAR REQUEST packet.
* The socket will be disconnected when we receive a confirmation
* or a clear collision.
*/
case PRU_DISCONNECT:
pk_disconnect (lcp);
break;
/*
* Accept an INCOMING CALL. Most of the work has already been done
* by pk_input. Just return the callers address to the user.
*/
case PRU_ACCEPT:
if (lcp -> lcd_craddr == NULL)
break;
bcopy ((caddr_t)lcp -> lcd_craddr, mtod (nam, caddr_t),
sizeof (struct sockaddr_x25));
nam -> m_len = sizeof (struct sockaddr_x25);
if (lcp -> lcd_flags & X25_OLDSOCKADDR)
new_to_old (nam);
break;
/*
* After a receive, we should send a RR.
*/
case PRU_RCVD:
pk_flowcontrol (lcp, /*sbspace (&so -> so_rcv) <= */ 0, 1);
break;
/*
* Send INTERRUPT packet.
*/
case PRU_SENDOOB:
if (m == 0) {
MGETHDR(m, M_WAITOK, MT_OOBDATA);
m -> m_pkthdr.len = m -> m_len = 1;
*mtod (m, octet *) = 0;
}
if (m -> m_pkthdr.len > 32) {
m_freem (m);
error = EMSGSIZE;
break;
}
MCHTYPE(m, MT_OOBDATA);
/* FALLTHROUGH */
/*
* Do send by placing data on the socket output queue.
*/
case PRU_SEND:
if (control) {
register struct cmsghdr *ch = mtod (m, struct cmsghdr *);
control -> m_len -= sizeof (*ch);
control -> m_data += sizeof (*ch);
error = pk_ctloutput (PRCO_SETOPT, so, ch -> cmsg_level,
ch -> cmsg_type, &control);
}
if (error == 0 && m)
error = pk_send (lcp, m);
break;
/*
* Abort a virtual circuit. For example all completed calls
* waiting acceptance.
*/
case PRU_ABORT:
pk_disconnect (lcp);
break;
/* Begin unimplemented hooks. */
case PRU_SHUTDOWN:
error = EOPNOTSUPP;
break;
case PRU_CONTROL:
error = EOPNOTSUPP;
break;
case PRU_SENSE:
#ifdef BSD4_3
((struct stat *)m) -> st_blksize = so -> so_snd.sb_hiwat;
#else
error = EOPNOTSUPP;
#endif
break;
/* End unimplemented hooks. */
case PRU_SOCKADDR:
if (lcp -> lcd_ceaddr == 0)
return (EADDRNOTAVAIL);
nam -> m_len = sizeof (struct sockaddr_x25);
bcopy ((caddr_t)lcp -> lcd_ceaddr, mtod (nam, caddr_t),
sizeof (struct sockaddr_x25));
if (lcp -> lcd_flags & X25_OLDSOCKADDR)
new_to_old (nam);
break;
case PRU_PEERADDR:
if (lcp -> lcd_state != DATA_TRANSFER)
return (ENOTCONN);
nam -> m_len = sizeof (struct sockaddr_x25);
bcopy (lcp -> lcd_craddr ? (caddr_t)lcp -> lcd_craddr :
(caddr_t)lcp -> lcd_ceaddr,
mtod (nam, caddr_t), sizeof (struct sockaddr_x25));
if (lcp -> lcd_flags & X25_OLDSOCKADDR)
new_to_old (nam);
break;
/*
* Receive INTERRUPT packet.
*/
case PRU_RCVOOB:
if (so -> so_options & SO_OOBINLINE) {
register struct mbuf *n = so -> so_rcv.sb_mb;
if (n && n -> m_type == MT_OOBDATA) {
unsigned len = n -> m_pkthdr.len;
so -> so_rcv.sb_mb = n -> m_nextpkt;
if (len != n -> m_len &&
(n = m_pullup (n, len)) == 0)
break;
m -> m_len = len;
bcopy (mtod (m, caddr_t), mtod (n, caddr_t), len);
m_freem (n);
}
break;
}
m -> m_len = 1;
*mtod (m, char *) = lcp -> lcd_intrdata;
break;
default:
panic ("pk_usrreq");
}
release:
if (control != NULL)
m_freem (control);
return (error);
}
/*
* If you want to use UBC X.25 level 3 in conjunction with some
* other X.25 level 2 driver, have the ifp -> if_ioctl routine
* assign pk_start to ia -> ia_start when called with SIOCSIFCONF_X25.
*/
/* ARGSUSED */
pk_start (lcp)
register struct pklcd *lcp;
{
pk_output (lcp);
return (0); /* XXX pk_output should return a value */
}
#ifndef _offsetof
#define _offsetof(t, m) ((int)((caddr_t)&((t *)0)->m))
#endif
struct sockaddr_x25 pk_sockmask = {
_offsetof(struct sockaddr_x25, x25_addr[0]), /* x25_len */
0, /* x25_family */
-1, /* x25_net id */
};
/*ARGSUSED*/
pk_control (so, cmd, data, ifp)
struct socket *so;
int cmd;
caddr_t data;
register struct ifnet *ifp;
{
register struct ifreq_x25 *ifr = (struct ifreq_x25 *)data;
register struct ifaddr *ifa = 0;
register struct x25_ifaddr *ia = 0;
struct pklcd *dev_lcp = 0;
int error, s, old_maxlcn;
unsigned n;
/*
* Find address for this interface, if it exists.
*/
if (ifp)
for (ifa = ifp -> if_addrlist; ifa; ifa = ifa -> ifa_next)
if (ifa -> ifa_addr -> sa_family == AF_CCITT)
break;
ia = (struct x25_ifaddr *)ifa;
switch (cmd) {
case SIOCGIFCONF_X25:
if (ifa == 0)
return (EADDRNOTAVAIL);
ifr -> ifr_xc = ia -> ia_xc;
return (0);
case SIOCSIFCONF_X25:
if ((so->so_state & SS_PRIV) == 0)
return (EPERM);
if (ifp == 0)
panic ("pk_control");
if (ifa == (struct ifaddr *)0) {
register struct mbuf *m;
MALLOC(ia, struct x25_ifaddr *, sizeof (*ia),
M_IFADDR, M_WAITOK);
if (ia == 0)
return (ENOBUFS);
bzero ((caddr_t)ia, sizeof (*ia));
if (ifa = ifp -> if_addrlist) {
for ( ; ifa -> ifa_next; ifa = ifa -> ifa_next)
;
ifa -> ifa_next = &ia -> ia_ifa;
} else
ifp -> if_addrlist = &ia -> ia_ifa;
ifa = &ia -> ia_ifa;
ifa -> ifa_netmask = (struct sockaddr *)&pk_sockmask;
ifa -> ifa_addr = (struct sockaddr *)&ia -> ia_xc.xc_addr;
ifa -> ifa_dstaddr = (struct sockaddr *)&ia -> ia_dstaddr; /* XXX */
ia -> ia_ifp = ifp;
ia -> ia_dstaddr.x25_family = AF_CCITT;
ia -> ia_dstaddr.x25_len = pk_sockmask.x25_len;
} else if (ISISO8802(ifp) == 0) {
rtinit (ifa, (int)RTM_DELETE, 0);
}
old_maxlcn = ia -> ia_maxlcn;
ia -> ia_xc = ifr -> ifr_xc;
ia -> ia_dstaddr.x25_net = ia -> ia_xc.xc_addr.x25_net;
if (ia -> ia_maxlcn != old_maxlcn && old_maxlcn != 0) {
/* VERY messy XXX */
register struct pkcb *pkp;
FOR_ALL_PKCBS(pkp)
if (pkp -> pk_ia == ia)
pk_resize (pkp);
}
/*
* Give the interface a chance to initialize if this
p * is its first address, and to validate the address.
*/
ia -> ia_start = pk_start;
s = splimp();
if (ifp -> if_ioctl)
error = (*ifp -> if_ioctl)(ifp, SIOCSIFCONF_X25,
(caddr_t) ifa);
if (error)
ifp -> if_flags &= ~IFF_UP;
else if (ISISO8802(ifp) == 0)
error = rtinit (ifa, (int)RTM_ADD, RTF_UP);
splx (s);
return (error);
default:
if (ifp == 0 || ifp -> if_ioctl == 0)
return (EOPNOTSUPP);
return ((*ifp -> if_ioctl)(ifp, cmd, data));
}
}
pk_ctloutput (cmd, so, level, optname, mp)
struct socket *so;
struct mbuf **mp;
int cmd, level, optname;
{
register struct mbuf *m = *mp;
register struct pklcd *lcp = (struct pklcd *) so -> so_pcb;
int error = EOPNOTSUPP;
if (m == 0)
return (EINVAL);
if (cmd == PRCO_SETOPT) switch (optname) {
case PK_FACILITIES:
if (m == 0)
return (EINVAL);
lcp -> lcd_facilities = m;
*mp = 0;
return (0);
case PK_ACCTFILE:
if ((so->so_state & SS_PRIV) == 0)
error = EPERM;
else if (m -> m_len)
error = pk_accton (mtod (m, char *));
else
error = pk_accton ((char *)0);
break;
case PK_RTATTACH:
error = pk_rtattach (so, m);
break;
case PK_PRLISTEN:
error = pk_user_protolisten (mtod (m, u_char *));
}
if (*mp) {
(void) m_freem (*mp);
*mp = 0;
}
return (error);
}
/*
* Do an in-place conversion of an "old style"
* socket address to the new style
*/
static
old_to_new (m)
register struct mbuf *m;
{
register struct x25_sockaddr *oldp;
register struct sockaddr_x25 *newp;
register char *ocp, *ncp;
struct sockaddr_x25 new;
oldp = mtod (m, struct x25_sockaddr *);
newp = &new;
bzero ((caddr_t)newp, sizeof (*newp));
newp -> x25_family = AF_CCITT;
newp -> x25_len = sizeof(*newp);
newp -> x25_opts.op_flags = (oldp -> xaddr_facilities & X25_REVERSE_CHARGE)
| X25_MQBIT | X25_OLDSOCKADDR;
if (oldp -> xaddr_facilities & XS_HIPRIO) /* Datapac specific */
newp -> x25_opts.op_psize = X25_PS128;
bcopy ((caddr_t)oldp -> xaddr_addr, newp -> x25_addr,
(unsigned)min (oldp -> xaddr_len, sizeof (newp -> x25_addr) - 1));
if (bcmp ((caddr_t)oldp -> xaddr_proto, newp -> x25_udata, 4) != 0) {
bcopy ((caddr_t)oldp -> xaddr_proto, newp -> x25_udata, 4);
newp -> x25_udlen = 4;
}
ocp = (caddr_t)oldp -> xaddr_userdata;
ncp = newp -> x25_udata + 4;
while (*ocp && ocp < (caddr_t)oldp -> xaddr_userdata + 12) {
if (newp -> x25_udlen == 0)
newp -> x25_udlen = 4;
*ncp++ = *ocp++;
newp -> x25_udlen++;
}
bcopy ((caddr_t)newp, mtod (m, char *), sizeof (*newp));
m -> m_len = sizeof (*newp);
}
/*
* Do an in-place conversion of a new style
* socket address to the old style
*/
static
new_to_old (m)
register struct mbuf *m;
{
register struct x25_sockaddr *oldp;
register struct sockaddr_x25 *newp;
register char *ocp, *ncp;
struct x25_sockaddr old;
oldp = &old;
newp = mtod (m, struct sockaddr_x25 *);
bzero ((caddr_t)oldp, sizeof (*oldp));
oldp -> xaddr_facilities = newp -> x25_opts.op_flags & X25_REVERSE_CHARGE;
if (newp -> x25_opts.op_psize == X25_PS128)
oldp -> xaddr_facilities |= XS_HIPRIO; /* Datapac specific */
ocp = (char *)oldp -> xaddr_addr;
ncp = newp -> x25_addr;
while (*ncp) {
*ocp++ = *ncp++;
oldp -> xaddr_len++;
}
bcopy (newp -> x25_udata, (caddr_t)oldp -> xaddr_proto, 4);
if (newp -> x25_udlen > 4)
bcopy (newp -> x25_udata + 4, (caddr_t)oldp -> xaddr_userdata,
(unsigned)(newp -> x25_udlen - 4));
bcopy ((caddr_t)oldp, mtod (m, char *), sizeof (*oldp));
m -> m_len = sizeof (*oldp);
}
pk_checksockaddr (m)
struct mbuf *m;
{
register struct sockaddr_x25 *sa = mtod (m, struct sockaddr_x25 *);
register char *cp;
if (m -> m_len != sizeof (struct sockaddr_x25))
return (1);
if (sa -> x25_family != AF_CCITT ||
sa -> x25_udlen > sizeof (sa -> x25_udata))
return (1);
for (cp = sa -> x25_addr; *cp; cp++) {
if (*cp < '0' || *cp > '9' ||
cp >= &sa -> x25_addr[sizeof (sa -> x25_addr) - 1])
return (1);
}
return (0);
}
pk_send (lcp, m)
struct pklcd *lcp;
register struct mbuf *m;
{
int mqbit = 0, error = 0;
register struct x25_packet *xp;
register struct socket *so;
if (m -> m_type == MT_OOBDATA) {
if (lcp -> lcd_intrconf_pending)
error = ETOOMANYREFS;
if (m -> m_pkthdr.len > 32)
error = EMSGSIZE;
M_PREPEND(m, PKHEADERLN, M_WAITOK);
if (m == 0 || error)
goto bad;
*(mtod (m, octet *)) = 0;
xp = mtod (m, struct x25_packet *);
X25SBITS(xp -> bits, fmt_identifier, 1);
xp -> packet_type = X25_INTERRUPT;
SET_LCN(xp, lcp -> lcd_lcn);
sbinsertoob ( (so = lcp -> lcd_so) ?
&so -> so_snd : &lcp -> lcd_sb, m);
goto send;
}
/*
* Application has elected (at call setup time) to prepend
* a control byte to each packet written indicating m-bit
* and q-bit status. Examine and then discard this byte.
*/
if (lcp -> lcd_flags & X25_MQBIT) {
if (m -> m_len < 1) {
m_freem (m);
return (EMSGSIZE);
}
mqbit = *(mtod (m, u_char *));
m -> m_len--;
m -> m_data++;
m -> m_pkthdr.len--;
}
error = pk_fragment (lcp, m, mqbit & 0x80, mqbit & 0x40, 1);
send:
if (error == 0 && lcp -> lcd_state == DATA_TRANSFER)
lcp -> lcd_send (lcp); /* XXXXXXXXX fix pk_output!!! */
return (error);
bad:
if (m)
m_freem (m);
return (error);
}

View File

@ -1,245 +0,0 @@
/*
* Copyright (c) Computing Centre, University of British Columbia, 1985
* Copyright (C) Computer Science Department IV,
* University of Erlangen-Nuremberg, Germany, 1990, 1991, 1992
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by the
* Laboratory for Computation Vision and the Computer Science Department
* of the the University of British Columbia and the Computer Science
* Department (IV) of the University of Erlangen-Nuremberg, Germany.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)pk_var.h 8.1 (Berkeley) 6/10/93
* $Id: pk_var.h,v 1.7 1995/11/21 12:54:12 bde Exp $
*/
#ifndef _NETCCITT_PK_VAR_H_
#define _NETCCITT_PK_VAR_H_
/*
*
* X.25 Logical Channel Descriptor
*
*/
struct pklcd {
struct pklcd_q {
struct pklcd_q *q_forw; /* debugging chain */
struct pklcd_q *q_back; /* debugging chain */
} lcd_q;
int (*lcd_upper) __P((struct pklcd *lcp, struct mbuf *m));
/* switch to socket vs datagram vs ...*/
caddr_t lcd_upnext; /* reference for lcd_upper() */
int (*lcd_send) __P((struct pklcd *lcp));
/* if X.25 front end, direct connect */
caddr_t lcd_downnext; /* reference for lcd_send() */
short lcd_lcn; /* Logical channel number */
short lcd_state; /* Logical Channel state */
short lcd_timer; /* Various timer values */
short lcd_dg_timer; /* to reclaim idle datagram circuits */
bool lcd_intrconf_pending; /* Interrupt confirmation pending */
octet lcd_intrdata; /* Octet of incoming intr data */
char lcd_retry; /* Timer retry count */
char lcd_rsn; /* Seq no of last received packet */
char lcd_ssn; /* Seq no of next packet to send */
char lcd_output_window; /* Output flow control window */
char lcd_input_window; /* Input flow control window */
char lcd_last_transmitted_pr;/* Last Pr value transmitted */
bool lcd_rnr_condition; /* Remote in busy condition */
bool lcd_window_condition; /* Output window size exceeded */
bool lcd_reset_condition; /* True, if waiting reset confirm */
bool lcd_rxrnr_condition; /* True, if we have sent rnr */
char lcd_packetsize; /* Maximum packet size */
char lcd_windowsize; /* Window size - both directions */
octet lcd_closed_user_group; /* Closed user group specification */
char lcd_flags; /* copy of sockaddr_x25 op_flags */
struct mbuf *lcd_facilities; /* user supplied facilities for cr */
struct mbuf *lcd_template; /* Address of response packet */
struct socket *lcd_so; /* Socket addr for connection */
struct sockaddr_x25 *lcd_craddr;/* Calling address pointer */
struct sockaddr_x25 *lcd_ceaddr;/* Called address pointer */
time_t lcd_stime; /* time circuit established */
long lcd_txcnt; /* Data packet transmit count */
long lcd_rxcnt; /* Data packet receive count */
short lcd_intrcnt; /* Interrupt packet transmit count */
struct pklcd *lcd_listen; /* Next lcd on listen queue */
struct pkcb *lcd_pkp; /* Network this lcd is attached to */
struct mbuf *lcd_cps; /* Complete Packet Sequence reassembly*/
long lcd_cpsmax; /* Max length for CPS */
struct sockaddr_x25 lcd_faddr; /* Remote Address (Calling) */
struct sockaddr_x25 lcd_laddr; /* Local Address (Called) */
struct sockbuf lcd_sb; /* alternate for datagram service */
};
struct dll_ctlinfo;
/*
* Per network information, allocated dynamically
* when a new network is configured.
*/
struct pkcb {
struct pkcb_q {
struct pkcb_q *q_forw;
struct pkcb_q *q_backw;
} pk_q;
short pk_state; /* packet level status */
short pk_maxlcn; /* local copy of xc_maxlcn */
int (*pk_lloutput) __P((caddr_t, struct mbuf *, struct rtentry *));
/* link level output procedure */
caddr_t (*pk_llctlinput) __P((int, int, struct dll_ctlinfo *));
/* link level ctloutput procedure */
caddr_t pk_llnext; /* handle for next level down */
struct x25config *pk_xcp; /* network specific configuration */
struct x25_ifaddr *pk_ia; /* backpointer to ifaddr */
struct pklcd **pk_chan; /* actual size == xc_maxlcn+1 */
short pk_dxerole; /* DXE role of PLE over LLC2 */
short pk_restartcolls; /* counting RESTART collisions til resolved */
struct rtentry *pk_rt; /* back pointer to route */
struct rtentry *pk_llrt; /* pointer to reverse mapping */
u_short pk_refcount; /* ref count */
};
#define FOR_ALL_PKCBS(p) for((p) = (struct pkcb *)(pkcb_q.q_forw); \
(pkcb_q.q_forw != &pkcb_q) && ((struct pkcb_q *)(p) != &pkcb_q); \
(p) = (struct pkcb *)((p) -> pk_q.q_forw))
#define PQEMPTY (pkcb_q.q_forw == &pkcb_q)
/*
* Interface address, x25 version. Exactly one of these structures is
* allocated for each interface with an x25 address.
*
* The ifaddr structure contains the protocol-independent part
* of the structure, and is assumed to be first.
*/
struct x25_ifaddr {
struct ifaddr ia_ifa; /* protocol-independent info */
#define ia_ifp ia_ifa.ifa_ifp
#define ia_flags ia_ifa.ifa_flags
struct x25config ia_xc; /* network specific configuration */
struct pkcb *ia_pkcb;
#define ia_maxlcn ia_xc.xc_maxlcn
int (*ia_start) __P((struct pklcd *lcp));
/* connect, confirm method */
struct sockaddr_x25 ia_dstaddr; /* reserve space for route dst */
};
/*
* ``Link-Level'' extension to Routing Entry for upper level
* packet switching via X.25 virtual circuits.
*/
struct llinfo_x25 {
struct llinfo_x25 *lx_next; /* chain together in linked list */
struct llinfo_x25 *lx_prev; /* chain together in linked list */
struct rtentry *lx_rt; /* back pointer to route */
struct pklcd *lx_lcd; /* local connection block */
struct x25_ifaddr *lx_ia; /* may not be same as rt_ifa */
int lx_state; /* can't trust lcd->lcd_state */
int lx_flags;
int lx_timer; /* for idle timeout */
int lx_family; /* for dispatch */
};
/* States for lx_state */
#define LXS_NEWBORN 0
#define LXS_RESOLVING 1
#define LXS_FREE 2
#define LXS_CONNECTING 3
#define LXS_CONNECTED 4
#define LXS_DISCONNECTING 5
#define LXS_LISTENING 6
/* flags */
#define LXF_VALID 0x1 /* Circuit is live, etc. */
#define LXF_RTHELD 0x2 /* this lcb references rtentry */
#define LXF_LISTEN 0x4 /* accepting incoming calls */
/*
* Definitions for accessing bitfields/bitslices inside X.25 structs
*/
struct x25bitslice {
unsigned int bs_mask;
unsigned int bs_shift;
};
#define calling_addrlen 0
#define called_addrlen 1
#define q_bit 2
#define d_bit 3
#define fmt_identifier 4
#define lc_group_number 1
#define p_r 5
#define m_bit 6
#define p_s 7
#define zilch 8
#define X25GBITS(Arg, Index) (((Arg) & x25_bitslice[(Index)].bs_mask) >> x25_bitslice[(Index)].bs_shift)
#define X25SBITS(Arg, Index, Val) (Arg) |= (((Val) << x25_bitslice[(Index)].bs_shift) & x25_bitslice[(Index)].bs_mask)
#define X25CSBITS(Arg, Index, Val) (Arg) = (((Val) << x25_bitslice[(Index)].bs_shift) & x25_bitslice[(Index)].bs_mask)
extern struct x25bitslice x25_bitslice[];
#define ISOFIFTTYPE(i,t) ((i)->if_type == (t))
#define ISISO8802(i) ((ISOFIFTTYPE(i, IFT_ETHER) || \
ISOFIFTTYPE(i, IFT_ISO88023) || \
ISOFIFTTYPE(i, IFT_ISO88024) || \
ISOFIFTTYPE(i, IFT_ISO88025) || \
ISOFIFTTYPE(i, IFT_ISO88026) || \
ISOFIFTTYPE(i, IFT_P10) || \
ISOFIFTTYPE(i, IFT_P80) || \
ISOFIFTTYPE(i, IFT_FDDI)))
/*
* miscellaneous debugging info
*/
struct mbuf_cache {
int mbc_size;
int mbc_num;
int mbc_oldsize;
struct mbuf **mbc_cache;
};
#if defined(KERNEL) && defined(CCITT)
extern struct pkcb_q pkcb_q;
extern struct pklcd *pk_listenhead;
void ccittintr __P((void));
struct pklcd *pk_attach __P((struct socket *so));
extern char *pk_name[], *pk_state[];
extern int pk_t20, pk_t21, pk_t22, pk_t23;
#endif
#endif

View File

@ -1,163 +0,0 @@
/*
* Copyright (c) University of British Columbia, 1984
* Copyright (c) 1990, 1992, 1993
* The Regents of the University of California. All rights reserved.
* University of Erlangen-Nuremberg, Germany, 1992
*
* This code is derived from software contributed to Berkeley by the
* Laboratory for Computation Vision and the Computer Science Department
* of the the University of British Columbia and the Computer Science
* Department (IV) of the University of Erlangen-Nuremberg, Germany.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)x25.h 8.1 (Berkeley) 6/10/93
* $Id: x25.h,v 1.3 1994/08/21 05:44:11 paul Exp $
*/
#ifndef _NETCCITT_X25_H_
#define _NETCCITT_X25_H_
#ifdef KERNEL
#define PRC_IFUP 3
#define PRC_LINKUP 4
#define PRC_LINKDOWN 5
#define PRC_LINKRESET 6
#define PRC_LINKDONTCOPY 7
#ifndef PRC_DISCONNECT_REQUEST
#define PRC_DISCONNECT_REQUEST 10
#endif
#endif
#define CCITTPROTO_HDLC 1
#define CCITTPROTO_X25 2 /* packet level protocol */
#define IEEEPROTO_802LLC 3 /* doesn't belong here */
#define HDLCPROTO_LAP 1
#define HDLCPROTO_LAPB 2
#define HDLCPROTO_UNSET 3
#define HDLCPROTO_LAPD 4
/* socket options */
#define PK_ACCTFILE 1 /* use level = CCITTPROTO_X25 */
#define PK_FACILITIES 2 /* use level = CCITTPROTO_X25 */
#define PK_RTATTACH 3 /* use level = CCITTPROTO_X25 */
#define PK_PRLISTEN 4 /* use level = CCITTPROTO_X25 */
#define MAX_FACILITIES 109 /* maximum size for facilities */
/*
* X.25 Socket address structure. It contains the X.121 or variation of
* X.121, facilities information, higher level protocol value (first four
* bytes of the User Data field), and the last 12 characters of the User
* Data field.
*/
struct x25_sockaddr { /* obsolete - use sockaddr_x25 */
short xaddr_len; /* Length of xaddr_addr. */
u_char xaddr_addr[15]; /* Network dependent or X.121 address. */
u_char xaddr_facilities; /* Facilities information. */
#define XS_REVERSE_CHARGE 0x01
#define XS_HIPRIO 0x02
u_char xaddr_proto[4]; /* Protocol ID (4 bytes of user data). */
u_char xaddr_userdata[12]; /* Remaining User data field. */
};
/*
* X.25 Socket address structure. It contains the network id, X.121
* address, facilities information, higher level protocol value (first four
* bytes of the User Data field), and up to 12 characters of User Data.
*/
struct sockaddr_x25 {
u_char x25_len;
u_char x25_family; /* must be AF_CCITT */
short x25_net; /* network id code (usually a dnic) */
char x25_addr[16]; /* X.121 address (null terminated) */
struct x25opts {
char op_flags; /* miscellaneous options */
/* pk_var.h defines other lcd_flags */
#define X25_REVERSE_CHARGE 0x01 /* remote DTE pays for call */
#define X25_DBIT 0x02 /* not yet supported */
#define X25_MQBIT 0x04 /* prepend M&Q bit status byte to packet data */
#define X25_OLDSOCKADDR 0x08 /* uses old sockaddr structure */
#define X25_DG_CIRCUIT 0x10 /* lcd_flag: used for datagrams */
#define X25_DG_ROUTING 0x20 /* lcd_flag: peer addr not yet known */
#define X25_MBS_HOLD 0x40 /* lcd_flag: collect m-bit sequences */
char op_psize; /* requested packet size */
#define X25_PS128 7
#define X25_PS256 8
#define X25_PS512 9
char op_wsize; /* window size (1 .. 7) */
char op_speed; /* throughput class */
} x25_opts;
short x25_udlen; /* user data field length */
char x25_udata[16]; /* user data field */
};
/*
* network configuration info
* this structure must be 16 bytes long
*/
struct x25config {
struct sockaddr_x25 xc_addr;
/* link level parameters */
u_short xc_lproto:4, /* link level protocol eg. CCITTPROTO_HDLC */
xc_lptype:4, /* protocol type eg. HDLCPROTO_LAPB */
xc_ltrace:1, /* link level tracing flag */
xc_lwsize:7; /* link level window size */
u_short xc_lxidxchg:1, /* link level XID exchange flag - NOT YET */
/* packet level parameters */
xc_rsvd1:2,
xc_pwsize:3, /* default window size */
xc_psize:4, /* default packet size 7=128, 8=256, ... */
xc_type:3, /* network type */
#define X25_1976 0
#define X25_1980 1
#define X25_1984 2
#define X25_DDN 3
#define X25_BASIC 4
xc_ptrace:1, /* packet level tracing flag */
xc_nodnic:1, /* remove our dnic when calling on net */
xc_prepnd0:1; /* prepend 0 when making offnet calls */
u_short xc_maxlcn; /* max logical channels */
u_short xc_dg_idletimo; /* timeout for idle datagram circuits. */
};
#ifdef IFNAMSIZ
struct ifreq_x25 {
char ifr_name[IFNAMSIZ]; /* if name, e.g. "en0" */
struct x25config ifr_xc;
};
#define SIOCSIFCONF_X25 _IOW('i', 12, struct ifreq_x25) /* set ifnet config */
#define SIOCGIFCONF_X25 _IOWR('i',13, struct ifreq_x25) /* get ifnet config */
#endif
#endif

View File

@ -1,76 +0,0 @@
/*
* Copyright (c) University of British Columbia, 1984
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* the Laboratory for Computation Vision and the Computer Science Department
* of the University of British Columbia.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)x25acct.h 8.1 (Berkeley) 6/10/93
* $Id: x25acct.h,v 1.2 1994/08/02 07:47:52 davidg Exp $
*/
#ifndef _NETCCITT_X25ACCT_H_
#define _NETCCITT_X25ACCT_H_
/*
* Format of X.25 accounting record written
* to X25ACCTF whenever a circuit is closed.
*/
#ifdef waterloo
#define X25ACCTF "/usr/adm/logs/x25acct"
#else
#define X25ACCTF "/usr/adm/x25acct"
#endif
struct x25acct {
time_t x25acct_stime; /* start time */
#ifdef waterloo
u_long x25acct_etime; /* elapsed time (seconds) */
#else
u_short x25acct_etime; /* elapsed time (seconds) */
#endif
short x25acct_uid; /* user id */
short x25acct_net; /* network id */
u_short x25acct_psize:4, /* packet size */
x25acct_addrlen:4, /* x25acct_addr length */
x25acct_revcharge:1, /* reverse charging */
x25acct_callin:1, /* incoming call */
x25acct_unused:6;
char x25acct_addr[8]; /* remote DTE address (in bcd) */
char x25acct_udata[4]; /* protocol id */
long x25acct_txcnt; /* packets transmitted */
long x25acct_rxcnt; /* packets received */
};
#endif

View File

@ -1,69 +0,0 @@
/*
* Copyright (c) University of British Columbia, 1984
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* the Laboratory for Computation Vision and the Computer Science Department
* of the University of British Columbia.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)x25err.h 8.1 (Berkeley) 6/10/93
* $Id: x25err.h,v 1.3 1994/08/21 05:44:12 paul Exp $
*/
#ifndef _NETCCITT_X25ERR_H_
#define _NETCCITT_X25ERR_H_
/*
*
* X.25 Reset and Clear errors and diagnostics. These values are
* returned in the u_error field of the u structure.
*
*/
#define EXRESET 100 /* Reset: call reset */
#define EXROUT 101 /* Reset: out of order */
#define EXRRPE 102 /* Reset: remote procedure error */
#define EXRLPE 103 /* Reset: local procedure error */
#define EXRNCG 104 /* Reset: network congestion */
#define EXCLEAR 110 /* Clear: call cleared */
#define EXCBUSY 111 /* Clear: number busy */
#define EXCOUT 112 /* Clear: out of order */
#define EXCRPE 113 /* Clear: remote procedure error */
#define EXCRRC 114 /* Clear: collect call refused */
#define EXCINV 115 /* Clear: invalid call */
#define EXCAB 116 /* Clear: access barred */
#define EXCLPE 117 /* Clear: local procedure error */
#define EXCNCG 118 /* Clear: network congestion */
#define EXCNOB 119 /* Clear: not obtainable */
#endif