tsdu2spkt.c
来自「ftam等标准协议服务器和客户端的源代码。」· C语言 代码 · 共 2,171 行 · 第 1/4 页
C
2,171 行
static u_long str2ssn (s, n)register char *s;register int n;{ register u_long u; for (u = 0L; n > 0; n--) u = u * 10 + *s++ - '0'; return u;}/* *//* this is used to pull PCI, not user data... */#define advance(n) \ if (base >= xbase) { \ if ((base = pullqb (qb, (n))) == NULL) { \ s -> s_errno = SC_PROTOCOL; \ break; \ } \ xbase = base + (n); \ nread += (n); \ } \ elsestatic char *pullqb (qb, n)struct qbuf *qb;int n;{ register int i; int once; register char *cp; register struct qbuf *qp; static char *buffer = NULL; if (n > SEGMENT_MAX) return NULLCP; for (once = 1, cp = buffer, qp = NULL; n > 0; once = 0, cp += i, n -= i) { if (qp == NULL && (qp = qb -> qb_forw) == qb) return NULLCP; i = min (qp -> qb_len, n); if (once && i == n) { /* special case */ cp = qp -> qb_data; qp -> qb_data += i, qp -> qb_len -= i; return cp; } if (buffer == NULL) { if ((buffer = malloc ((unsigned) SEGMENT_MAX)) == NULL) return NULLCP; cp = buffer; } bcopy (qp -> qb_data, cp, i); qp -> qb_data += i, qp -> qb_len -= i; if (qp -> qb_len <= 0) { remque (qp); free ((char *) qp); qp = NULL; } } return buffer;}/* */struct ssapkt *tsdu2spkt (qb, len, cc)struct qbuf *qb;int len, *cc;{ register int li; int cat0, nread, pktlen, pgilen, pmask, xlen; register char *base; char *xbase; unsigned char code, si; register struct ssapkt *s; if (cc) { cat0 = *cc; *cc = 0; } else cat0 = 1; if ((base = pullqb (qb, nread = 2)) == NULL || (s = newspkt ((int) (si = *base++))) == NULL) return NULLSPKT; if (*((u_char *) base) == 255) { if ((base = pullqb (qb, 2)) == NULL) { s -> s_errno = SC_PROTOCOL; return s; } nread += 2; s -> s_li = (*((u_char *) base) << 8) + *((u_char *) (base + 1)); } else s -> s_li = *((u_char *) base); pgilen = pktlen = s -> s_li; if (cat0) switch (si) { case SPDU_GT: Set (SMASK_SPDU_GT); break;#if HULA case SPDU_UD: Set (SMASK_SPDU_UD);#ifdef HULADEBUG printf ("\n decoding UNITDATASPDU \n");#endif break;#endif case SPDU_AB: Set (SMASK_SPDU_AB); break; case SPDU_AA: Set (SMASK_SPDU_AA); break; default: break; } if ((si >= SI_TABLE_LEN) || ((pmask = si_table[si]) == PMASK_NOTSUPPORTED)) { s -> s_errno = SC_PROTOCOL; return s; } if (len < pktlen + nread) { s -> s_errno = SC_PROTOCOL; return s; } s -> s_errno = SC_ACCEPT; xbase = base; while (pktlen && (s -> s_errno == SC_ACCEPT)) { advance (2); code = *base++; if (*((u_char *) base) == 255) { base++; advance (2); li = (*((u_char *) base) << 8) + *((u_char *) (base + 1)); xlen = 2; } else { li = *((u_char *) base); xlen = 1; } base += xlen; if (xlen > 1) xlen += 2; else xlen++; switch (code) { case PI_UDATA: if (!(pmask & PMASK_UDATA)) s -> s_errno = SC_PROTOCOL; break; case PI_XDATA: if (!(pmask & PMASK_XDATA)) s -> s_errno = SC_PROTOCOL; break; default: if (code >= PI_TABLE_LEN || !(pmask & pi_table[code])) s -> s_errno = SC_PROTOCOL; break; } if (s -> s_errno != SC_ACCEPT) break; if (!pgilen) pgilen = pktlen; pktlen -= (xlen + li); if (li > (pgilen -= xlen)) { s -> s_errno = SC_PROTOCOL; break; } pgilen -= li; if (li) advance (li); if (code < PI_TABLE_LEN) { if (li) { if (pi_table[code] & PMASK_VARLEN) { if (li > pi_length[code]) { s -> s_errno = SC_PROTOCOL; break; } } else if (li != pi_length[code]) { s -> s_errno = SC_PROTOCOL; break; } } } switch (code) { case PGI_AR_LINK: Set (SMASK_AR_OID);/* HACK! */ goto do_pgi; case PGI_CN_ID: Set (SMASK_CN_REF);/* fall */ case PGI_CN_ITEMS: do_pgi: ; pktlen += li; pgilen = li; li = 0; break; case PI_CALLED_SS: case PI_CALLING_SS: #ifdef notdef case PI_AR_CALLED: case PI_AR_CALLING:#endif switch (si) { case SPDU_CN: case SPDU_AC: s -> s_cn_reference.sr_ulen = li; bcopy (base, s -> s_cn_reference.sr_udata, li); Set (SMASK_CN_REF); break; case SPDU_RF: s -> s_rf_reference.sr_ulen = li; bcopy (base, s -> s_rf_reference.sr_udata, li); Set (SMASK_RF_REF); break; case SPDU_AR: switch (code) { case PI_AR_CALLED: s -> s_ar_reference.sr_called_len = li; bcopy (base, s -> s_ar_reference.sr_called, li); Set (SMASK_AR_REF); break; case PI_AR_CALLING: s -> s_ar_reference.sr_calling_len = li; bcopy (base, s -> s_ar_reference.sr_calling, li); Set (SMASK_AR_REF); break; default: s -> s_errno = SC_PROTOCOL; break; } break; default: s -> s_errno = SC_PROTOCOL; break; } base += li; break; case PI_COMMON_REF: #ifdef notdef case PI_AR_COMMON:#endif switch (si) { case SPDU_CN: case SPDU_AC: s -> s_cn_reference.sr_clen = li; bcopy (base, s -> s_cn_reference.sr_cdata, li); Set (SMASK_CN_REF); break; case SPDU_RF: s -> s_rf_reference.sr_clen = li; bcopy (base, s -> s_rf_reference.sr_cdata, li); Set (SMASK_RF_REF); break; case SPDU_AR: s -> s_ar_reference.sr_clen = li; bcopy (base, s -> s_ar_reference.sr_cdata, li); Set (SMASK_AR_REF); break; default: s -> s_errno = SC_PROTOCOL; break; } base += li; break; case PI_ADD_INFO: #ifdef notdef case PI_AR_ADDT:#endif switch (si) { case SPDU_CN: case SPDU_AC: s -> s_cn_reference.sr_alen = li; bcopy (base, s -> s_cn_reference.sr_adata, li); Set (SMASK_CN_REF); break; case SPDU_RF: s -> s_rf_reference.sr_alen = li; bcopy (base, s -> s_rf_reference.sr_adata, li); Set (SMASK_RF_REF); break; case SPDU_AR: s -> s_ar_reference.sr_alen = li; bcopy (base, s -> s_ar_reference.sr_adata, li); Set (SMASK_AR_REF); break; default: s -> s_errno = SC_PROTOCOL; break; } base += li; break; case PI_PROTOCOL_OPT: if ((s -> s_options = *base++) & ~CR_OPT_MASK) s -> s_errno = SC_PROTOCOL; else Set (SMASK_CN_OPT); break; case PI_TSDU_MAXSIZ: { u_long tsdu_maxsize; bcopy (base, (char *) &tsdu_maxsize, pi_length[PI_TSDU_MAXSIZ]); tsdu_maxsize = ntohl (tsdu_maxsize); s -> s_tsdu_init = (tsdu_maxsize >> 16) & 0xffff; s -> s_tsdu_resp = tsdu_maxsize & 0xffff; Set (SMASK_CN_TSDU); } base += pi_length[PI_TSDU_MAXSIZ]; break; case PI_VERSION: switch (si) { case SPDU_CN: case SPDU_AC: s -> s_cn_version = *base++; Set (SMASK_CN_VRSN); break; case SPDU_RF: s -> s_rf_version = *base++; Set (SMASK_RF_VRSN); break; default: s -> s_errno = SC_PROTOCOL; break; } break; case PI_SYNC: switch (si) { case SPDU_MIP: if ((s -> s_mip_sync = *base++) & ~MIP_SYNC_MASK) s -> s_errno = SC_PROTOCOL; else Set (SMASK_MIP_SYNC); break; case SPDU_MAP: if ((s -> s_map_sync = *base++) & ~MAP_SYNC_MASK) s -> s_errno = SC_PROTOCOL; else Set (SMASK_MAP_SYNC); break; } break; case PI_TOKEN_SET: switch (si) { case SPDU_CN: case SPDU_AC: s -> s_settings = *base++; Set (SMASK_CN_SET); break; case SPDU_RS: s -> s_rs_settings = *base++; Set (SMASK_RS_SET); break; case SPDU_RA: s -> s_ra_settings = *base++; Set (SMASK_RA_SET); break; default: s -> s_errno = SC_PROTOCOL; break; } break; case PI_TOKEN: switch (si) { case SPDU_AC: s -> s_ac_token = *base++; Set (SMASK_AC_TOKEN); break; case SPDU_GT: If_Reset (SMASK_SPDU_GT) { s -> s_errno = SC_PROTOCOL; break; } s -> s_gt_token = *base++; Set (SMASK_GT_TOKEN); break; case SPDU_PT: s -> s_pt_token = *base++; Set (SMASK_PT_TOKEN); break; default: s -> s_errno = SC_PROTOCOL; break; } break; case PI_TDISC: switch (si) { case SPDU_RF: if ((s -> s_rf_disconnect = *base++) & ~RF_DISC_MASK) s -> s_errno = SC_PROTOCOL; else Set (SMASK_RF_DISC); break; case SPDU_FN: if ((s -> s_fn_disconnect = *base++) & ~FN_DISC_MASK) s -> s_errno = SC_PROTOCOL; else Set (SMASK_FN_DISC); break; case SPDU_AB: If_Reset (SMASK_SPDU_AB) { s -> s_errno = SC_PROTOCOL; break; } if ((s -> s_ab_disconnect = *base++) & ~AB_DISC_MASK) s -> s_errno = SC_PROTOCOL; else Set (SMASK_AB_DISC); break; default: s -> s_errno = SC_PROTOCOL; break; } break; case PI_USER_REQ: { u_short requirements; bcopy (base, (char *) &requirements, 2); requirements = ntohs (requirements); if (si != SPDU_RF) { s -> s_cn_require = requirements; Set (SMASK_CN_REQ); } else { s -> s_rf_require = requirements; Set (SMASK_RF_REQ); } } base += 2; break; case PI_ISN: switch (si) { case SPDU_CN: case SPDU_AC: s -> s_isn = str2ssn (base, li); Set (SMASK_CN_ISN); break; default: s -> s_errno = SC_PROTOCOL; break; } case PI_ISN2: /* not supported yet */ base += li; break; case PI_ENCLOSE: if ((si == SPDU_DT && (s -> s_mask & SMASK_SPDU_GT)) || (si == SPDU_AI && !(s -> s_mask & SMASK_SPDU_AB))) { s -> s_errno = SC_PROTOCOL; break; } if ((s -> s_enclose = *base++) & ~ENCL_MASK) s -> s_errno = SC_PROTOCOL; else Set (SMASK_ENCLOSE); break; case PI_RESYNC: s -> s_rs_type = *base++; if (SYNC_OK (s -> s_rs_type)) Set (SMASK_RS_TYPE); else s -> s_errno = SC_PROTOCOL; break; case PI_ACT_ID: switch (si) { case SPDU_AS: s -> s_as_id.sd_len = li; bcopy (base, s -> s_as_id.sd_data, li); Set (SMASK_AS_ID); break; case SPDU_AR: if ((s -> s_mask & SMASK_AR_OID) && s -> s_ar_oid.sd_len == 0) { s -> s_ar_oid.sd_len = li; bcopy (base, s -> s_ar_oid.sd_data, li); } else { s -> s_ar_id.sd_len = li; bcopy (base, s -> s_ar_id.sd_data, li); Set (SMASK_AR_ID); } break; default: s -> s_errno = SC_PROTOCOL; break; } base += li; break; case PI_SERIAL: switch (si) { case SPDU_MIP: s -> s_mip_serial = str2ssn (base, li); Set (SMASK_MIP_SERIAL); break;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?