Annotation of 43BSDReno/contrib/isode-beta/ssap/tsdu2spkt.c, revision 1.1

1.1     ! root        1: /* tsdu2spkt.c - read/write a SPDU to a TSDU */
        !             2: 
        !             3: #ifndef        lint
        !             4: static char *rcsid = "$Header: /f/osi/ssap/RCS/tsdu2spkt.c,v 7.0 89/11/23 22:25:55 mrose Rel $";
        !             5: #endif
        !             6: 
        !             7: /* 
        !             8:  * $Header: /f/osi/ssap/RCS/tsdu2spkt.c,v 7.0 89/11/23 22:25:55 mrose Rel $
        !             9:  *
        !            10:  *
        !            11:  * $Log:       tsdu2spkt.c,v $
        !            12:  * Revision 7.0  89/11/23  22:25:55  mrose
        !            13:  * Release 6.0
        !            14:  * 
        !            15:  */
        !            16: 
        !            17: /*
        !            18:  *                               NOTICE
        !            19:  *
        !            20:  *    Acquisition, use, and distribution of this module and related
        !            21:  *    materials are subject to the restrictions of a license agreement.
        !            22:  *    Consult the Preface in the User's Manual for the full terms of
        !            23:  *    this agreement.
        !            24:  *
        !            25:  */
        !            26: 
        !            27: 
        !            28: /* LINTLIBRARY */
        !            29: 
        !            30: #include <stdio.h>
        !            31: #include "spkt.h"
        !            32: #include "tailor.h"
        !            33: 
        !            34: /*  */
        !            35: 
        !            36: struct local_buf {
        !            37:        char *top;                              /* Top of buffer */
        !            38:        char *ptr;                              /* Pointer to working buffer */
        !            39:        int pgi;                                /* Offset of last PGI li */
        !            40:        int left;                               /* Number of bytes left */
        !            41:        int li;                                 /* Running spdu length */
        !            42:        int allocli;                            /* Allocated li */
        !            43:        int len;                                /* Current buffer size */
        !            44: };
        !            45: 
        !            46: /*  */
        !            47: 
        !            48: #define PMASK_NODATA           0x000000
        !            49: #define        PMASK_CN_ID             0x000001        /*   1: Connection ID */
        !            50: #define        PMASK_CN_ITEMS          0x000002        /*   5: Connect/Accept Item */
        !            51: #define        PMASK_SYNC              0x000004        /*  15: Sync Type Item */
        !            52: #define        PMASK_TOKEN             0x000008        /*  16: Token Item */
        !            53: #define        PMASK_TDISC             0x000010        /*  17: Transport Disc */
        !            54: #define        PMASK_USER_REQ          0x000020        /*  20: Session User Req */
        !            55: #define        PMASK_VERSION           0x000040        /*  22: Version Number */
        !            56: #define        PMASK_PREPARE           0x000080        /*  24: Prepare type */
        !            57: #define        PMASK_ENCLOSE           0x000100        /*  25: Enclosure Item */
        !            58: #define PMASK_TOKEN_SET                0x000200        /*  26: Token Setting Item */
        !            59: #define        PMASK_RESYNC            0x000400        /*  27: Resync type */
        !            60: #define        PMASK_LINK              0x000800        /*  33: Linking information */
        !            61: #define        PMASK_ACT_ID            0x001000        /*  41: Activity ID */
        !            62: #define        PMASK_SERIAL            0x002000        /*  42: Serial Number */
        !            63: #define        PMASK_MIA_DATA          0x004000        /*  46: MIA User Data */
        !            64: #define        PMASK_REFLECT           0x008000        /*  49: Reflect parameter */
        !            65: #define        PMASK_REASON            0x010000        /*  50: Refusal Reason */
        !            66: #define        PMASK_SSAP_CALLING      0x020000        /*  51: Calling SSAP ID */
        !            67: #define        PMASK_SSAP_CALLED       0x040000        /*  52: Called SSAP ID */
        !            68: #define        PMASK_UDATA             0x080000        /* 193: User data */
        !            69: #define        PMASK_XDATA             0x100000        /* 194: Extended user data */
        !            70: 
        !            71: #define PMASK_VARLEN           0x800000        /* PI is Variable Len */
        !            72: #define PMASK_NOTSUPPORTED     -1              /* Type not supported */
        !            73: 
        !            74: 
        !            75: static int si_table[] = {
        !            76:        PMASK_REFLECT,                          /* 0x00: SPDU_ER */
        !            77:        PMASK_ENCLOSE                           /* 0x01: SPDU_GT & SPDU_DT */
        !            78:            | PMASK_TOKEN,
        !            79:        PMASK_TOKEN                             /* 0x02: SPDU_PT */
        !            80:            | PMASK_ENCLOSE
        !            81:            | PMASK_UDATA,
        !            82:        PMASK_NOTSUPPORTED,                     /* 0x03 */
        !            83:        PMASK_NOTSUPPORTED,                     /* 0x04 */
        !            84:        PMASK_NODATA,                           /* 0x05: SPDU_EX */
        !            85:        PMASK_NOTSUPPORTED,                     /* 0x06 */
        !            86:        PMASK_PREPARE,                          /* 0x07: SPDU_PR */
        !            87:        PMASK_ENCLOSE                           /* 0x08: SPDU_NF */
        !            88:            | PMASK_UDATA,
        !            89:        PMASK_TDISC                             /* 0x09: SPDU_FN */
        !            90:            | PMASK_ENCLOSE
        !            91:            | PMASK_UDATA,
        !            92:        PMASK_ENCLOSE                           /* 0x0a: SPDU_DN */
        !            93:            | PMASK_UDATA,
        !            94:        PMASK_NOTSUPPORTED,                     /* 0x0b */
        !            95:        PMASK_CN_ID                             /* 0x0c: SPDU_RF */
        !            96:            | PMASK_TDISC       
        !            97:            | PMASK_USER_REQ
        !            98:            | PMASK_VERSION
        !            99:            | PMASK_ENCLOSE
        !           100:            | PMASK_REASON,
        !           101:        PMASK_CN_ID                             /* 0x0d: SPDU_CN */
        !           102:            | PMASK_CN_ITEMS    
        !           103:            | PMASK_USER_REQ
        !           104:            | PMASK_VERSION
        !           105:            | PMASK_SSAP_CALLING
        !           106:            | PMASK_SSAP_CALLED
        !           107:            | PMASK_UDATA
        !           108:            | PMASK_XDATA,
        !           109:        PMASK_CN_ID                             /* 0x0e: SPDU_AC */
        !           110:            | PMASK_CN_ITEMS    
        !           111:            | PMASK_USER_REQ
        !           112:            | PMASK_VERSION
        !           113:            | PMASK_SSAP_CALLING
        !           114:            | PMASK_TOKEN
        !           115:            | PMASK_ENCLOSE
        !           116:            | PMASK_SSAP_CALLED
        !           117:            | PMASK_UDATA,
        !           118:        PMASK_NOTSUPPORTED,                     /* 0x0f */
        !           119:        PMASK_NOTSUPPORTED,                     /* 0x10 */
        !           120:        PMASK_NOTSUPPORTED,                     /* 0x11 */
        !           121:        PMASK_NOTSUPPORTED,                     /* 0x12 */
        !           122:        PMASK_NOTSUPPORTED,                     /* 0x13 */
        !           123:        PMASK_NOTSUPPORTED,                     /* 0x14 */
        !           124:        PMASK_NODATA,                           /* 0x15: SPDU_GTC */
        !           125:        PMASK_NODATA,                           /* 0x16: SPDU_GTA */
        !           126:        PMASK_NOTSUPPORTED,                     /* 0x17 */
        !           127:        PMASK_NOTSUPPORTED,                     /* 0x18 */
        !           128:        PMASK_TDISC                             /* 0x19: SPDU_AB & SPDU_AI */
        !           129:            | PMASK_REFLECT     
        !           130:            | PMASK_REASON
        !           131:            | PMASK_ENCLOSE
        !           132:            | PMASK_UDATA,
        !           133:        PMASK_NODATA,                           /* 0x1a: SPDU_AA & SPDU_AIA */
        !           134:        PMASK_NOTSUPPORTED,                     /* 0x1b */
        !           135:        PMASK_NOTSUPPORTED,                     /* 0x1c */
        !           136:        PMASK_LINK                              /* 0x1d: SPDU_AR */
        !           137:            | PMASK_ACT_ID
        !           138:            | PMASK_ENCLOSE
        !           139:            | PMASK_SERIAL
        !           140:            | PMASK_UDATA,                      
        !           141:        PMASK_NOTSUPPORTED,                     /* 0x1e */
        !           142:        PMASK_NOTSUPPORTED,                     /* 0x1f */
        !           143:        PMASK_NOTSUPPORTED,                     /* 0x20 */
        !           144:        PMASK_ENCLOSE,                          /* 0x21: SPDU_TD */
        !           145:        PMASK_TOKEN_SET                         /* 0x22: SPDU_RA */
        !           146:            | PMASK_ENCLOSE
        !           147:            | PMASK_SERIAL      
        !           148:            | PMASK_UDATA,
        !           149:        PMASK_NOTSUPPORTED,                     /* 0x23 */
        !           150:        PMASK_NOTSUPPORTED,                     /* 0x24 */
        !           151:        PMASK_NOTSUPPORTED,                     /* 0x25 */
        !           152:        PMASK_NOTSUPPORTED,                     /* 0x26 */
        !           153:        PMASK_NOTSUPPORTED,                     /* 0x27 */
        !           154:        PMASK_NOTSUPPORTED,                     /* 0x28 */
        !           155:        PMASK_SYNC                              /* 0x29: SPDU_MAP & SPDU_AE */
        !           156:            | PMASK_ENCLOSE
        !           157:            | PMASK_SERIAL      
        !           158:            | PMASK_UDATA,
        !           159:        PMASK_ENCLOSE                           /* 0x2a: SPDU_MAA & SPDU_AEA */
        !           160:            | PMASK_SERIAL
        !           161:            | PMASK_UDATA,
        !           162:        PMASK_NOTSUPPORTED,                     /* 0x2b */
        !           163:        PMASK_NOTSUPPORTED,                     /* 0x2c */
        !           164:        PMASK_ENCLOSE                           /* 0x2d: SPDU_AS */
        !           165:            | PMASK_ACT_ID
        !           166:            | PMASK_UDATA,
        !           167:        PMASK_NOTSUPPORTED,                     /* 0x2e */
        !           168:        PMASK_NOTSUPPORTED,                     /* 0x2f */
        !           169:        PMASK_ENCLOSE                           /* 0x30: SPDU_ED */
        !           170:            | PMASK_REASON                              
        !           171:            | PMASK_UDATA,
        !           172:        PMASK_SYNC                              /* 0x31: SPDU_MIP */
        !           173:            | PMASK_ENCLOSE     
        !           174:            | PMASK_SERIAL      
        !           175:            | PMASK_UDATA,                      
        !           176:        PMASK_ENCLOSE                           /* 0x32: SPDU_MIA */
        !           177:            | PMASK_SERIAL                              
        !           178:            | PMASK_MIA_DATA,
        !           179:        PMASK_NOTSUPPORTED,                     /* 0x33 */
        !           180:        PMASK_NOTSUPPORTED,                     /* 0x34 */
        !           181:        PMASK_TOKEN_SET                         /* 0x35: SPDU_RS */
        !           182:            | PMASK_ENCLOSE     
        !           183:            | PMASK_RESYNC      
        !           184:            | PMASK_SERIAL
        !           185:            | PMASK_UDATA,
        !           186:        PMASK_NOTSUPPORTED,                     /* 0x36 */
        !           187:        PMASK_NOTSUPPORTED,                     /* 0x37 */
        !           188:        PMASK_NOTSUPPORTED,                     /* 0x38 */
        !           189:        PMASK_REASON,                           /* 0x39: SPDU_AD */
        !           190:        PMASK_NODATA,                           /* 0x3a: SPDU_ADA */
        !           191:        PMASK_NOTSUPPORTED,                     /* 0x3b */
        !           192:        PMASK_NOTSUPPORTED,                     /* 0x3c */
        !           193:        PMASK_ENCLOSE                           /* 0x3d: SPDU_CD */
        !           194:            | PMASK_UDATA,
        !           195:        PMASK_ENCLOSE                           /* 0x3e: SPDU_CDA */
        !           196:            | PMASK_UDATA
        !           197: };
        !           198: #define        SI_TABLE_LEN            ((sizeof si_table) / (sizeof si_table[0]))
        !           199: 
        !           200: /*  */
        !           201: 
        !           202: #define        PGI_CN_ID               1
        !           203: #define                PI_CALLED_SS    9
        !           204: #define                PI_CALLING_SS   10
        !           205: #define                PI_COMMON_REF   11
        !           206: #define                PI_ADD_INFO     12
        !           207: #define        PGI_CN_ITEMS            5
        !           208: #define                PI_PROTOCOL_OPT 19
        !           209: #define                PI_TSDU_MAXSIZ  21
        !           210: #define                PI_VERSION      22
        !           211: #define                PI_ISN          23
        !           212: #define                PI_TOKEN_SET    26
        !           213: #define                PI_ISN2         55
        !           214: #define        PI_SYNC                 15
        !           215: #define        PI_TOKEN                16
        !           216: #define        PI_TDISC                17
        !           217: #define        PI_USER_REQ             20
        !           218: #define        PI_PREPARE              24
        !           219: #define        PI_ENCLOSE              25
        !           220: #define        PI_RESYNC               27
        !           221: #define        PGI_AR_LINK             33
        !           222: #define                PI_AR_CALLED    9
        !           223: #define                PI_AR_CALLING   10
        !           224: #define                PI_AR_COMMON    11
        !           225: #define                PI_AR_ADDT      12
        !           226: #define                PI_AR_OLD       41
        !           227: #define                PI_AR_SERIAL    42
        !           228: #define        PI_ACT_ID               41
        !           229: #define        PI_SERIAL               42
        !           230: #define        PI_MIA_DATA             46
        !           231: #define        PI_REFLECT              49
        !           232: #define        PI_REASON               50
        !           233: #define        PI_SSAP_CALLING         51
        !           234: #define        PI_SSAP_CALLED          52
        !           235: #define        PI_UDATA                193
        !           236: #define        PI_XDATA                194
        !           237: 
        !           238: 
        !           239: static int pi_table[] = {
        !           240:        0,                                      /* 0x00 */
        !           241:        PMASK_VARLEN | PMASK_CN_ID,             /* 0x01: Connection ID */
        !           242:        0, 0, 0,                                /* 0x02-04 */
        !           243:        PMASK_VARLEN | PMASK_CN_ITEMS,          /* 0x05: Connect/Accept Item */
        !           244:        0, 0, 0,                                /* 0x06-08 */
        !           245:        PMASK_VARLEN | PMASK_CN_ID | PMASK_LINK,/* 0x09: Called Session SS */
        !           246:        PMASK_VARLEN | PMASK_CN_ID | PMASK_LINK,/* 0x0a: Calling Session SS */
        !           247:        PMASK_VARLEN | PMASK_CN_ID | PMASK_LINK,/* 0x0b: Common Reference */
        !           248:        PMASK_VARLEN | PMASK_CN_ID | PMASK_LINK,/* 0x0c: Additional Info */
        !           249:        0, 0,                                   /* 0x0d-0e */
        !           250:        PMASK_SYNC,                             /* 0x0f: Sync Type Item */
        !           251:        PMASK_TOKEN,                            /* 0x10: Token Item */
        !           252:        PMASK_TDISC,                            /* 0x11: Transport Disc */
        !           253:        0,                                      /* 0x12 */
        !           254:        PMASK_CN_ITEMS,                         /* 0x13: Protocol Option */
        !           255:        PMASK_USER_REQ,                         /* 0x14: Session User Req */
        !           256:        PMASK_VARLEN | PMASK_CN_ITEMS,          /* 0x15: TSDU Max Size */
        !           257:        PMASK_VERSION,                          /* 0x16: Version Number */
        !           258:        PMASK_VARLEN | PMASK_CN_ITEMS,          /* 0x17: Initial Serial Num */
        !           259:        PMASK_PREPARE,                          /* 0x18: Prepare Type */
        !           260:        PMASK_ENCLOSE,                          /* 0x19: Enclosure Item */
        !           261:        PMASK_CN_ITEMS | PMASK_TOKEN_SET,       /* 0x1a: Token setting item */
        !           262:        PMASK_RESYNC,                           /* 0x1b: Resync type */
        !           263:        0, 0, 0, 0, 0,                          /* 0x1c-20 */
        !           264:        PMASK_VARLEN | PMASK_LINK,              /* 0x21: Activity Link */
        !           265:        0, 0, 0, 0, 0, 0, 0,                    /* 0x22-28 */
        !           266:        PMASK_VARLEN | PMASK_ACT_ID,            /* 0x29: Activity ID */
        !           267:        PMASK_VARLEN | PMASK_SERIAL,            /* 0x2a: Serial Number */
        !           268:        0, 0, 0,                                /* 0x2b-2d */
        !           269:        PMASK_VARLEN | PMASK_MIA_DATA,          /* 0x2e: MIA User Data */
        !           270:        0, 0,                                   /* 0x2f-30 */
        !           271:        PMASK_VARLEN | PMASK_REFLECT,           /* 0x31: Reflect parameter */
        !           272:        PMASK_VARLEN | PMASK_REASON,            /* 0x32: Refusal Reason */
        !           273:        PMASK_VARLEN | PMASK_SSAP_CALLING,      /* 0x33: Calling SSAP ID */
        !           274:        PMASK_VARLEN | PMASK_SSAP_CALLED,       /* 0x34: Called SSAP ID */
        !           275:        0, 0,                                   /* 0x35-36 */
        !           276:        PMASK_VARLEN | PMASK_CN_ITEMS           /* 0x17: 2nd initial s/n */
        !           277: };
        !           278: #define        PI_TABLE_LEN            ((sizeof pi_table) / (sizeof pi_table[0]))
        !           279: 
        !           280: /*  */
        !           281: 
        !           282: static int pi_length[PI_TABLE_LEN] = {
        !           283:        0,                                      /* 0x00 */
        !           284:        SREF_USER_SIZE                          /* 0x01: Connection ID */
        !           285:            + SREF_COMM_SIZE
        !           286:            + SREF_ADDT_SIZE
        !           287:            + 6,
        !           288:        0, 0, 0,                                /* 0x02-04 */
        !           289:        1 + 4 + 1 + 6 + 1 + 10,                 /* 0x05: Connect/Accept Item */
        !           290:        0, 0, 0,                                /* 0x06-08 */
        !           291:        SREF_USER_SIZE,                         /* 0x09: Called Session SS */
        !           292:        SREF_USER_SIZE,                         /* 0x0a: Calling Session SS */
        !           293:        SREF_COMM_SIZE,                         /* 0x0b: Common Reference */
        !           294:        SREF_ADDT_SIZE,                         /* 0x0c: Additional Info */
        !           295:        0, 0,                                   /* 0x0d-0e */
        !           296:        1,                                      /* 0x0f: Sync Type Item */
        !           297:        1,                                      /* 0x10: Token Item */
        !           298:        1,                                      /* 0x11: Transport Disc */
        !           299:        0,                                      /* 0x12 */
        !           300:        1,                                      /* 0x13: Protocol Option */
        !           301:        2,                                      /* 0x14: Session User Req */
        !           302:        4,                                      /* 0x15: TSDU Max Size */
        !           303:        1,                                      /* 0x16: Version Number */
        !           304:        SIZE_CN_ISN,                            /* 0x17: Initial Serial Num */
        !           305:        1,                                      /* 0x18: Prepare Type */
        !           306:        1,                                      /* 0x19: Enclosure Item */
        !           307:        1,                                      /* 0x1a: Token setting item */
        !           308:        1,                                      /* 0x1b: Resync type */
        !           309:        0, 0, 0, 0, 0,                          /* 0x1c-20 */
        !           310:        2 * SREF_USER_SIZE                      /* 0x21: Activity Link */
        !           311:            + SREF_COMM_SIZE
        !           312:            + SREF_ADDT_SIZE
        !           313:            + SID_DATA_SIZE
        !           314:            + SIZE_CN_ISN
        !           315:            + 6 * 2,
        !           316:        0, 0, 0, 0, 0, 0, 0,                    /* 0x22-28 */
        !           317:        SID_DATA_SIZE,                          /* 0x29: Activity ID */
        !           318:        SIZE_CN_ISN,                            /* 0x2a: Serial Number */
        !           319:        0, 0, 0,                                /* 0x2b-2d */
        !           320:        SEGMENT_MAX /* MIA_SIZE */,             /* 0x2e: MIA User Data */
        !           321:        0, 0,                                   /* 0x2f-30 */
        !           322:        SEGMENT_MAX,                            /* 0x31: Reflect parameter */
        !           323:        RF_SIZE,                                /* 0x32: Refusal Reason */
        !           324:        SSSIZE,                                 /* 0x33: Calling SSAP ID */
        !           325:        SSSIZE,                                 /* 0x34: Called SSAP ID */
        !           326:        0, 0,                                   /* 0x35-36 */
        !           327:        SIZE_CN_ISN,                            /* 0x37: 2nd initial s/n */
        !           328: };
        !           329: 
        !           330: /*  */
        !           331: 
        !           332: #define        If_Set(flag)    if (s -> s_mask & (flag))
        !           333: #define If_Reset(flag) if (!(s -> s_mask & (flag)))
        !           334: #define Set(flag)      s -> s_mask |= (flag)
        !           335: #define Reset(flag)    s -> s_mask &= ~(flag)
        !           336: 
        !           337: #define Put_Item(code,value) \
        !           338:        put2spdu((code), pi_length[(code)], (value), &c)
        !           339: 
        !           340: #define Put_Ref(r,code) \
        !           341: { \
        !           342:     start_pgi (PGI_CN_ID, &c); \
        !           343:     if (r.sr_ulen) \
        !           344:        put2spdu (code, (int) r.sr_ulen, r.sr_udata, &c); \
        !           345:     if (r.sr_clen) \
        !           346:        put2spdu (PI_COMMON_REF, (int) r.sr_clen, r.sr_cdata, &c); \
        !           347:     if (r.sr_alen) \
        !           348:        put2spdu (PI_ADD_INFO, (int) r.sr_alen, r.sr_adata, &c); \
        !           349:     end_pgi (&c); \
        !           350: }
        !           351: 
        !           352: #define        Put_SSN(code,ssn) \
        !           353: { \
        !           354:     if ((ssn) > SERIAL_MAX + 1) { \
        !           355:        if (c.len) \
        !           356:            free (c.top); \
        !           357:        s -> s_errno = SC_PROTOCOL; \
        !           358:        return NOTOK; \
        !           359:     } \
        !           360:     (void) sprintf (isn, "%lu", (ssn)); \
        !           361:     put2spdu ((code), strlen (isn), isn, &c); \
        !           362: }
        !           363: 
        !           364: /* this used to check
        !           365: 
        !           366:        if (s -> s_ulen > (csize)) {
        !           367:            if (c.len)
        !           368:                free (c.top);
        !           369:            s -> s_errno = SC_PROTOCOL;
        !           370:            return NOTOK;
        !           371:        }
        !           372: 
        !           373:    but with version 2 session, there's really no point... */
        !           374: 
        !           375: #define Put_UData(csize) \
        !           376: { \
        !           377:     if (s -> s_udata) { \
        !           378:        put2spdu (PI_UDATA, s -> s_ulen, s -> s_udata, &c); \
        !           379:     } \
        !           380: }
        !           381: 
        !           382: #define Put_XData(csize) \
        !           383: { \
        !           384:     if (s -> s_udata) { \
        !           385:        put2spdu (s -> s_ulen > csize ? PI_XDATA : PI_UDATA, s -> s_ulen, \
        !           386:                  s -> s_udata, &c); \
        !           387:     } \
        !           388: }
        !           389: 
        !           390: #define Put_MData(csize) \
        !           391: { \
        !           392:     if (s -> s_udata) { \
        !           393:        put2spdu (PI_MIA_DATA, s -> s_ulen, s -> s_udata, &c); \
        !           394:     } \
        !           395: }
        !           396: 
        !           397: /*  */
        !           398: 
        !           399: static start_spdu (s, c, basesize)
        !           400: struct ssapkt *s;
        !           401: struct local_buf *c;
        !           402: int basesize;
        !           403: {
        !           404:     if (s -> s_udata)
        !           405:        switch (s -> s_code) {
        !           406:            case SPDU_DT:       /* caller responsible for this... */
        !           407:            case SPDU_EX: 
        !           408:            case SPDU_TD: 
        !           409:                break;
        !           410: 
        !           411:            default: 
        !           412:                if (s -> s_ulen)
        !           413:                    basesize += s -> s_ulen + (s -> s_ulen > 254 ? 4 : 2);
        !           414:                break;
        !           415:        }
        !           416: 
        !           417:     switch (s -> s_code) {
        !           418:        case SPDU_CN: 
        !           419:        case SPDU_AC: 
        !           420:            If_Set (SMASK_CN_REF) {
        !           421:                basesize += 2;
        !           422:                if (s -> s_cn_reference.sr_ulen)
        !           423:                    basesize += 2 + s -> s_cn_reference.sr_ulen;
        !           424:                if (s -> s_cn_reference.sr_clen)
        !           425:                    basesize += 2 + s -> s_cn_reference.sr_clen;
        !           426:                if (s -> s_cn_reference.sr_alen)
        !           427:                    basesize += 2 + s -> s_cn_reference.sr_alen;
        !           428:            }
        !           429:            If_Set (SMASK_CN_CALLING)
        !           430:                basesize += s -> s_callinglen + 2;
        !           431:            If_Set (SMASK_CN_CALLED)
        !           432:                basesize += s -> s_calledlen + 2;
        !           433:            break;
        !           434: 
        !           435:        case SPDU_RF: 
        !           436:            If_Set (SMASK_RF_REF) {
        !           437:                basesize += 2;
        !           438:                if (s -> s_rf_reference.sr_ulen)
        !           439:                    basesize += 2 + s -> s_rf_reference.sr_ulen;
        !           440:                if (s -> s_rf_reference.sr_clen)
        !           441:                    basesize += 2 + s -> s_rf_reference.sr_clen;
        !           442:                if (s -> s_rf_reference.sr_alen)
        !           443:                    basesize += 2 + s -> s_rf_reference.sr_alen;
        !           444:            }
        !           445:            break;
        !           446: 
        !           447:        case SPDU_AR: 
        !           448:            basesize += 2;
        !           449:            If_Set (SMASK_AR_REF) {
        !           450:                if (s -> s_ar_reference.sr_ulen)
        !           451:                    basesize += 2 + s -> s_ar_reference.sr_ulen;
        !           452:                if (s -> s_ar_reference.sr_clen)
        !           453:                    basesize += 2 + s -> s_ar_reference.sr_clen;
        !           454:                if (s -> s_ar_reference.sr_alen)
        !           455:                    basesize += 2 + s -> s_ar_reference.sr_alen;
        !           456:                if (s -> s_ar_reference.sr_vlen)
        !           457:                    basesize += 2 + s -> s_ar_reference.sr_vlen;
        !           458:            }
        !           459:            break;
        !           460:     }
        !           461: 
        !           462:     if (basesize < 254)
        !           463:        basesize = 254;
        !           464:     c -> li = c -> pgi = 0;
        !           465:     c -> len = basesize + ((basesize > 254) ? 4 : 2);
        !           466:     if ((c -> top = malloc ((unsigned) c -> len)) == NULL) {
        !           467:        c -> len = 0;
        !           468:        s -> s_errno = SC_CONGEST;
        !           469:     }
        !           470:     else
        !           471:        s -> s_errno = SC_ACCEPT;
        !           472:     if ((c -> allocli = c -> left = basesize) > 254)
        !           473:        c -> ptr = c -> top + 4;
        !           474:     else
        !           475:        c -> ptr = c -> top + 2;
        !           476: }
        !           477: 
        !           478: /*  */
        !           479: 
        !           480: static int end_spdu (code, c)
        !           481: unsigned char code;
        !           482: struct local_buf *c;
        !           483: {
        !           484:     if (c -> len) {
        !           485:        if (c -> allocli > 254) {
        !           486:            if (c -> li < 255) {
        !           487:                bcopy ((c -> top + 2), c -> top, (c -> len - c -> left));
        !           488:                *(c -> top + 1) = c -> li;
        !           489:                c -> len = c -> li + 2;
        !           490:            }
        !           491:            else {
        !           492:                *(c -> top + 1) = 255;
        !           493:                *(c -> top + 2) = (c -> li >> 8) & 0xff;
        !           494:                *(c -> top + 3) = c -> li & 0xff;
        !           495:                c -> len = c -> li + 4;
        !           496:            }
        !           497:        }
        !           498:        else {
        !           499:            *(c -> top + 1) = c -> li;
        !           500:            c -> len = c -> ptr - c -> top;
        !           501:        }
        !           502:        *c -> top = code;
        !           503:        return OK;
        !           504:     }
        !           505: 
        !           506:     return NOTOK;
        !           507: }
        !           508: 
        !           509: /*  */
        !           510: 
        !           511: static start_pgi (code, c)
        !           512: unsigned char code;
        !           513: struct local_buf *c;
        !           514: {
        !           515:     put2spdu ((int) code, 0, NULLCP, c);
        !           516:     if (c -> len)
        !           517:        c -> pgi = (c -> ptr - c -> top - 1);
        !           518: }
        !           519: 
        !           520: 
        !           521: static end_pgi (c)
        !           522: struct local_buf *c;
        !           523: {
        !           524:     if (c -> len)
        !           525:        *(c -> top + c -> pgi) = (c -> len - c -> left) - (c -> pgi + 1);
        !           526: }
        !           527: 
        !           528: /*  */
        !           529: 
        !           530: static put2spdu (code, li, value, c)
        !           531: int code;
        !           532: int li;
        !           533: char *value;
        !           534: struct local_buf *c;
        !           535: {
        !           536:     int     cl = li;
        !           537:     char   *p1,
        !           538:            *p2;
        !           539: 
        !           540:     if (c -> len) {
        !           541:        cl += (li < 255) ? 2 : 4;
        !           542:        if (c -> left >= cl)
        !           543:            c -> left -= cl;
        !           544:        else {
        !           545: /* XXX:        this clause of Dwight's is all WRONG, WRONG, WRONG.  I think we
        !           546:        should make start_spdu() smarter, if necessary and change this to
        !           547: 
        !           548:        c -> len = 0;
        !           549:        return;
        !           550: */
        !           551:        char   *cp;
        !           552: 
        !           553:            if (c -> allocli < 255)
        !           554:                cl += 2;
        !           555:            cp = realloc (c -> top, (unsigned) (c -> len += cl));
        !           556:            if (cp == NULL) {
        !           557:                c -> len = 0;
        !           558:                return;
        !           559:            }
        !           560:            c -> ptr = (c -> top = cp) + (c -> len - c -> left);
        !           561:            if (c -> allocli < 255) {
        !           562:                c -> allocli += cl;
        !           563:                cl = c -> len - c -> left + 2;
        !           564:                for (p1 = c -> ptr, p2 = p1 + 2; cl; cl--)
        !           565:                    *p2-- = *p1--;
        !           566:                c -> pgi += 2;
        !           567:                c -> left -= 2;
        !           568:            }
        !           569:        }
        !           570:        *c -> ptr++ = code & 0xff;
        !           571:        if (li < 255) {
        !           572:            *c -> ptr++ = li;
        !           573:            c -> li += 2 + li;
        !           574:        }
        !           575:        else {
        !           576:            *c -> ptr++ = 255;
        !           577:            *c -> ptr++ = (li >> 8) & 0xff;
        !           578:            *c -> ptr++ = li & 0xff;
        !           579:            c -> li += 4 + li;
        !           580:        }
        !           581: 
        !           582:        bcopy (value, c -> ptr, li);
        !           583:        c -> ptr += li;
        !           584:     }
        !           585: }
        !           586: 
        !           587: /*  */
        !           588: 
        !           589: int    spkt2tsdu (s, base, len)
        !           590: register struct ssapkt *s;
        !           591: char  **base;
        !           592: int    *len;
        !           593: {
        !           594:     struct local_buf    c;
        !           595:     char    isn[SIZE_CN_ISN + 1];
        !           596: 
        !           597:     c.len = 0;
        !           598:     switch (s -> s_code) {
        !           599:        case SPDU_CN: 
        !           600:            start_spdu (s, &c, CN_BASE_SIZE);
        !           601:            If_Set (SMASK_CN_REF)
        !           602:                Put_Ref (s -> s_cn_reference, PI_CALLING_SS);
        !           603:            If_Set (SMASK_CN_OPT | SMASK_CN_TSDU | SMASK_CN_VRSN | SMASK_CN_ISN
        !           604:                    | SMASK_CN_SET) {
        !           605:                start_pgi (PGI_CN_ITEMS, &c);
        !           606:                If_Set (SMASK_CN_OPT)
        !           607:                    Put_Item (PI_PROTOCOL_OPT, (char *) &s -> s_options);
        !           608:                If_Set (SMASK_CN_TSDU) {
        !           609:                    u_long tsdu_maxsize = (s -> s_tsdu_init & 0xffff) << 16
        !           610:                        | s -> s_tsdu_resp & 0xffff;
        !           611:                    tsdu_maxsize = htonl (tsdu_maxsize);
        !           612:                    Put_Item (PI_TSDU_MAXSIZ, (char *) &tsdu_maxsize);
        !           613:                }
        !           614:                If_Set (SMASK_CN_VRSN)
        !           615:                    Put_Item (PI_VERSION, (char *) &s -> s_cn_version);
        !           616:                If_Set (SMASK_CN_ISN)
        !           617:                    Put_SSN (PI_ISN, s -> s_isn);
        !           618:                If_Set (SMASK_CN_SET)
        !           619:                    Put_Item (PI_TOKEN_SET, (char *) &s -> s_settings);
        !           620:                end_pgi (&c);
        !           621:            }
        !           622:            If_Set (SMASK_CN_REQ) {
        !           623:                u_short requirements = htons (s -> s_cn_require);
        !           624:                Put_Item (PI_USER_REQ, (char *) &requirements);
        !           625:            }
        !           626:            If_Set (SMASK_CN_CALLING)
        !           627:                put2spdu (PI_SSAP_CALLING, s -> s_callinglen, 
        !           628:                            s -> s_calling, &c);
        !           629:            If_Set (SMASK_CN_CALLED)
        !           630:                put2spdu (PI_SSAP_CALLED, s -> s_calledlen, 
        !           631:                            s -> s_called, &c);
        !           632:            Put_XData (CN_SIZE);
        !           633:            break;
        !           634: 
        !           635:        case SPDU_AC: 
        !           636:            start_spdu (s, &c, AC_BASE_SIZE);
        !           637:            If_Set (SMASK_CN_REF)
        !           638:                Put_Ref (s -> s_cn_reference, PI_CALLED_SS);
        !           639:            If_Set (SMASK_CN_OPT | SMASK_CN_TSDU | SMASK_CN_VRSN | SMASK_CN_ISN
        !           640:                    | SMASK_CN_SET) {
        !           641:                start_pgi (PGI_CN_ITEMS, &c);
        !           642:                If_Set (SMASK_CN_OPT)
        !           643:                    Put_Item (PI_PROTOCOL_OPT, (char *) &s -> s_options);
        !           644:                If_Set (SMASK_CN_TSDU) {
        !           645:                    u_long tsdu_maxsize = (s -> s_tsdu_init & 0xffff) << 16
        !           646:                        | s -> s_tsdu_resp & 0xffff;
        !           647:                    tsdu_maxsize = htonl (tsdu_maxsize);
        !           648:                    Put_Item (PI_TSDU_MAXSIZ, (char *) &tsdu_maxsize);
        !           649:                }
        !           650:                If_Set (SMASK_CN_VRSN)
        !           651:                    Put_Item (PI_VERSION, (char *) &s -> s_cn_version);
        !           652:                If_Set (SMASK_CN_ISN)
        !           653:                    Put_SSN (PI_ISN, s -> s_isn);
        !           654:                If_Set (SMASK_CN_SET)
        !           655:                    Put_Item (PI_TOKEN_SET, (char *) &s -> s_settings);
        !           656:                end_pgi (&c);
        !           657:            }
        !           658:            If_Set (SMASK_AC_TOKEN)
        !           659:                Put_Item (PI_TOKEN, (char *) &s -> s_ac_token);
        !           660:            If_Set (SMASK_CN_REQ) {
        !           661:                u_short requirements = htons (s -> s_cn_require);
        !           662:                Put_Item (PI_USER_REQ, (char *) &requirements);
        !           663:            }
        !           664:            If_Set (SMASK_CN_CALLING)
        !           665:                put2spdu (PI_SSAP_CALLING, s -> s_callinglen,
        !           666:                            s -> s_calling, &c);
        !           667:            If_Set (SMASK_CN_CALLED)
        !           668:                put2spdu (PI_SSAP_CALLED, s -> s_calledlen, 
        !           669:                            s -> s_called, &c);
        !           670:            If_Set (SMASK_ENCLOSE)
        !           671:                Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
        !           672:            Put_UData (AC_SIZE);
        !           673:            break;
        !           674: 
        !           675:        case SPDU_RF: 
        !           676:            start_spdu (s, &c, RF_BASE_SIZE);
        !           677:            If_Set (SMASK_RF_REF)
        !           678:                Put_Ref (s -> s_rf_reference, PI_CALLED_SS);
        !           679:            If_Set (SMASK_RF_DISC)
        !           680:                Put_Item (PI_TDISC, (char *) &s -> s_rf_disconnect);
        !           681:            If_Set (SMASK_RF_REQ) {
        !           682:                u_short requirements = htons (s -> s_rf_require);
        !           683:                Put_Item (PI_USER_REQ, (char *) &requirements);
        !           684:            }
        !           685:            If_Set (SMASK_RF_VRSN)
        !           686:                Put_Item (PI_VERSION, (char *) &s -> s_rf_version);
        !           687:            if (s -> s_rlen > RF_SIZE) {
        !           688:                if (c.len)
        !           689:                    free (c.top);
        !           690:                s -> s_errno = SC_PROTOCOL;
        !           691:                return NOTOK;
        !           692:            }
        !           693:            If_Set (SMASK_ENCLOSE)
        !           694:                Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
        !           695:            if (s -> s_rlen > 0)
        !           696:                put2spdu (PI_REASON, s -> s_rlen, s -> s_rdata, &c);
        !           697:            break;
        !           698: 
        !           699:        case SPDU_FN: 
        !           700:            start_spdu (s, &c, FN_BASE_SIZE);
        !           701:            If_Set (SMASK_FN_DISC)
        !           702:                Put_Item (PI_TDISC, (char *) &s -> s_fn_disconnect);
        !           703:            If_Set (SMASK_ENCLOSE)
        !           704:                Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
        !           705:            Put_UData (FN_SIZE);
        !           706:            break;
        !           707: 
        !           708:        case SPDU_DN: 
        !           709:            start_spdu (s, &c, DN_BASE_SIZE);
        !           710:            If_Set (SMASK_ENCLOSE)
        !           711:                Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
        !           712:            Put_UData (DN_SIZE);
        !           713:            break;
        !           714: 
        !           715:        case SPDU_NF: 
        !           716:            start_spdu (s, &c, NF_BASE_SIZE);
        !           717:            If_Set (SMASK_ENCLOSE)
        !           718:                Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
        !           719:            Put_UData (NF_SIZE);
        !           720:            break;
        !           721: 
        !           722:        case SPDU_AB: 
        !           723: #ifdef notdef
        !           724:        case SPDU_AI:           /* aka SPDU_AB */
        !           725: #endif
        !           726:            If_Set (SMASK_SPDU_AB) {
        !           727:                start_spdu (s, &c, AB_BASE_SIZE);
        !           728:                If_Reset (SMASK_AB_DISC) {
        !           729:                    s -> s_errno = SC_PROTOCOL;
        !           730:                    break;
        !           731:                }
        !           732:                Put_Item (PI_TDISC, (char *) &s -> s_ab_disconnect);
        !           733:                If_Set (SMASK_AB_REFL)
        !           734:                    put2spdu (PI_REFLECT, AB_REFL_SIZE,
        !           735:                                (char *) s -> s_reflect, &c);
        !           736:                If_Set (SMASK_ENCLOSE)
        !           737:                    Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
        !           738:                Put_UData (AB_SIZE);
        !           739:                break;
        !           740:            }
        !           741:            start_spdu (s, &c, AI_BASE_SIZE);
        !           742:            If_Set (SMASK_AI_REASON)
        !           743:                put2spdu (PI_REASON, 1, (char *) &s -> s_ai_reason, &c);
        !           744:            break;
        !           745: 
        !           746:        case SPDU_AA: 
        !           747: #ifdef notdef
        !           748:        case SPDU_AIA:          /* aka SPDU_AA */
        !           749: #endif
        !           750:            If_Set (SMASK_SPDU_AA) {
        !           751:                start_spdu (s, &c, AA_BASE_SIZE);
        !           752:                break;
        !           753:            }
        !           754:            start_spdu (s, &c, AIA_BASE_SIZE);
        !           755:            break;
        !           756: 
        !           757:        case SPDU_GT:
        !           758: #ifdef notdef
        !           759:        case SPDU_DT:           /* aka SPDU_GT */
        !           760: #endif
        !           761:            If_Set (SMASK_SPDU_GT) {
        !           762:                start_spdu (s, &c, GT_BASE_SIZE);
        !           763:                If_Set (SMASK_GT_TOKEN)
        !           764:                    Put_Item (PI_TOKEN, (char *) &s -> s_gt_token);
        !           765:                break;
        !           766:            }                   /* else fall */
        !           767:            start_spdu (s, &c, DT_BASE_SIZE);
        !           768:            If_Set (SMASK_ENCLOSE)
        !           769:                Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
        !           770: /* NB: caller responsible for mapping s -> s_udata to user info */
        !           771:            break;
        !           772: 
        !           773:        case SPDU_TD: 
        !           774:            start_spdu (s, &c, TD_BASE_SIZE);
        !           775:            If_Set (SMASK_ENCLOSE)
        !           776:                Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
        !           777: /* NB: caller responsible for mapping s -> s_udata to user info */
        !           778:            break;
        !           779: 
        !           780:        case SPDU_EX: 
        !           781:            start_spdu (s, &c, EX_BASE_SIZE);
        !           782: /* NB: caller responsible for mapping s -> s_udata to user info */
        !           783:            break;
        !           784: 
        !           785:        case SPDU_CD: 
        !           786:            start_spdu (s, &c, CD_BASE_SIZE);
        !           787:            If_Set (SMASK_ENCLOSE)
        !           788:                Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
        !           789:            Put_UData (CD_SIZE);
        !           790:            break;
        !           791: 
        !           792:        case SPDU_CDA: 
        !           793:            start_spdu (s, &c, CDA_BASE_SIZE);
        !           794:            If_Set (SMASK_ENCLOSE)
        !           795:                Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
        !           796:            Put_UData (CDA_SIZE);
        !           797:            break;
        !           798: 
        !           799:        case SPDU_PT: 
        !           800:            start_spdu (s, &c, PT_BASE_SIZE);
        !           801:            If_Set (SMASK_PT_TOKEN)
        !           802:                Put_Item (PI_TOKEN, (char *) &s -> s_pt_token);
        !           803:            If_Set (SMASK_ENCLOSE)
        !           804:                Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
        !           805:            Put_UData (PT_SIZE);
        !           806:            break;
        !           807: 
        !           808:        case SPDU_GTC: 
        !           809:            start_spdu (s, &c, GTC_BASE_SIZE);
        !           810:            break;
        !           811: 
        !           812:        case SPDU_GTA: 
        !           813:            start_spdu (s, &c, GTA_BASE_SIZE);
        !           814:            break;
        !           815: 
        !           816:        case SPDU_MIP: 
        !           817:            start_spdu (s, &c, MIP_BASE_SIZE);
        !           818:            If_Set (SMASK_MIP_SYNC)
        !           819:                Put_Item (PI_SYNC, (char *) &s -> s_mip_sync);
        !           820:            If_Reset (SMASK_MIP_SERIAL) {
        !           821:                s -> s_errno = SC_PROTOCOL;
        !           822:                break;
        !           823:            }
        !           824:            Put_SSN (PI_SERIAL, s -> s_mip_serial);
        !           825:            If_Set (SMASK_ENCLOSE)
        !           826:                Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
        !           827:            Put_UData (MIP_SIZE);
        !           828:            break;
        !           829: 
        !           830:        case SPDU_MAP: 
        !           831: #ifdef notdef
        !           832:        case SPDU_AE:           /* aka SPDU_MAP */
        !           833: #endif
        !           834:            If_Set (SMASK_MAP_SYNC) {
        !           835:                start_spdu (s, &c, MAP_BASE_SIZE);
        !           836:                Put_Item (PI_SYNC, (char *) &s -> s_map_sync);
        !           837:            }
        !           838:            else
        !           839:                start_spdu (s, &c, AE_BASE_SIZE);
        !           840:            If_Reset (SMASK_MAP_SERIAL) {
        !           841:                s -> s_errno = SC_PROTOCOL;
        !           842:                break;
        !           843:            }
        !           844:            Put_SSN (PI_SERIAL, s -> s_map_serial);
        !           845:            If_Set (SMASK_ENCLOSE)
        !           846:                Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
        !           847:            Put_UData (MAP_SIZE);
        !           848:            break;
        !           849: 
        !           850:        case SPDU_MIA: 
        !           851:            start_spdu (s, &c, MIA_BASE_SIZE);
        !           852:            If_Reset (SMASK_MIA_SERIAL) {
        !           853:                s -> s_errno = SC_PROTOCOL;
        !           854:                break;
        !           855:            }
        !           856:            Put_SSN (PI_SERIAL, s -> s_mia_serial);
        !           857:            If_Set (SMASK_ENCLOSE)
        !           858:                Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
        !           859:            Put_MData (MIA_SIZE);
        !           860:            break;
        !           861: 
        !           862:        case SPDU_MAA: 
        !           863: #ifdef notdef
        !           864:        case SPDU_AEA:          /* aka SPDU_MAA */
        !           865: #endif
        !           866:            start_spdu (s, &c, MAA_BASE_SIZE);
        !           867:            If_Reset (SMASK_MAA_SERIAL) {
        !           868:                s -> s_errno = SC_PROTOCOL;
        !           869:                break;
        !           870:            }
        !           871:            Put_SSN (PI_SERIAL, s -> s_maa_serial);
        !           872:            If_Set (SMASK_ENCLOSE)
        !           873:                Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
        !           874:            Put_UData (MAA_SIZE);
        !           875:            break;
        !           876: 
        !           877:        case SPDU_RS:
        !           878:            start_spdu (s, &c, RS_BASE_SIZE);
        !           879:            If_Set (SMASK_RS_SET)
        !           880:                Put_Item (PI_TOKEN_SET, (char *) &s -> s_rs_settings);
        !           881:            If_Reset (SMASK_RS_TYPE) {
        !           882:                s -> s_errno = SC_PROTOCOL;
        !           883:                break;
        !           884:            }
        !           885:            Put_Item (PI_RESYNC, (char *) &s -> s_rs_type);
        !           886:            If_Reset (SMASK_RS_SSN) {
        !           887:                s -> s_errno = SC_PROTOCOL;
        !           888:                break;
        !           889:            }
        !           890:            Put_SSN (PI_SERIAL, s -> s_rs_serial);
        !           891:            If_Set (SMASK_ENCLOSE)
        !           892:                Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
        !           893:            Put_UData (RS_SIZE);
        !           894:            break;
        !           895: 
        !           896:        case SPDU_RA:
        !           897:            start_spdu (s, &c, RA_BASE_SIZE);
        !           898:            If_Set (SMASK_RA_SET)
        !           899:                Put_Item (PI_TOKEN_SET, (char *) &s -> s_ra_settings);
        !           900:            If_Reset (SMASK_RA_SSN) {
        !           901:                s -> s_errno = SC_PROTOCOL;
        !           902:                break;
        !           903:            }
        !           904:            Put_SSN (PI_SERIAL, s -> s_ra_serial);
        !           905:            If_Set (SMASK_ENCLOSE)
        !           906:                Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
        !           907:            Put_UData (RA_SIZE);
        !           908:            break;
        !           909: 
        !           910:        case SPDU_PR: 
        !           911:            start_spdu (s, &c, PR_BASE_SIZE);
        !           912:            If_Reset (SMASK_PR_TYPE) {
        !           913:                s -> s_errno = SC_PROTOCOL;
        !           914:                break;
        !           915:            }
        !           916:            Put_Item (PI_PREPARE, (char *) &s -> s_pr_type);
        !           917:            break;
        !           918: 
        !           919:        case SPDU_ER:           /* we don't do these! */
        !           920:            s -> s_errno = SC_PROTOCOL;
        !           921:            break;
        !           922: 
        !           923:        case SPDU_ED: 
        !           924:            start_spdu (s, &c, ED_BASE_SIZE);
        !           925:            If_Reset (SMASK_ED_REASON) {
        !           926:                s -> s_errno = SC_PROTOCOL;
        !           927:                break;
        !           928:            }
        !           929:            put2spdu (PI_REASON, 1, (char *) &s -> s_ed_reason, &c);
        !           930:            If_Set (SMASK_ENCLOSE)
        !           931:                Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
        !           932:            Put_UData (ED_SIZE);
        !           933:            break;
        !           934: 
        !           935:        case SPDU_AS: 
        !           936:            start_spdu (s, &c, AS_BASE_SIZE);
        !           937:            If_Reset (SMASK_AS_ID) {
        !           938:                s -> s_errno = SC_PROTOCOL;
        !           939:                break;
        !           940:            }
        !           941:            put2spdu (PI_ACT_ID, (int) s -> s_as_id.sd_len,
        !           942:                s -> s_as_id.sd_data, &c);
        !           943:            If_Set (SMASK_ENCLOSE)
        !           944:                Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
        !           945:            Put_UData (AS_SIZE);
        !           946:            break;
        !           947: 
        !           948:        case SPDU_AR:
        !           949:            start_spdu (s, &c, AR_BASE_SIZE);
        !           950:            start_pgi (PGI_AR_LINK, &c);
        !           951:            If_Set (SMASK_AR_REF) {
        !           952:                if (s -> s_ar_reference.sr_called_len)
        !           953:                    put2spdu (PI_AR_CALLED,
        !           954:                            (int) s -> s_ar_reference.sr_called_len,
        !           955:                            s -> s_ar_reference.sr_called, &c);
        !           956:                if (s -> s_ar_reference.sr_calling_len)
        !           957:                    put2spdu (PI_AR_CALLING,
        !           958:                            (int) s -> s_ar_reference.sr_calling_len,
        !           959:                            s -> s_ar_reference.sr_calling, &c);
        !           960:                if (s -> s_ar_reference.sr_clen)
        !           961:                    put2spdu (PI_AR_COMMON, (int) s -> s_ar_reference.sr_clen,
        !           962:                            s -> s_ar_reference.sr_cdata, &c);
        !           963:                if (s -> s_ar_reference.sr_alen)
        !           964:                    put2spdu (PI_AR_ADDT, (int) s -> s_ar_reference.sr_alen,
        !           965:                            s -> s_ar_reference.sr_adata, &c);
        !           966:            }
        !           967:            If_Reset (SMASK_AR_OID) {
        !           968:                s -> s_errno = SC_PROTOCOL;
        !           969:                break;
        !           970:            }
        !           971:            put2spdu (PI_ACT_ID, (int) s -> s_ar_oid.sd_len,
        !           972:                    s -> s_ar_oid.sd_data, &c);
        !           973:            If_Reset (SMASK_AR_SSN) {
        !           974:                s -> s_errno = SC_PROTOCOL;
        !           975:                break;
        !           976:            }
        !           977:            Put_SSN (PI_SERIAL, s -> s_ar_serial);
        !           978:            end_pgi (&c);           
        !           979:            If_Reset (SMASK_AR_ID) {
        !           980:                s -> s_errno = SC_PROTOCOL;
        !           981:                break;
        !           982:            }
        !           983:            put2spdu (PI_ACT_ID, (int) s -> s_ar_id.sd_len,
        !           984:                s -> s_ar_id.sd_data, &c);
        !           985:            If_Set (SMASK_ENCLOSE)
        !           986:                Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
        !           987:            Put_UData (AR_SIZE);
        !           988:            break;
        !           989: 
        !           990:        case SPDU_AD: 
        !           991:            start_spdu (s, &c, AD_BASE_SIZE);
        !           992:            If_Set (SMASK_AD_REASON) 
        !           993:                put2spdu (PI_REASON, 1, (char *) &s -> s_ad_reason, &c);
        !           994:            break;
        !           995: 
        !           996:        case SPDU_ADA: 
        !           997:            start_spdu (s, &c, ADA_BASE_SIZE);
        !           998:            break;
        !           999: 
        !          1000:        default: 
        !          1001:            s -> s_errno = SC_PROTOCOL;
        !          1002:            break;
        !          1003:     }
        !          1004: 
        !          1005:     if ((end_spdu (s -> s_code, &c) == NOTOK) || (s -> s_errno != SC_ACCEPT)) {
        !          1006:        if (s -> s_errno == SC_ACCEPT)
        !          1007:            s -> s_errno = SC_CONGEST;
        !          1008:        if (c.len) {
        !          1009:            free (c.top);
        !          1010:            c.len = 0;
        !          1011:        }
        !          1012:        *base = NULL;
        !          1013:        *len = 0;
        !          1014:     }
        !          1015:     else {
        !          1016:        *base = c.top;
        !          1017:        *len = c.len;
        !          1018:        s -> s_li = c.li;
        !          1019:     }
        !          1020: 
        !          1021: #ifdef DEBUG
        !          1022:     if (ssap_log -> ll_events & LLOG_PDUS)
        !          1023:        spkt2text (ssap_log, s, 0);
        !          1024: #endif
        !          1025: 
        !          1026:     return c.len ? OK : NOTOK;
        !          1027: }
        !          1028: 
        !          1029: /*  */
        !          1030: 
        !          1031: static u_long str2ssn (s, n)
        !          1032: register char  *s;
        !          1033: register int   n;
        !          1034: {
        !          1035:     register u_long u;
        !          1036: 
        !          1037:     for (u = 0L; n > 0; n--)
        !          1038:        u = u * 10 + *s++ - '0';
        !          1039: 
        !          1040:     return u;
        !          1041: }
        !          1042: 
        !          1043: /*  */
        !          1044: 
        !          1045: /* this is used to pull PCI, not user data... */
        !          1046: 
        !          1047: #define        advance(n) \
        !          1048:     if (base >= xbase) { \
        !          1049:        if ((base = pullqb (qb, (n))) == NULL) { \
        !          1050:            s -> s_errno = SC_PROTOCOL; \
        !          1051:            break; \
        !          1052:        } \
        !          1053:        xbase = base + (n); \
        !          1054:        nread += (n); \
        !          1055:     } \
        !          1056:     else
        !          1057: 
        !          1058: static char *pullqb (qb, n)
        !          1059: struct qbuf *qb;
        !          1060: int    n;
        !          1061: {
        !          1062:     register int    i;
        !          1063:     int            once;
        !          1064:     register char  *cp;
        !          1065:     register struct qbuf *qp;
        !          1066:     static char *buffer = NULL;
        !          1067: 
        !          1068:     if (n > SEGMENT_MAX)
        !          1069:        return NULLCP;
        !          1070: 
        !          1071:     for (once = 1, cp = buffer, qp = NULL; n > 0; once = 0, cp += i, n -= i) {
        !          1072:        if (qp == NULL && (qp = qb -> qb_forw) == qb)
        !          1073:            return NULLCP;
        !          1074: 
        !          1075:        i = min (qp -> qb_len, n);
        !          1076:        if (once && i == n) {   /* special case */
        !          1077:            cp = qp -> qb_data;
        !          1078:            qp -> qb_data += i, qp -> qb_len -= i;
        !          1079:            return cp;
        !          1080:        }
        !          1081: 
        !          1082:        if (buffer == NULL) {
        !          1083:            if ((buffer = malloc ((unsigned) SEGMENT_MAX)) == NULL)
        !          1084:                return NULLCP;
        !          1085:            cp = buffer;
        !          1086:        }
        !          1087:        bcopy (qp -> qb_data, cp, i);
        !          1088: 
        !          1089:        qp -> qb_data += i, qp -> qb_len -= i;
        !          1090:        if (qp -> qb_len <= 0) {
        !          1091:            remque (qp);
        !          1092: 
        !          1093:            free ((char *) qp);
        !          1094:            qp = NULL;
        !          1095:        }
        !          1096:     }
        !          1097: 
        !          1098:     return buffer;
        !          1099: }
        !          1100: 
        !          1101: /*  */
        !          1102: 
        !          1103: struct ssapkt *tsdu2spkt (qb, len, cc)
        !          1104: struct qbuf *qb;
        !          1105: int    len,
        !          1106:        *cc;
        !          1107: {
        !          1108:     register int    li;
        !          1109:     int     cat0,
        !          1110:            nread,
        !          1111:            pktlen,
        !          1112:             pgilen,
        !          1113:            pmask,
        !          1114:            xlen;
        !          1115:     register char *base;
        !          1116:     char   *xbase;
        !          1117:     unsigned char   code,
        !          1118:                     si;
        !          1119:     register struct ssapkt  *s;
        !          1120: 
        !          1121:     if (cc) {
        !          1122:        cat0 = *cc;
        !          1123:        *cc = 0;
        !          1124:     }
        !          1125:     else
        !          1126:        cat0 = 1;
        !          1127:     if ((base = pullqb (qb, nread = 2)) == NULL
        !          1128:            || (s = newspkt ((int) (si = *base++))) == NULL)
        !          1129:        return NULLSPKT;
        !          1130: 
        !          1131:     if (*((u_char *) base) == 255) {
        !          1132:        if ((base = pullqb (qb, 2)) == NULL) {
        !          1133:            s -> s_errno = SC_PROTOCOL;
        !          1134:            return s;
        !          1135:        }
        !          1136:        nread += 2;
        !          1137:        s -> s_li = 
        !          1138:                (*((u_char *) base) << 8) + *((u_char *) (base + 1));
        !          1139:     }
        !          1140:     else
        !          1141:        s -> s_li = *((u_char *) base);
        !          1142:     pgilen = pktlen = s -> s_li;
        !          1143: 
        !          1144:     if (cat0)
        !          1145:        switch (si) {
        !          1146:            case SPDU_GT:
        !          1147:                Set (SMASK_SPDU_GT);
        !          1148:                break;
        !          1149: 
        !          1150:            case SPDU_AB:
        !          1151:                Set (SMASK_SPDU_AB);
        !          1152:                break;
        !          1153: 
        !          1154:            case SPDU_AA:
        !          1155:                Set (SMASK_SPDU_AA);
        !          1156:                break;
        !          1157: 
        !          1158:            default:
        !          1159:                break;
        !          1160:        }
        !          1161: 
        !          1162:     if ((si >= SI_TABLE_LEN)
        !          1163:            || ((pmask = si_table[si]) == PMASK_NOTSUPPORTED)) {
        !          1164:        s -> s_errno = SC_PROTOCOL;
        !          1165:        return s;
        !          1166:     }
        !          1167:     if (len < pktlen + nread) {
        !          1168:        s -> s_errno = SC_PROTOCOL;
        !          1169:        return s;
        !          1170:     }
        !          1171: 
        !          1172:     s -> s_errno = SC_ACCEPT;
        !          1173:     xbase = base;
        !          1174:     while (pktlen && (s -> s_errno == SC_ACCEPT)) {
        !          1175:        advance (2);
        !          1176:        code = *base++;
        !          1177:        if (*((u_char *) base) == 255) {
        !          1178:            base++;
        !          1179:            advance (2);
        !          1180:            li = (*((u_char *) base) << 8) + *((u_char *) (base + 1));
        !          1181:            xlen = 2;
        !          1182:        }
        !          1183:        else {
        !          1184:            li = *((u_char *) base);
        !          1185:            xlen = 1;
        !          1186:        }
        !          1187:        base += xlen;
        !          1188:        if (xlen > 1)
        !          1189:            xlen += 2;
        !          1190:        else
        !          1191:            xlen++;
        !          1192:        switch (code) {
        !          1193:            case PI_UDATA:
        !          1194:                if (!(pmask & PMASK_UDATA))
        !          1195:                    s -> s_errno = SC_PROTOCOL;
        !          1196:                break;
        !          1197: 
        !          1198:            case PI_XDATA:
        !          1199:                if (!(pmask & PMASK_XDATA))
        !          1200:                    s -> s_errno = SC_PROTOCOL;
        !          1201:                break;
        !          1202: 
        !          1203:            default:
        !          1204:                if (code >= PI_TABLE_LEN || !(pmask & pi_table[code]))
        !          1205:                    s -> s_errno = SC_PROTOCOL;
        !          1206:                break;
        !          1207:        }
        !          1208:        if (s -> s_errno != SC_ACCEPT)
        !          1209:            break;
        !          1210:        if (!pgilen)
        !          1211:            pgilen = pktlen;
        !          1212:        pktlen -= (xlen + li);
        !          1213:        if (li > (pgilen -= xlen)) {
        !          1214:            s -> s_errno = SC_PROTOCOL;
        !          1215:            break;
        !          1216:        }
        !          1217:        pgilen -= li;
        !          1218:        if (li)
        !          1219:            advance (li);
        !          1220:        if (code < PI_TABLE_LEN) {
        !          1221:            if (li) {
        !          1222:                if (pi_table[code] & PMASK_VARLEN) {
        !          1223:                    if (li > pi_length[code]) {
        !          1224:                        s -> s_errno = SC_PROTOCOL;
        !          1225:                        break;
        !          1226:                    }
        !          1227:                }
        !          1228:                else
        !          1229:                    if (li != pi_length[code]) {
        !          1230:                        s -> s_errno = SC_PROTOCOL;
        !          1231:                        break;
        !          1232:                    }
        !          1233:            }
        !          1234:        }
        !          1235: 
        !          1236:        switch (code) {
        !          1237:            case PGI_AR_LINK:
        !          1238:                Set (SMASK_AR_OID);/* HACK! */
        !          1239:                goto do_pgi;
        !          1240: 
        !          1241:            case PGI_CN_ID: 
        !          1242:                Set (SMASK_CN_REF);/* fall */
        !          1243:            case PGI_CN_ITEMS: 
        !          1244: do_pgi: ;
        !          1245:                pktlen += li;
        !          1246:                pgilen = li;
        !          1247:                li = 0;
        !          1248:                break;
        !          1249: 
        !          1250:            case PI_CALLED_SS: 
        !          1251:            case PI_CALLING_SS: 
        !          1252: #ifdef notdef
        !          1253:            case PI_AR_CALLED:
        !          1254:            case PI_AR_CALLING:
        !          1255: #endif
        !          1256:                switch (si) {
        !          1257:                    case SPDU_CN: 
        !          1258:                    case SPDU_AC: 
        !          1259:                        s -> s_cn_reference.sr_ulen = li;
        !          1260:                        bcopy (base, s -> s_cn_reference.sr_udata, li);
        !          1261:                        Set (SMASK_CN_REF);
        !          1262:                        break;
        !          1263:                    case SPDU_RF: 
        !          1264:                        s -> s_rf_reference.sr_ulen = li;
        !          1265:                        bcopy (base, s -> s_rf_reference.sr_udata, li);
        !          1266:                        Set (SMASK_RF_REF);
        !          1267:                        break;
        !          1268:                    case SPDU_AR:
        !          1269:                        switch (code) {
        !          1270:                            case PI_AR_CALLED:
        !          1271:                                s -> s_ar_reference.sr_called_len = li;
        !          1272:                                bcopy (base, s -> s_ar_reference.sr_called,
        !          1273:                                        li);
        !          1274:                                Set (SMASK_AR_REF);
        !          1275:                                break;                          
        !          1276:                            case PI_AR_CALLING:
        !          1277:                                s -> s_ar_reference.sr_calling_len = li;
        !          1278:                                bcopy (base, s -> s_ar_reference.sr_calling,
        !          1279:                                        li);
        !          1280:                                Set (SMASK_AR_REF);
        !          1281:                                break;
        !          1282:                            default:
        !          1283:                                s -> s_errno = SC_PROTOCOL;
        !          1284:                                break;
        !          1285:                        }
        !          1286:                        break;
        !          1287:                    default: 
        !          1288:                        s -> s_errno = SC_PROTOCOL;
        !          1289:                        break;
        !          1290:                }
        !          1291:                base += li;
        !          1292:                break;
        !          1293: 
        !          1294:            case PI_COMMON_REF: 
        !          1295: #ifdef notdef
        !          1296:            case PI_AR_COMMON:
        !          1297: #endif
        !          1298:                switch (si) {
        !          1299:                    case SPDU_CN: 
        !          1300:                    case SPDU_AC: 
        !          1301:                        s -> s_cn_reference.sr_clen = li;
        !          1302:                        bcopy (base, s -> s_cn_reference.sr_cdata, li);
        !          1303:                        Set (SMASK_CN_REF);
        !          1304:                        break;
        !          1305:                    case SPDU_RF: 
        !          1306:                        s -> s_rf_reference.sr_clen = li;
        !          1307:                        bcopy (base, s -> s_rf_reference.sr_cdata, li);
        !          1308:                        Set (SMASK_RF_REF);
        !          1309:                        break;
        !          1310:                    case SPDU_AR:
        !          1311:                        s -> s_ar_reference.sr_clen = li;
        !          1312:                        bcopy (base, s -> s_ar_reference.sr_cdata, li);
        !          1313:                        Set (SMASK_AR_REF);
        !          1314:                        break;
        !          1315:                    default: 
        !          1316:                        s -> s_errno = SC_PROTOCOL;
        !          1317:                        break;
        !          1318:                }
        !          1319:                base += li;
        !          1320:                break;
        !          1321: 
        !          1322:            case PI_ADD_INFO: 
        !          1323: #ifdef notdef
        !          1324:            case PI_AR_ADDT:
        !          1325: #endif
        !          1326:                switch (si) {
        !          1327:                    case SPDU_CN: 
        !          1328:                    case SPDU_AC: 
        !          1329:                        s -> s_cn_reference.sr_alen = li;
        !          1330:                        bcopy (base, s -> s_cn_reference.sr_adata, li);
        !          1331:                        Set (SMASK_CN_REF);
        !          1332:                        break;
        !          1333:                    case SPDU_RF: 
        !          1334:                        s -> s_rf_reference.sr_alen = li;
        !          1335:                        bcopy (base, s -> s_rf_reference.sr_adata, li);
        !          1336:                        Set (SMASK_RF_REF);
        !          1337:                        break;
        !          1338:                    case SPDU_AR:
        !          1339:                        s -> s_ar_reference.sr_alen = li;
        !          1340:                        bcopy (base, s -> s_ar_reference.sr_adata, li);
        !          1341:                        Set (SMASK_AR_REF);
        !          1342:                        break;
        !          1343:                    default: 
        !          1344:                        s -> s_errno = SC_PROTOCOL;
        !          1345:                        break;
        !          1346:                }
        !          1347:                base += li;
        !          1348:                break;
        !          1349: 
        !          1350:            case PI_PROTOCOL_OPT: 
        !          1351:                if ((s -> s_options = *base++) & ~CR_OPT_MASK)
        !          1352:                    s -> s_errno = SC_PROTOCOL;
        !          1353:                else
        !          1354:                    Set (SMASK_CN_OPT);
        !          1355:                break;
        !          1356: 
        !          1357:            case PI_TSDU_MAXSIZ: 
        !          1358:                {
        !          1359:                    u_long tsdu_maxsize;
        !          1360:                    bcopy (base, (char *) &tsdu_maxsize,
        !          1361:                            pi_length[PI_TSDU_MAXSIZ]);
        !          1362:                    tsdu_maxsize = ntohl (tsdu_maxsize);
        !          1363:                    s -> s_tsdu_init = (tsdu_maxsize >> 16) & 0xffff;
        !          1364:                    s -> s_tsdu_resp = tsdu_maxsize & 0xffff;
        !          1365:                    Set (SMASK_CN_TSDU);
        !          1366:                }
        !          1367:                base += pi_length[PI_TSDU_MAXSIZ];
        !          1368:                break;
        !          1369: 
        !          1370:            case PI_VERSION: 
        !          1371:                switch (si) {
        !          1372:                    case SPDU_CN: 
        !          1373:                    case SPDU_AC: 
        !          1374:                        s -> s_cn_version = *base++;
        !          1375:                        Set (SMASK_CN_VRSN);
        !          1376:                        break;
        !          1377:                    case SPDU_RF: 
        !          1378:                        s -> s_rf_version = *base++;
        !          1379:                        Set (SMASK_RF_VRSN);
        !          1380:                        break;
        !          1381:                    default: 
        !          1382:                        s -> s_errno = SC_PROTOCOL;
        !          1383:                        break;
        !          1384:                }
        !          1385:                break;
        !          1386: 
        !          1387:            case PI_SYNC: 
        !          1388:                switch (si) {
        !          1389:                    case SPDU_MIP: 
        !          1390:                        if ((s -> s_mip_sync = *base++) & ~MIP_SYNC_MASK)
        !          1391:                            s -> s_errno = SC_PROTOCOL;
        !          1392:                        else
        !          1393:                            Set (SMASK_MIP_SYNC);
        !          1394:                        break;
        !          1395:                    case SPDU_MAP: 
        !          1396:                        if ((s -> s_map_sync = *base++) & ~MAP_SYNC_MASK)
        !          1397:                            s -> s_errno = SC_PROTOCOL;
        !          1398:                        else
        !          1399:                            Set (SMASK_MAP_SYNC);
        !          1400:                        break;
        !          1401:                }
        !          1402:                break;
        !          1403: 
        !          1404:            case PI_TOKEN_SET: 
        !          1405:                switch (si) {
        !          1406:                    case SPDU_CN: 
        !          1407:                    case SPDU_AC: 
        !          1408:                        s -> s_settings = *base++;
        !          1409:                        Set (SMASK_CN_SET);
        !          1410:                        break;
        !          1411:                    case SPDU_RS:
        !          1412:                        s -> s_rs_settings = *base++;
        !          1413:                        Set (SMASK_RS_SET);
        !          1414:                        break;
        !          1415:                    case SPDU_RA:
        !          1416:                        s -> s_ra_settings = *base++;
        !          1417:                        Set (SMASK_RA_SET);
        !          1418:                        break;
        !          1419:                    default: 
        !          1420:                        s -> s_errno = SC_PROTOCOL;
        !          1421:                        break;
        !          1422:                }
        !          1423:                break;
        !          1424: 
        !          1425:            case PI_TOKEN: 
        !          1426:                switch (si) {
        !          1427:                    case SPDU_AC: 
        !          1428:                        s -> s_ac_token = *base++;
        !          1429:                        Set (SMASK_AC_TOKEN);
        !          1430:                        break;
        !          1431:                    case SPDU_GT: 
        !          1432:                        If_Reset (SMASK_SPDU_GT) {
        !          1433:                            s -> s_errno = SC_PROTOCOL;
        !          1434:                            break;
        !          1435:                        }
        !          1436:                        s -> s_gt_token = *base++;
        !          1437:                        Set (SMASK_GT_TOKEN);
        !          1438:                        break;
        !          1439:                    case SPDU_PT: 
        !          1440:                        s -> s_pt_token = *base++;
        !          1441:                        Set (SMASK_PT_TOKEN);
        !          1442:                        break;
        !          1443:                    default: 
        !          1444:                        s -> s_errno = SC_PROTOCOL;
        !          1445:                        break;
        !          1446:                }
        !          1447:                break;
        !          1448: 
        !          1449:            case PI_TDISC: 
        !          1450:                switch (si) {
        !          1451:                    case SPDU_RF: 
        !          1452:                        if ((s -> s_rf_disconnect = *base++) & ~RF_DISC_MASK)
        !          1453:                            s -> s_errno = SC_PROTOCOL;
        !          1454:                        else
        !          1455:                            Set (SMASK_RF_DISC);
        !          1456:                        break;
        !          1457:                    case SPDU_FN: 
        !          1458:                        if ((s -> s_fn_disconnect = *base++) & ~FN_DISC_MASK)
        !          1459:                            s -> s_errno = SC_PROTOCOL;
        !          1460:                        else
        !          1461:                            Set (SMASK_FN_DISC);
        !          1462:                        break;
        !          1463:                    case SPDU_AB: 
        !          1464:                        If_Reset (SMASK_SPDU_AB) {
        !          1465:                            s -> s_errno = SC_PROTOCOL;
        !          1466:                            break;
        !          1467:                        }
        !          1468:                        if ((s -> s_ab_disconnect = *base++) & ~AB_DISC_MASK)
        !          1469:                            s -> s_errno = SC_PROTOCOL;
        !          1470:                        else
        !          1471:                            Set (SMASK_AB_DISC);
        !          1472:                        break;
        !          1473:                    default: 
        !          1474:                        s -> s_errno = SC_PROTOCOL;
        !          1475:                        break;
        !          1476:                }
        !          1477:                break;
        !          1478: 
        !          1479:            case PI_USER_REQ: 
        !          1480:                {
        !          1481:                    u_short requirements;
        !          1482:                    bcopy (base, (char *) &requirements, 2);
        !          1483:                    requirements = ntohs (requirements);
        !          1484:                    if (si != SPDU_RF) {
        !          1485:                        s -> s_cn_require = requirements;
        !          1486:                        Set (SMASK_CN_REQ);
        !          1487:                    }
        !          1488:                    else {
        !          1489:                        s -> s_rf_require = requirements;
        !          1490:                        Set (SMASK_RF_REQ);
        !          1491:                    }
        !          1492:                }
        !          1493:                base += 2;
        !          1494:                break;
        !          1495: 
        !          1496:            case PI_ISN: 
        !          1497:                switch (si) {
        !          1498:                    case SPDU_CN: 
        !          1499:                    case SPDU_AC: 
        !          1500:                        s -> s_isn = str2ssn (base, li);
        !          1501:                        Set (SMASK_CN_ISN);
        !          1502:                        break;
        !          1503:                    default: 
        !          1504:                        s -> s_errno = SC_PROTOCOL;
        !          1505:                        break;
        !          1506:                }
        !          1507:            case PI_ISN2:       /* not supported yet */
        !          1508:                base += li;
        !          1509:                break;
        !          1510: 
        !          1511:            case PI_ENCLOSE:
        !          1512:                if ((si == SPDU_DT && (s -> s_mask & SMASK_SPDU_GT))
        !          1513:                        || (si == SPDU_AI && !(s -> s_mask & SMASK_SPDU_AB))) {
        !          1514:                    s -> s_errno = SC_PROTOCOL;
        !          1515:                    break;
        !          1516:                }
        !          1517:                if ((s -> s_enclose = *base++) & ~ENCL_MASK)
        !          1518:                    s -> s_errno = SC_PROTOCOL;
        !          1519:                else
        !          1520:                    Set (SMASK_ENCLOSE);
        !          1521:                break;
        !          1522: 
        !          1523:            case PI_RESYNC:
        !          1524:                s -> s_rs_type = *base++;
        !          1525:                if (SYNC_OK (s -> s_rs_type))
        !          1526:                    Set (SMASK_RS_TYPE);
        !          1527:                else
        !          1528:                    s -> s_errno = SC_PROTOCOL;
        !          1529:                break;
        !          1530: 
        !          1531:            case PI_ACT_ID:
        !          1532:                switch (si) {
        !          1533:                    case SPDU_AS:
        !          1534:                        s -> s_as_id.sd_len = li;
        !          1535:                        bcopy (base, s -> s_as_id.sd_data, li);
        !          1536:                        Set (SMASK_AS_ID);
        !          1537:                        break;
        !          1538: 
        !          1539:                    case SPDU_AR:
        !          1540:                        if ((s -> s_mask & SMASK_AR_OID)
        !          1541:                                && s -> s_ar_oid.sd_len == 0) {
        !          1542:                            s -> s_ar_oid.sd_len = li;
        !          1543:                            bcopy (base, s -> s_ar_oid.sd_data, li);
        !          1544:                        }
        !          1545:                        else {
        !          1546:                            s -> s_ar_id.sd_len = li;
        !          1547:                            bcopy (base, s -> s_ar_id.sd_data, li);
        !          1548:                            Set (SMASK_AR_ID);
        !          1549:                        }
        !          1550:                        break;
        !          1551: 
        !          1552:                    default:
        !          1553:                        s -> s_errno = SC_PROTOCOL;
        !          1554:                        break;
        !          1555:                }
        !          1556:                base += li;
        !          1557:                break;
        !          1558: 
        !          1559:            case PI_SERIAL: 
        !          1560:                switch (si) {
        !          1561:                    case SPDU_MIP: 
        !          1562:                        s -> s_mip_serial = str2ssn (base, li);
        !          1563:                        Set (SMASK_MIP_SERIAL);
        !          1564:                        break;
        !          1565:                    case SPDU_MAP: 
        !          1566:                        s -> s_map_serial = str2ssn (base, li);
        !          1567:                        Set (SMASK_MAP_SERIAL);
        !          1568:                        break;
        !          1569:                    case SPDU_MIA: 
        !          1570:                        s -> s_mia_serial = str2ssn (base, li);
        !          1571:                        Set (SMASK_MIA_SERIAL);
        !          1572:                        break;
        !          1573:                    case SPDU_MAA: 
        !          1574:                        s -> s_maa_serial = str2ssn (base, li);
        !          1575:                        Set (SMASK_MAA_SERIAL);
        !          1576:                        break;
        !          1577:                    case SPDU_RS: 
        !          1578:                        s -> s_rs_serial = str2ssn (base, li);
        !          1579:                        Set (SMASK_RS_SSN);
        !          1580:                        break;
        !          1581:                    case SPDU_RA: 
        !          1582:                        s -> s_ra_serial = str2ssn (base, li);
        !          1583:                        Set (SMASK_RA_SSN);
        !          1584:                        break;
        !          1585:                    case SPDU_AR: 
        !          1586:                        s -> s_ar_serial = str2ssn (base, li);
        !          1587:                        Set (SMASK_AR_SSN);
        !          1588:                        break;
        !          1589:                    default: 
        !          1590:                        s -> s_errno = SC_PROTOCOL;
        !          1591:                        break;
        !          1592:                }
        !          1593:                base += li;
        !          1594:                break;
        !          1595: 
        !          1596:            case PI_MIA_DATA: 
        !          1597:            case PI_UDATA: 
        !          1598:            case PI_XDATA: 
        !          1599:                Set (SMASK_UDATA_PGI);
        !          1600:                if (!li)
        !          1601:                    break;
        !          1602:                if (si == SPDU_AB && !(s -> s_mask & SMASK_SPDU_AB)) {
        !          1603:                    s -> s_errno = SC_PROTOCOL;
        !          1604:                    break;
        !          1605:                }
        !          1606:                else
        !          1607:                    if (li > (code != PI_XDATA ? SEGMENT_MAX : CONNECT_MAX)) {
        !          1608:                        s -> s_errno = SC_PROTOCOL;
        !          1609:                        break;
        !          1610:                    }
        !          1611:                s -> s_udata = malloc ((unsigned) (s -> s_ulen = li));
        !          1612:                if (s -> s_udata == NULL) {
        !          1613:                    s -> s_errno = SC_CONGEST;
        !          1614:                    break;
        !          1615:                }
        !          1616:                bcopy (base, s -> s_udata, li);
        !          1617:                base += li;
        !          1618:                break;
        !          1619: 
        !          1620:            case PI_REASON: 
        !          1621:                switch (si) {
        !          1622:                    case SPDU_RF: 
        !          1623:                        s -> s_rdata = malloc ((unsigned) (s -> s_rlen = li));
        !          1624:                        if (s -> s_rdata == NULL) {
        !          1625:                            s -> s_errno = SC_CONGEST;
        !          1626:                            break;
        !          1627:                        }
        !          1628:                        bcopy (base, s -> s_rdata, li);
        !          1629:                        base += li;
        !          1630:                        break;
        !          1631:                    case SPDU_ED: 
        !          1632:                        s -> s_ed_reason = *base++;
        !          1633:                        if (li == 1 && SP_OK (s -> s_ed_reason))
        !          1634:                            Set (SMASK_ED_REASON);
        !          1635:                        else
        !          1636:                            s -> s_errno = SC_PROTOCOL;
        !          1637:                        break;
        !          1638:                    case SPDU_AI: 
        !          1639:                        If_Set (SMASK_SPDU_AB) {
        !          1640:                            s -> s_errno = SC_PROTOCOL;
        !          1641:                            break;
        !          1642:                        }
        !          1643:                        s -> s_ai_reason = *base++;
        !          1644:                        if (li == 1 && SP_OK (s -> s_ai_reason))
        !          1645:                            Set (SMASK_AI_REASON);
        !          1646:                        else
        !          1647:                            s -> s_errno = SC_PROTOCOL;
        !          1648:                        break;
        !          1649:                    case SPDU_AD: 
        !          1650:                        s -> s_ad_reason = *base++;
        !          1651:                        if (li == 1 && SP_OK (s -> s_ad_reason))
        !          1652:                            Set (SMASK_AD_REASON);
        !          1653:                        else
        !          1654:                            s -> s_errno = SC_PROTOCOL;
        !          1655:                        break;
        !          1656:                    default: 
        !          1657:                        s -> s_errno = SC_PROTOCOL;
        !          1658:                        break;
        !          1659:                }
        !          1660:                break;
        !          1661: 
        !          1662:            case PI_REFLECT: 
        !          1663:                switch (si) {
        !          1664:                    case SPDU_AB: 
        !          1665:                        If_Reset (SMASK_SPDU_AB) {
        !          1666:                            s -> s_errno = SC_PROTOCOL;
        !          1667:                            break;
        !          1668:                        }
        !          1669:                        if (li > AB_REFL_SIZE) {
        !          1670:                            s -> s_errno = SC_PROTOCOL;
        !          1671:                            break;
        !          1672:                        }
        !          1673:                        bcopy (base, (char *) s -> s_reflect, li);
        !          1674:                        Set (SMASK_AB_REFL);
        !          1675:                        break;
        !          1676:                    case SPDU_ER: 
        !          1677:                        s -> s_udata = malloc ((unsigned) (s -> s_ulen = li));
        !          1678:                        if (s -> s_udata == NULL) {
        !          1679:                            s -> s_errno = SC_CONGEST;
        !          1680:                            break;
        !          1681:                        }
        !          1682:                        bcopy (base, s -> s_udata, li);
        !          1683:                        break;
        !          1684:                    default: 
        !          1685:                        s -> s_errno = SC_PROTOCOL;
        !          1686:                        break;
        !          1687:                }
        !          1688:                base += li;
        !          1689:                break;
        !          1690: 
        !          1691:            case PI_SSAP_CALLING: 
        !          1692:                bcopy (base, s -> s_calling, s -> s_callinglen = li);
        !          1693:                Set (SMASK_CN_CALLING);
        !          1694:                base += li;
        !          1695:                break;
        !          1696: 
        !          1697:            case PI_SSAP_CALLED: 
        !          1698:                bcopy (base, s -> s_called, s -> s_calledlen = li);
        !          1699:                Set (SMASK_CN_CALLED);
        !          1700:                base += li;
        !          1701:                break;
        !          1702: 
        !          1703:            case PI_PREPARE: 
        !          1704:                if ((s -> s_pr_type = *base++) > PR_MAX)
        !          1705:                    s -> s_errno = SC_PROTOCOL;
        !          1706:                else
        !          1707:                    Set (SMASK_PR_TYPE);
        !          1708:                break;
        !          1709: 
        !          1710:            default: 
        !          1711:                s -> s_errno = SC_PROTOCOL;
        !          1712:                break;
        !          1713:        }
        !          1714:     }
        !          1715: /* NB: caller responsible for mapping user info to s -> s_qbuf */
        !          1716: 
        !          1717:     if (cc)
        !          1718:        *cc = nread;
        !          1719:     {                          /* "dangling" qbuf */
        !          1720:        register struct qbuf *qp;
        !          1721: 
        !          1722:        if ((qp = qb -> qb_forw) != qb && qp -> qb_len <= 0) {
        !          1723:            remque (qp);
        !          1724: 
        !          1725:            free ((char *) qp);
        !          1726:        }
        !          1727:     }
        !          1728: 
        !          1729:     switch (s -> s_code) {
        !          1730:        case SPDU_AB: 
        !          1731:            If_Set (SMASK_SPDU_AB) {
        !          1732:                If_Reset (SMASK_AB_DISC)
        !          1733:                    s -> s_errno = SC_PROTOCOL;
        !          1734:            }
        !          1735:            break;
        !          1736: 
        !          1737:        case SPDU_MIP: 
        !          1738:            If_Reset (SMASK_MIP_SERIAL)
        !          1739:                s -> s_errno = SC_PROTOCOL;
        !          1740:            break;
        !          1741: 
        !          1742:        case SPDU_MAP: 
        !          1743:            If_Reset (SMASK_MAP_SERIAL)
        !          1744:                s -> s_errno = SC_PROTOCOL;
        !          1745:            break;
        !          1746: 
        !          1747:        case SPDU_MIA: 
        !          1748:            If_Reset (SMASK_MIA_SERIAL)
        !          1749:                s -> s_errno = SC_PROTOCOL;
        !          1750:            break;
        !          1751: 
        !          1752:        case SPDU_MAA: 
        !          1753:            If_Reset (SMASK_MAA_SERIAL)
        !          1754:                s -> s_errno = SC_PROTOCOL;
        !          1755:            break;
        !          1756: 
        !          1757:        case SPDU_RS: 
        !          1758:            If_Reset (SMASK_RS_TYPE)
        !          1759:                s -> s_errno = SC_PROTOCOL;
        !          1760:            If_Reset (SMASK_RS_SSN)
        !          1761:                s -> s_errno = SC_PROTOCOL;
        !          1762:            break;
        !          1763: 
        !          1764:        case SPDU_RA: 
        !          1765:            If_Reset (SMASK_RA_SSN)
        !          1766:                s -> s_errno = SC_PROTOCOL;
        !          1767:            break;
        !          1768: 
        !          1769:        case SPDU_PR: 
        !          1770:            If_Reset (SMASK_PR_TYPE)
        !          1771:                s -> s_errno = SC_PROTOCOL;
        !          1772:            break;
        !          1773: 
        !          1774:        case SPDU_ED: 
        !          1775:            If_Reset (SMASK_ED_REASON)
        !          1776:                s -> s_errno = SC_PROTOCOL;
        !          1777:            break;
        !          1778: 
        !          1779:        case SPDU_AS: 
        !          1780:            If_Reset (SMASK_AS_ID)
        !          1781:                s -> s_errno = SC_PROTOCOL;
        !          1782:            break;
        !          1783: 
        !          1784:        case SPDU_AR: 
        !          1785:            If_Reset (SMASK_AR_OID)
        !          1786:                s -> s_errno = SC_PROTOCOL;
        !          1787:            If_Reset (SMASK_AR_SSN)
        !          1788:                s -> s_errno = SC_PROTOCOL;
        !          1789:            If_Reset (SMASK_AR_ID)
        !          1790:                s -> s_errno = SC_PROTOCOL;
        !          1791:            break;
        !          1792:     }
        !          1793: 
        !          1794: #ifdef DEBUG
        !          1795:     if (ssap_log -> ll_events & LLOG_PDUS)
        !          1796:        spkt2text (ssap_log, s, 1);
        !          1797: #endif
        !          1798: 
        !          1799:     return s;
        !          1800: }
        !          1801: 
        !          1802: /*  */
        !          1803: 
        !          1804: struct ssapkt *newspkt (code)
        !          1805: int    code;
        !          1806: {
        !          1807:     register struct ssapkt *s;
        !          1808: 
        !          1809:     s = (struct ssapkt *) calloc (1, sizeof *s);
        !          1810:     if (s == NULL)
        !          1811:        return NULL;
        !          1812: 
        !          1813:     s -> s_code = code;
        !          1814:     s -> s_qbuf.qb_forw = s -> s_qbuf.qb_back = &s -> s_qbuf;
        !          1815: 
        !          1816:     return s;
        !          1817: }
        !          1818: 
        !          1819: 
        !          1820: int    freespkt (s)
        !          1821: register struct ssapkt *s;
        !          1822: {
        !          1823:     if (s == NULL)
        !          1824:        return;
        !          1825: 
        !          1826:     switch (s -> s_code) {
        !          1827:        case SPDU_RF: 
        !          1828:            if (s -> s_rdata)
        !          1829:                free (s -> s_rdata);/* and fall... */
        !          1830: 
        !          1831:        default: 
        !          1832:            if (s -> s_udata)
        !          1833:                free (s -> s_udata);
        !          1834:            QBFREE (&s -> s_qbuf);
        !          1835:            break;
        !          1836:     }
        !          1837: 
        !          1838:     free ((char *) s);
        !          1839: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.