Solstice X.25 9.2 Developer's Guide

12.9 Miscellaneous ioctls

This section describes some miscellaneous ioctl calls that were either not covered in the previous sections, or are supported from previous releases for backward compatibility. This does not imply backward compatibility with all user-written software for previous releases of Solstice X.25.

12.9.1 Obtaining Statistics

Use the X25_GET_NLINKS ioctl to determine the number of links configured:

int s, error, nlinks;
 error = ioctl(s, X25_GET_NLINKS, &nlinks);

The X.25 software maintains statistics for levels 1, 2, and 3. The statistics are made available for any socket at any time (that is, the sockets over which the calls for reading statistics are issued need not have superuser privilege).

The X25_RD_LINK_STATISTICS ioctl is used to read statistics of levels 1 and 2:

struct ss_dstats {
    int32_t ssd_ipack;    /* input packets */
    int32_t ssd_opack;    /* output packets */
    int32_t ssd_ichar;    /* input bytes */
    int32_t ssd_ochar;    /* output bytes */
 };
 
 /* error stats */
 struct ss_estats {
    int32_t sse_abort;      /* abort received */
    int32_t sse_crc;        /* CRC error */
    int32_t sse_overrun;    /* receiver overrun */
    int32_t sse_underrun;   /* xmitter underrun */
 };
 typedef struct x25_link_stat_db_s {
    int linkid; /* link identifier */
    u_short state;
    /* 0: initial state
     * 1: SABM outstanding
     * 2: FRMR outstanding
     * 3: DISC outstanding
     * 4: information transfer state
     */
    u_short hs_sentsabms;       /* sabms sent */
    struct ss_dstats hs_data;   /* data stats */
    struct ss_estats hs_errors; /* error stats */
 } X25_LINK_STAT_DB;

 X25_LINK_STAT_DB link_stats;
 int s, error;
 error = ioctl(s, X25_RD_LINK_STATISTICS, &link_stats); 

The linkid field in the X25_LINK_STAT_DB structure identifies the interface whose statistics are to be read.

The X25_RD_PKT_STATISTICS ioctl is used for reading packet-level statistics for a specified logical channel:

typedef struct x25_pkt_stat_db_s {
    int linkid;   /* link identifier */
    u_short lcn;  /* logical channel identifier */
    u_char state; /* level 3 lcn state */
 /* current state of virtual circuit
    ST_OFF (0): virtual circuit not active
    ST_LISTEN (1): passive wait for incoming call
    ST_READY (2): connection in process of being established
                  (connection NOT up yet)
    ST_SENT_CALL (3): wait for call connected packet
    ST_RECV_CALL (4): wait user to send call accepted packet
    ST_CALL_COLLISION (5): call collision state
    ST_RECV_CLR (6): unused (should indicate reception of a
                 clear packet)
    ST_SENT_CLR (7): wait for clear confirmation packet
    ST_DATA_TRANSFER (8): in normal data transfer
    ST_SENT_RES (9): wait reset confirmation packet
 */
    u_char sub_state; /* level 3 lcn sub_state */
    /* valid only when state is ST_DATA_TRANSFER
       bit 0 (RECV_RNR): remote busy
       bit 1 (RECV_INT): wait user to read interrupt data
       bit 2 (SENT_INT): wait for interrupt confirmation
       bit 3 (SENT_RNR): local busy
    */
    u_char intcnt;   /* number of received interrupt datum */
    u_char resetcnt; /* times of virtual circuit reset */
    int sendpkts;    /* number of output packets */
    int recvpkts;    /* number of input packets */
    short pgrp;      /* process group of socket, if not 0 */
    short flags;     /* flag bits. If bit 0 is set, it */
    /* indicates an incoming call. */
    /* Otherwise, it is an outgoing call. */
 } X25_PKT_STAT_DB;

 X25_PKT_STAT_DB pkt_stats;
 int s, error;
 error = ioctl(s, X25_RD_PKT_STATISTICS, &pkt_stats); 

The linkid field in the X25_PKT_STAT_DB structure identifies a link, and lcn identifies the logical channel whose statistics are to be read. Note that pkt_stats.lcn needs to be set to the proper logical channel number before making the X25_RD_PKT_STATISTICS ioctl call.

Solstice X.25 also provides ioctl commands to read the status of all of the links currently active and all the virtual circuits currently active. Use the X25_GET_NEXT_LINK_STAT ioctl to obtain link status as follows:

/*  The following is used to cycle through all the interfaces -
  *  static HDLC links as well as links used for LLC2.
  */
 typedef struct x25_next_link_stat_s {
    u_char opt;             /* search option */
 #define  GET_FIRST  0      /* get first one */
 #define  GET_NEXT   1      /* get next one */
    u_char specific;        /* applies to specified interface */
    u_char link_type;       /* HDLC_TYPE, LLC_TYPE */
    int linkid;             /* interface id */
    X25_MACADDR mac;        /* always null in current release */
 /* Level 2 states */
 #define LINKSTATE_DOWN  0               /* initial state */
 #define LINKSTATE_SABM  1               /* SABM outstanding */
 #define LINKSTATE_FRMR  2               /* FRMR outstanding */
 #define LINKSTATE_DISC  3               /* DISC outstanding */
 #define LINKSTATE_UP    4               /* info transfer state */
    u_short state;              /* link state--see preceding defines */
    u_short hs_sentsabms;       /* sabms sent */
    struct ss_dstats hs_data;   /* data stats */
    struct ss_estats hs_errors; /* error stats */
 } X25_NEXT_LINK_STAT;

    int s;
    int error;
    X25_NEXT_LINK_STAT lstats;

    lstats.opt = GET_FIRST;
    lstats.specific = 0;
    do {
       error = ioctl(s, X25_GET_NEXT_LINK_STAT, &lstats);
       if (error == 0)
       /* print the statistics */;
       } while (error == 0); 

If the statistics for a specific link are required, set specific to 1, and linkid to the id of the interface whose statistics are required. After the first call, the opt field will automatically be changed to GET_NEXT. When the statistics for all the links are returned, error will be -1, and errno will be set to ENOENT.

Use the X25_GET_NEXT_VC_STAT ioctl to obtain the status of all the virtual circuits as follows:


Example 12-1 Reading Virtual Circuit Status

/* X25_NEXT_VC_STAT is used to cycle through all virtual circuits,
  * over HDLC as well as LLC type links.
  */
 typedef struct x25_next_vc_stat_s {
    u_char    opt;       /* search option */
    u_char    specific;  /* applies to specified linkid */
    u_char    link_type; /* HDLC_TYPE, LLC_TYPE */
    int    linkid;       /* link id */
    u_short    lcn;      /* logical channel to return */
    u_char    state;     /* level 3 lcn state */
 #define ST_OFF             0
 #define ST_LISTEN          1
 #define ST_READY           2
 #define ST_SENT_CALL       3
 #define ST_RECV_CALL       4
 #define ST_CALL_COLLISION  5
 #define ST_RECV_CLR        6
 #define ST_SENT_CLR        7
 #define ST_DATA_TRANSFER   8
 #define ST_SENT_RES        9
    u_char    sub_state;  /* level 3 lcn sub_state */
 #define RECV_RNR  0
 #define RECV_INT  1
 #define SENT_INT  2
 #define SENT_RNR  3
    u_char    intcnt;    /* number of received interrupts */
    u_char    resetcnt;  /* times of virtual circuit reset */
    int    sendpkts;     /* number of output packets */
    int    recvpkts;     /* number of input packets */
    short    pgrp;       /* process group, if any */
    short    flags;      /* various flags for future */
 #define  INCOMING_CALL  0x01
 #define  IS_A_PVC  0x02
    struct sockaddr  sa;  /* Remote X.121/IP address */
    AEF    aef;           /* Remote AEF, if any */
    X25_MACADDR  mac;    /* Remote mac for LLC links */
 } X25_NEXT_VC_STAT;

    int s;
    int error;
    X25_NEXT_VC_STAT vstats;

    vstats.opt = GET_FIRST;
    vstats.specific = 0;
    do {
       error = ioctl(s, X25_GET_NEXT_VC_STAT, &vstats);
       if (error == 0)
       /* print the statistics */;
       } while (error == 0);

hoIf the statistics of virtual circuits for a specific link are required, set specific to 1, and linkid to the id of the desired interface. After the first call, the opt field will automatically be changed to GET_NEXT. When the statistics for all the virtual circuits are returned, error will be -1, and errno will be set to ENOENT.

12.9.1.1 Obtaining Version Number

The X25_VERSION ioctl returns the version number of the Solstice X.25 kernel code. You can issue this call on any socket. The version number returned for the current release of Solstice X.25 is 92.

int so, version, error;
 error = ioctl(s, X25_VERSION, &version);