Solstice X.25 9.2 Administration Guide

High-Level Data Link Control


Note -

The Solstice X.25 9.2 LAPB driver implements an interface that is compatible with SunNet X.25 7.0's HDLC interface. This has been included for backward-compatibility with SunNet X.25 7.0 only. In other situations, use LAPB plus DLPI. This implementation of HDLC does not support hdlcconf.


Solstice X.25 9.2 supports the Application Program interface that was available in SunNet X.25 7.0. An application program can open an HDLC device as a file and can control HDLC through SunOS system calls.

Before starting X.25, you need to associate the HDLC driver with the relevant WAN port. To do so, enter:


hostname#: iflayer ifdn portname

Application Program

You can access HDLC from a program with the same interface used at the user level, the ifnet device. A program can perform all the user-level tasks presented above with standard system calls.


Note -

This description assumes that you are familiar with the system calls open(2), close(2), read(2), write(2) and ioctl(2). It also assumes that the ifnet device has been initialized and layered.


All of the contents and structures used are in the following include files:


#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sundev/syncstat.h>
#include <nethdlc/hdlc_ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>

Access HDLC by opening the ifd device attached to it. In the examples, this is /dev/ifd0. For example:


fid = open ("/dev/ifd0", )_RDWR);

To configure HDLC, invoke ioctl(2) as follows:


int fid, error;
struct hdlc_param_req hpr;
struct hdlc_param *hdlc_param

hdlc_param = &hpr.hp:
/* set fields in structure pointed to by hdlc_param */
error = ioctl(fid, HDLC_SET_PARAM, (caddr_t) &hpr);

where fid is the value returned by open, HDLC_SET_PARAM is the call to set the parameters, and hdlc_param is a structure defined as follows:


struct hdlc_param {
      u_short hp_t1;        /*T1 - P-bit timer (msec) */
      u_short hp_t2;        /*T2 - max delay before ACK (msec) */
      u_short hp_t3;        /*T3 - max idle link time (msec)
      u_short hp_t4;        /*T4 - LLC2 busy timer (msec) */
      u_short hp_t5;        /*T5 - LLC2 reject timer (msec) */
      u_short hp_t6;        /*T6 - Ack timer (msec) */
      u_short hp_tick;      /* resolution of timer (msec/tick) */
      u_short hp_n1;        /*N1 - max frame size - bytes */
      u_char hp_n2;         /*N2 - max retries (used with T1, T4) */
      u_char hp_xcntl;      /* extended control - mod 128 */
      u_char hp_k;          /* K - window size */
      u_char hp_addr;       /* address */

The value hp_t1 corresponds to the --t1 flag parameter of hdlcconf command and the values hp_t2, hp_t3, hp_tick, hp_n1 and hp_n2 correspond similarly. The hp_xcntl is a boolean value. If it is set, then the implementation will operate in Asynchronous Balanced Mode Extended. Otherwise, it will run in Asynchronous Balanced Mode. The window size is set with hp_k. Lastly, set the HDLC address with hp_addr and the following values:


#define LAPB_ADDR_A   0x03   /* commands to DTE secondary */
                             /* responses from DTE secondary */
#define LAPB_ADDR_B   0x01   /* commands to DCE secondary */
                             /* responses from DCE secondary

Setting Parameters

The kernel does not check the parameters, it assumes they are set to reasonable values. Take care when setting them, as wrong parameters can affect the operation of the HDLC link.

Before setting the parameters, it is advisable to get them first with the ioctl call HDLC_GET_PARAM. The HDLC_SET_PARAM and HDLC_GET_PARAM calls have the same parameter format.

After setting the HDLC parameters, start HDLC by making the following call:


int fid;
 error = ioctl (fid, HDLC_INIT, 0);

In Solstice X.25 9.2 this is equivalent to executing hdlcstart in SunNet X.25 7.0.

Data Transfer

To transfer data to or from HDLC, use read (2) and write (2). Each operation corresponds to an HDLC frame, which means that each read call will return only one packet, even if there is more data waiting and room in the buffer. If there is not enough room in the buffer for the current frame, read fails, and the frame is discarded. The buffer passed to a write call corresponds to a single HDLC frame. Calls to write with a length greater than the maximum frame size (hp_n1) fail.

Statistics


Note -

The command x25stat returns more complete statistics than those returned by the procedure shown below.


To get the same statistics as those returned by hdlcstate in SunNet X.25 7.0, your program should run the HDLC_STATS ioctl call as follows:


int fid, error;
 struct hdlc_stats_req hsr;
 struct hdlc_stats *hdlc_stats;

 hdlc_stats = &hsr.he;
 error = ioctl(fid, HDLC_STATS, (caddr_t) &hsr);
 /* results are in structure pointed to by hdlc_stats */

The hdlc_stats is of type struct hdlc_stats shown below:


struct hdlc_stats {
       u_short        hs_state;     /* hdlc state */
       u_short        hs_sentsabms; /* sabms sent */
       struct ss_dstats hs_data;    /* data stats */
       struct ss_estats hs_errors;  /* error stats */

The value hs_sentsabmns is the cumulative total of SABMS that were transmitted, including retry attempts. The field hs_state can be any one of the following:


#define HDLCLINK_DOWN 0 /* initial state */
#define HDLCLINK_SABM 1 /* SABM outstanding
#define HDLCLINK_FMR 2  /* FRMR outstanding */
#define HDLCLINK_DISC 3 /* DISC outstanding */
#define HDLCLINK_UP   4 /* information transfer state */

The structures ss_dstats and ssestats are defined in the file <sundev/syncstat.h> as follows:


struct ss_dstats {
      long ssd_spack;    /* input packets */
      long ssd_opack;    /* output packets */
      long ssd_ichar;    /* input bytes */
      long ssd_ochar;    /* output bytes */
 ];

 struct ss_estats {
      long sse_abort;    /* abort received */
      long sse_crc;      /* CRC error */
      long sse_overrun;  /* receiver overrun */
      long sse_underrun; /* xmitter underrun */

Their values correspond to the Total bytes and Errors lines of the hdlcstate display.

Shutdown

Normally, HDLC remains up for as long as the remote host is physically connected to the local port. For this reason, close (2) does not affect the state of HDLC, and any packets queued for output are transmitted.

To shut down HDLC, execute the following ioctl:


int fid;
error = ioctl(fid, HDLC_RESET, 0);

This puts the line into the HDLCLINK_DOWN state. Calls to read and write will fail, and errno is set to ENETDOWN. This is the same call that hdlcstop uses.