Annotation of 43BSDReno/contrib/isode-beta/tsap/fd2tpkt.c, revision 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.