Annotation of 43BSDReno/contrib/isode-beta/tsap/fd2tpkt.c, revision 1.1.1.1

1.1       root        1: /* fd2tpkt.c - read/write a TPDU thru a socket */
                      2: 
                      3: #ifndef        lint
                      4: static char *rcsid = "$Header: /f/osi/tsap/RCS/fd2tpkt.c,v 7.1 89/12/07 01:07:25 mrose Exp $";
                      5: #endif
                      6: 
                      7: /* 
                      8:  * $Header: /f/osi/tsap/RCS/fd2tpkt.c,v 7.1 89/12/07 01:07:25 mrose Exp $
                      9:  *
                     10:  *
                     11:  * $Log:       fd2tpkt.c,v $
                     12:  * Revision 7.1  89/12/07  01:07:25  mrose
                     13:  * queued writes
                     14:  * 
                     15:  * Revision 7.0  89/11/23  22:30:26  mrose
                     16:  * Release 6.0
                     17:  * 
                     18:  */
                     19: 
                     20: /*
                     21:  *                               NOTICE
                     22:  *
                     23:  *    Acquisition, use, and distribution of this module and related
                     24:  *    materials are subject to the restrictions of a license agreement.
                     25:  *    Consult the Preface in the User's Manual for the full terms of
                     26:  *    this agreement.
                     27:  *
                     28:  */
                     29: 
                     30: 
                     31: /* LINTLIBRARY */
                     32: 
                     33: #include <stdio.h>
                     34: #include <signal.h>
                     35: #include "tpkt.h"
                     36: #include "tailor.h"
                     37: 
                     38: /*  */
                     39: 
                     40: struct tsapkt *fd2tpkt (fd, initfnx, readfnx)
                     41: int    fd;
                     42: IFP    initfnx,
                     43:        readfnx;
                     44: {
                     45:     register struct tsapkt *t;
                     46: 
                     47:     if ((t = newtpkt (0)) == NULL)
                     48:        return NULL;
                     49: 
                     50:     if ((t -> t_errno = fd2tpktaux (fd, t, initfnx, readfnx)) != OK) {
                     51:        if (t -> t_vdata != NULL)
                     52:            free (t -> t_vdata), t -> t_vdata = NULL, t -> t_vlen = 0;
                     53: 
                     54:        if (t -> t_qbuf)
                     55:            free ((char *) t -> t_qbuf), t -> t_qbuf = NULL;
                     56:     }
                     57: 
                     58: #ifdef DEBUG
                     59:     if (tsap_log -> ll_events & LLOG_PDUS)
                     60:        tpkt2text (tsap_log, t, 1);
                     61: #endif
                     62: 
                     63:     return t;
                     64: }
                     65: 
                     66: /*  */
                     67: 
                     68: static int  fd2tpktaux (fd, t, initfnx, readfnx)
                     69: int    fd;
                     70: register struct tsapkt *t;
                     71: IFP    initfnx,
                     72:        readfnx;
                     73: {
                     74:     register int    code,
                     75:                     len,
                     76:                     vlen;
                     77:     register char  *vptr;
                     78: 
                     79:     if ((code = (*initfnx) (fd, t)) != OK)
                     80:        return code;
                     81:     if (t -> t_li > TPDU_MAXLEN (t))
                     82:        return DR_LENGTH;
                     83: 
                     84:     switch (TPDU_CODE (t)) {
                     85:        case TPDU_CR:
                     86:        case TPDU_CC:
                     87:            if (t -> t_li < TPDU_MINLEN (t, CR))
                     88:                return DR_LENGTH;
                     89:            if (readx (fd, (char *) &t -> t_cr, CR_SIZE (t), readfnx)
                     90:                    != CR_SIZE (t))
                     91:                return DR_NETWORK;
                     92: 
                     93:            if (vlen = t -> t_vlen = t -> t_li - TPDU_MINLEN (t, CR)) {
                     94:                if ((vptr = t -> t_vdata = malloc ((unsigned) vlen)) == NULL)
                     95:                    return DR_CONGEST;
                     96:                if (readx (fd, t -> t_vdata, t -> t_vlen, readfnx)
                     97:                        != t -> t_vlen)
                     98:                    return DR_NETWORK;
                     99:                for (; vlen > 0; vptr += len, vlen -= len) {
                    100:                    int     ilen;
                    101:                    
                    102:                    if (vlen < 2)
                    103:                        return DR_LENGTH;
                    104:                    code = *vptr++ & 0xff;
                    105:                    len = *vptr++ & 0xff;
                    106:                    if ((vlen -= 2) < len)
                    107:                        return DR_LENGTH;
                    108: 
                    109:                    switch (code) {
                    110:                        case VDAT_TSAP_SRV:
                    111:                            if ((ilen = len) > sizeof t -> t_called)
                    112:                                ilen = sizeof t -> t_called;
                    113:                            bcopy (vptr, t -> t_called,
                    114:                                        t -> t_calledlen = ilen);
                    115:                            break;
                    116: 
                    117:                        case VDAT_TSAP_CLI:
                    118:                            if ((ilen = len) > sizeof t -> t_calling)
                    119:                                ilen = sizeof t -> t_calling;
                    120:                            bcopy (vptr, t -> t_calling,
                    121:                                        t -> t_callinglen = ilen);
                    122:                            break;
                    123: 
                    124:                        case VDAT_SIZE:
                    125:                            if (len != 1)
                    126:                                return DR_LENGTH;
                    127:                            t -> t_tpdusize = *vptr & 0xff;
                    128:                            break;
                    129: 
                    130:                        case VDAT_OPTIONS:
                    131:                            if (len != 1)
                    132:                                return DR_LENGTH;
                    133:                            t -> t_options = *vptr & 0xff;
                    134:                            break;
                    135: 
                    136:                        case VDAT_ALTERNATE:
                    137:                            {
                    138:                                register int i;
                    139:                                register char *ap;
                    140: 
                    141:                                for (ap = vptr, i = len; i > 0; ap++, i--)
                    142:                                    t -> t_cr.cr_alternate |=
                    143:                                                1 << ((*ap >> 4) & 0x0f);
                    144:                            }
                    145:                            break;
                    146: 
                    147:                        case VDAT_VRSN:
                    148:                        case VDAT_SECURITY:
                    149:                        case VDAT_CHECKSUM:
                    150:                        case VDAT_ACKTIME:
                    151:                        case VDAT_THROUGHPUT:
                    152:                        case VDAT_ERRORATE:
                    153:                        case VDAT_PRIORITY:
                    154:                        case VDAT_DELAY:
                    155:                        case VDAT_TTR:
                    156:                            break;
                    157: 
                    158:                        default:        /* IS 8073 says to ignore it on CRs */
                    159:                            SLOG (tsap_log, LLOG_EXCEPTIONS, NULLCP,
                    160:                               ("unknown option 0x%x (length 0x%x) in %s TPDU",
                    161:                                code, len,
                    162:                                TPDU_CODE (t) == TPDU_CR ? "CR" : "CC"));
                    163:                            if (TPDU_CODE (t) == TPDU_CR)
                    164:                                break;
                    165:                            return DR_PROTOCOL;
                    166:                    }
                    167:                }
                    168:            }
                    169:            break;
                    170: 
                    171:        case TPDU_DR:
                    172:            if (t -> t_li < TPDU_MINLEN (t, DR))
                    173:                return DR_LENGTH;
                    174:            if (readx (fd, (char *) &t -> t_dr, DR_SIZE (t), readfnx)
                    175:                    != DR_SIZE (t))
                    176:                return DR_NETWORK;
                    177: 
                    178:            if (vlen = t -> t_vlen = t -> t_li - TPDU_MINLEN (t, DR)) {
                    179:                if ((vptr = t -> t_vdata = malloc ((unsigned) vlen)) == NULL)
                    180:                    return DR_CONGEST;
                    181:                if (readx (fd, t -> t_vdata, t -> t_vlen, readfnx)
                    182:                        != t -> t_vlen)
                    183:                    return DR_NETWORK;
                    184:                for (; vlen > 0; vptr += len, vlen -= len) {
                    185:                    if (vlen < 2)
                    186:                        return DR_LENGTH;
                    187:                    code = *vptr++ & 0xff;
                    188:                    len = *vptr++ & 0xff;
                    189:                    if ((vlen -= 2) < len)
                    190:                        return DR_LENGTH;
                    191: 
                    192:                    switch (code) {
                    193:                        case VDAT_ADDITIONAL:
                    194:                        case VDAT_CHECKSUM:
                    195:                            break;
                    196: 
                    197:                        default: 
                    198:                            return DR_PROTOCOL;
                    199:                    }
                    200:                }
                    201:            }
                    202:            break;
                    203: 
                    204:        case TPDU_DT:
                    205:            if (t -> t_li < TPDU_MINLEN (t, DT))
                    206:                return DR_LENGTH;
                    207:            if (readx (fd, (char *) &t -> t_dt, DT_SIZE (t), readfnx)
                    208:                    != DT_SIZE (t))
                    209:                return DR_NETWORK;
                    210: 
                    211:            if (vlen = t -> t_vlen = t -> t_li - TPDU_MINLEN (t, DT)) {
                    212:                if ((vptr = t -> t_vdata = malloc ((unsigned) vlen)) == NULL)
                    213:                    return DR_CONGEST;
                    214:                if (readx (fd, t -> t_vdata, t -> t_vlen, readfnx)
                    215:                        != t -> t_vlen)
                    216:                    return DR_NETWORK;
                    217:                for (; vlen > 0; vptr += len, vlen -= len) {
                    218:                    if (vlen < 2)
                    219:                        return DR_LENGTH;
                    220:                    code = *vptr++ & 0xff;
                    221:                    len = *vptr++ & 0xff;
                    222:                    if ((vlen -= 2) < len)
                    223:                        return DR_LENGTH;
                    224: 
                    225:                    switch (code) {
                    226:                        case VDAT_CHECKSUM:
                    227:                            break;
                    228: 
                    229:                        default: 
                    230:                            return DR_PROTOCOL;
                    231:                    }
                    232:                }
                    233:            }
                    234:            break;
                    235: 
                    236:        case TPDU_ED: 
                    237:            if (t -> t_li < TPDU_MINLEN (t, ED))
                    238:                return DR_LENGTH;
                    239:            if (readx (fd, (char *) &t -> t_ed, ED_SIZE (t), readfnx)
                    240:                    != ED_SIZE (t))
                    241:                return DR_NETWORK;
                    242:            t -> t_ed.ed_nr = ntohs (t -> t_ed.ed_nr);
                    243: 
                    244:            if (vlen = t -> t_vlen = t -> t_li - TPDU_MINLEN (t, ED)) {
                    245:                if ((vptr = t -> t_vdata = malloc ((unsigned) vlen)) == NULL)
                    246:                    return DR_CONGEST;
                    247:                if (readx (fd, t -> t_vdata, t -> t_vlen, readfnx)
                    248:                        != t -> t_vlen)
                    249:                    return DR_NETWORK;
                    250: 
                    251:                for (; vlen > 0; vptr += len, vlen -= len) {
                    252:                    if (vlen < 2)
                    253:                        return DR_LENGTH;
                    254:                    code = *vptr++ & 0xff;
                    255:                    len = *vptr++ & 0xff;
                    256:                    if ((vlen -= 2) < len)
                    257:                        return DR_LENGTH;
                    258: 
                    259:                    switch (code) {
                    260:                        case VDAT_CHECKSUM:
                    261:                        case VDAT_SUBSEQ:
                    262:                        case VDAT_FLOWCTL:
                    263:                            break;
                    264: 
                    265:                        default: 
                    266:                            return DR_PROTOCOL;
                    267:                    }
                    268:                }
                    269:            }
                    270:            break;
                    271: 
                    272:        case TPDU_ER:
                    273:            if (t -> t_li < TPDU_MINLEN (t, ER))
                    274:                return DR_LENGTH;
                    275:            if (readx (fd, (char *) &t -> t_er, ER_SIZE (t), readfnx)
                    276:                    != ER_SIZE (t))
                    277:                return DR_NETWORK;
                    278: 
                    279:            if (vlen = t -> t_vlen = t -> t_li - TPDU_MINLEN (t, ER)) {
                    280:                if ((vptr = t -> t_vdata = malloc ((unsigned) vlen)) == NULL)
                    281:                    return DR_CONGEST;
                    282:                if (readx (fd, t -> t_vdata, t -> t_vlen, readfnx)
                    283:                        != t -> t_vlen)
                    284:                    return DR_NETWORK;
                    285:                for (; vlen > 0; vptr += len, vlen -= len) {
                    286:                    if (vlen < 2)
                    287:                        return DR_LENGTH;
                    288:                    code = *vptr++ & 0xff;
                    289:                    len = *vptr++ & 0xff;
                    290:                    if ((vlen -= 2) < len)
                    291:                        return DR_LENGTH;
                    292: 
                    293:                    switch (code) {
                    294:                        case VDAT_INVALID:
                    295:                        case VDAT_CHECKSUM:
                    296:                            break;
                    297: 
                    298:                        default: 
                    299:                            return DR_PROTOCOL;
                    300:                    }
                    301:                }
                    302:            }
                    303:            break;
                    304: 
                    305:        default: 
                    306:            return DR_PROTOCOL;
                    307:     }
                    308: 
                    309:     if (len = TPDU_USRLEN (t)) {
                    310:        if ((t -> t_qbuf = (struct qbuf *)
                    311:                            malloc (sizeof *t -> t_qbuf + (unsigned) len))
                    312:                == NULL)
                    313:            return DR_CONGEST;
                    314:        t -> t_qbuf -> qb_forw = t -> t_qbuf -> qb_back = t -> t_qbuf;
                    315:        if (readx (fd, t -> t_qbuf -> qb_data = t -> t_qbuf -> qb_base,
                    316:                t -> t_qbuf -> qb_len = len, readfnx) != len)
                    317:            return DR_NETWORK;
                    318:     }
                    319: 
                    320:     return OK;
                    321: }
                    322: 
                    323: /*  */
                    324: 
                    325: static int  readx (fd, buffer, n, readfnx)
                    326: int    fd;
                    327: char    *buffer;
                    328: int    n;
                    329: IFP    readfnx;
                    330: {
                    331:     register int    i,
                    332:                     cc;
                    333:     register char   *bp;
                    334: 
                    335:     for (bp = buffer, i = n; i > 0; bp += cc, i -= cc) {
                    336:        switch (cc = (*readfnx) (fd, bp, i)) {
                    337:            case NOTOK: 
                    338:                return (i = bp - buffer) ? i : NOTOK;
                    339: 
                    340:            case OK: 
                    341:                break;
                    342: 
                    343:            default: 
                    344:                continue;
                    345:        }
                    346:        break;
                    347:     }
                    348: 
                    349:     return (bp - buffer);
                    350: }
                    351: 
                    352: /*  */
                    353: 
                    354: int    tpkt2fd (tb, t, writefnx)
                    355: register struct tsapblk *tb;
                    356: register struct tsapkt *t;
                    357: IFP    writefnx;
                    358: {
                    359:     SBV            smask;
                    360:     int     i,
                    361:            ilen,
                    362:             ulen;
                    363:     char   *cp,
                    364:           *vptr,
                    365:            *outptr;
                    366:     register struct udvec  *uv;
                    367:     SFP            pstat;
                    368: 
                    369:     if (t -> t_errno != OK)
                    370:        return t -> t_errno;
                    371: 
                    372:     if (t -> t_vrsn != TPKT_VRSN)
                    373:        if (t -> t_vrsn)
                    374:            return DR_PROTOCOL;
                    375:        else
                    376:            t -> t_vrsn = TPKT_VRSN;
                    377: 
                    378:     if (t -> t_vdata != NULL) {
                    379:        free (t -> t_vdata);
                    380:        t -> t_vdata = NULL;
                    381:     }
                    382:     t -> t_vlen = 0;
                    383: 
                    384:     for (ulen = 0, uv = t -> t_udvec; uv -> uv_base; uv++)
                    385:        ulen += uv -> uv_len;
                    386: 
                    387:     switch (TPDU_CODE (t)) {
                    388:        case TPDU_CR:
                    389:        case TPDU_CC:
                    390:            if ((vptr = t -> t_vdata =
                    391:                    malloc ((unsigned) (3 + 7 + (2 + t -> t_callinglen)
                    392:                                 + (2 + t -> t_calledlen) + 3))) == NULL)
                    393:                return DR_CONGEST;
                    394:            if (t -> t_options) {
                    395:                *vptr++ = VDAT_OPTIONS;
                    396:                *vptr++ = 1;
                    397:                *vptr++ = t -> t_options;
                    398:                t -> t_vlen += 3;
                    399:            }
                    400:            if (CR_CLASS (t) != CR_CLASS_TP0 && t -> t_cr.cr_alternate) {
                    401:                /* XXX: this doesn't preserve the order of alternates */
                    402:                *vptr++ = VDAT_ALTERNATE;
                    403:                cp = vptr++;
                    404:                if (t -> t_cr.cr_alternate & ALT_TP0)
                    405:                    *vptr++ = CR_CLASS_TP0;
                    406:                if (t -> t_cr.cr_alternate & ALT_TP1)
                    407:                    *vptr++ = CR_CLASS_TP1;
                    408:                if (t -> t_cr.cr_alternate & ALT_TP2)
                    409:                    *vptr++ = CR_CLASS_TP2;
                    410:                if (t -> t_cr.cr_alternate & ALT_TP3)
                    411:                    *vptr++ = CR_CLASS_TP3;
                    412:                if (t -> t_cr.cr_alternate & ALT_TP4)
                    413:                    *vptr++ = CR_CLASS_TP4;
                    414:                i = (vptr - cp) - 1;
                    415:                *cp = i & 0xff;
                    416:                t -> t_vlen += (2 + i) & 0xff;
                    417:            }
                    418:            if (t -> t_callinglen > 0) {
                    419:                *vptr++ = VDAT_TSAP_CLI;
                    420:                *vptr++ = t -> t_callinglen;
                    421:                bcopy (t -> t_calling, vptr, t -> t_callinglen);
                    422:                vptr += t -> t_callinglen;
                    423:                t -> t_vlen += 2 + t -> t_callinglen;
                    424:            }
                    425:            if (t -> t_calledlen > 0) {
                    426:                *vptr++ = VDAT_TSAP_SRV;
                    427:                *vptr++ = t -> t_calledlen;
                    428:                bcopy (t -> t_called, vptr, t -> t_calledlen);
                    429:                vptr += t -> t_calledlen;
                    430:                t -> t_vlen += 2 + t -> t_calledlen;
                    431:            }
                    432:            if (t -> t_tpdusize) {
                    433:                *vptr++ = VDAT_SIZE;
                    434:                *vptr++ = 1;
                    435:                *vptr++ = t -> t_tpdusize;
                    436:                t -> t_vlen += 3;
                    437:            }
                    438:            if (t -> t_vlen == 0) {
                    439:                free (t -> t_vdata);
                    440:                t -> t_vdata = NULL;
                    441:            }
                    442:            t -> t_li = TPDU_MINLEN (t, CR) + t -> t_vlen;
                    443:            outptr = (char *) &t -> t_cr;
                    444:            ilen = CR_SIZE (t);
                    445:            break;
                    446: 
                    447:        case TPDU_DR: 
                    448:            t -> t_li = TPDU_MINLEN (t, DR) + t -> t_vlen;
                    449:            outptr = (char *) &t -> t_dr;
                    450:            ilen = DR_SIZE (t);
                    451:            break;
                    452: 
                    453:        case TPDU_DT: 
                    454:            t -> t_li = TPDU_MINLEN (t, DT) + t -> t_vlen;
                    455:            outptr = (char *) &t -> t_dt;
                    456:            ilen = DT_SIZE (t);
                    457:            break;
                    458: 
                    459:        case TPDU_ED: 
                    460:            t -> t_li = TPDU_MINLEN (t, ED) + t -> t_vlen;
                    461:            t -> t_ed.ed_nr = htons (t -> t_ed.ed_nr);
                    462:            outptr = (char *) &t -> t_ed;
                    463:            ilen = ED_SIZE (t);
                    464:            break;
                    465: 
                    466:        case TPDU_ER: 
                    467:            t -> t_li = TPDU_MINLEN (t, ER) + t -> t_vlen;
                    468:            outptr = (char *) &t -> t_er;
                    469:            ilen = ER_SIZE (t);
                    470:            if (ulen > 0)
                    471:                return DR_PROTOCOL;
                    472:            break;
                    473: 
                    474:        default: 
                    475:            return DR_PROTOCOL;
                    476:     }
                    477: 
                    478:     t -> t_length = htons (t -> t_li + 5 + ulen);
                    479: 
                    480: #ifdef DEBUG
                    481:     if (tsap_log -> ll_events & LLOG_PDUS)
                    482:        tpkt2text (tsap_log, t, 0);
                    483: #endif
                    484: 
                    485:     pstat = signal (SIGPIPE, SIG_IGN);
                    486:     smask = sigioblock ();
                    487: 
                    488:     i = (*writefnx) (tb, t, outptr, ilen);
                    489: 
                    490:     (void) sigiomask (smask);
                    491:     (void) signal (SIGPIPE, pstat);
                    492: 
                    493:     if (i != NOTOK)
                    494:        i = OK;
                    495:     else
                    496:        if (t -> t_errno == DR_UNKNOWN)
                    497:            t -> t_errno = DR_NETWORK;
                    498: 
                    499:     return i;
                    500: }
                    501: 
                    502: /*  */
                    503: 
                    504: struct tsapkt *newtpkt (code)
                    505: int    code;
                    506: {
                    507:     register struct tsapkt *t;
                    508: 
                    509:     t = (struct tsapkt *) calloc (1, sizeof *t);
                    510:     if (t == NULL)
                    511:        return NULL;
                    512: 
                    513:     t -> t_vrsn = TPKT_VRSN;
                    514:     t -> t_code = code;
                    515: 
                    516:     return t;
                    517: }
                    518: 
                    519: 
                    520: int    freetpkt (t)
                    521: register struct tsapkt *t;
                    522: {
                    523:     if (t == NULL)
                    524:        return;
                    525: 
                    526:     if (t -> t_vdata)
                    527:        free (t -> t_vdata);
                    528: 
                    529:     if (t -> t_qbuf)
                    530:        free ((char *) t -> t_qbuf);
                    531: 
                    532:     free ((char *) t);
                    533: }

unix.superglobalmegacorp.com

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