tsdu2spkt.c

来自「ftam等标准协议服务器和客户端的源代码。」· C语言 代码 · 共 2,171 行 · 第 1/4 页

C
2,171
字号
		    case SPDU_MAP: 			s -> s_map_serial = str2ssn (base, li);			Set (SMASK_MAP_SERIAL);			break;		    case SPDU_MIA: 			s -> s_mia_serial = str2ssn (base, li);			Set (SMASK_MIA_SERIAL);			break;		    case SPDU_MAA: 			s -> s_maa_serial = str2ssn (base, li);			Set (SMASK_MAA_SERIAL);			break;		    case SPDU_RS: 			s -> s_rs_serial = str2ssn (base, li);			Set (SMASK_RS_SSN);			break;		    case SPDU_RA: 			s -> s_ra_serial = str2ssn (base, li);			Set (SMASK_RA_SSN);			break;		    case SPDU_AR: 			s -> s_ar_serial = str2ssn (base, li);			Set (SMASK_AR_SSN);			break;		    default: 			s -> s_errno = SC_PROTOCOL;			break;		}		base += li;		break;	    case PI_MIA_DATA: 	    case PI_UDATA: 	    case PI_XDATA: 		Set (SMASK_UDATA_PGI);		if (!li)		    break;		if (si == SPDU_AB && !(s -> s_mask & SMASK_SPDU_AB)) {		    s -> s_errno = SC_PROTOCOL;		    break;		}		else		    if (li > (code != PI_XDATA ? SEGMENT_MAX : CONNECT_MAX)) {			s -> s_errno = SC_PROTOCOL;			break;		    }		s -> s_udata = malloc ((unsigned) (s -> s_ulen = li));		if (s -> s_udata == NULL) {		    s -> s_errno = SC_CONGEST;		    break;		}		bcopy (base, s -> s_udata, li);		base += li;		break;	    case PI_REASON: 		switch (si) {		    case SPDU_RF: 			s -> s_rdata = malloc ((unsigned) (s -> s_rlen = li));			if (s -> s_rdata == NULL) {			    s -> s_errno = SC_CONGEST;			    break;			}			bcopy (base, s -> s_rdata, li);			base += li;			break;		    case SPDU_ED: 			s -> s_ed_reason = *base++;			if (li == 1 && SP_OK (s -> s_ed_reason))			    Set (SMASK_ED_REASON);			else			    s -> s_errno = SC_PROTOCOL;			break;		    case SPDU_AI: 			If_Set (SMASK_SPDU_AB) {			    s -> s_errno = SC_PROTOCOL;			    break;			}			s -> s_ai_reason = *base++;			if (li == 1 && SP_OK (s -> s_ai_reason))			    Set (SMASK_AI_REASON);			else			    s -> s_errno = SC_PROTOCOL;			break;		    case SPDU_AD: 			s -> s_ad_reason = *base++;			if (li == 1 && SP_OK (s -> s_ad_reason))			    Set (SMASK_AD_REASON);			else			    s -> s_errno = SC_PROTOCOL;			break;		    default: 			s -> s_errno = SC_PROTOCOL;			break;		}		break;	    case PI_REFLECT: 		switch (si) {		    case SPDU_AB: 			If_Reset (SMASK_SPDU_AB) {			    s -> s_errno = SC_PROTOCOL;			    break;			}			if (li > AB_REFL_SIZE) {			    s -> s_errno = SC_PROTOCOL;			    break;			}			bcopy (base, (char *) s -> s_reflect, li);			Set (SMASK_AB_REFL);			break;		    case SPDU_ER: 			s -> s_udata = malloc ((unsigned) (s -> s_ulen = li));			if (s -> s_udata == NULL) {			    s -> s_errno = SC_CONGEST;			    break;			}			bcopy (base, s -> s_udata, li);			break;		    default: 			s -> s_errno = SC_PROTOCOL;			break;		}		base += li;		break;	    case PI_SSAP_CALLING: 		bcopy (base, s -> s_calling, s -> s_callinglen = li);		Set (SMASK_CN_CALLING);		base += li;		break;	    case PI_SSAP_CALLED: 		bcopy (base, s -> s_called, s -> s_calledlen = li);		Set (SMASK_CN_CALLED);		base += li;		break;	    case PI_PREPARE: 		if ((s -> s_pr_type = *base++) > PR_MAX)		    s -> s_errno = SC_PROTOCOL;		else		    Set (SMASK_PR_TYPE);		break;	    default: 		s -> s_errno = SC_PROTOCOL;		break;	}    }/* NB: caller responsible for mapping user info to s -> s_qbuf */    if (cc)	*cc = nread;    {				/* "dangling" qbuf */	register struct qbuf *qp;	if ((qp = qb -> qb_forw) != qb && qp -> qb_len <= 0) {	    remque (qp);	    free ((char *) qp);	}    }    switch (s -> s_code) {	case SPDU_AB: 	    If_Set (SMASK_SPDU_AB) {		If_Reset (SMASK_AB_DISC)		    s -> s_errno = SC_PROTOCOL;	    }	    break;	case SPDU_MIP: 	    If_Reset (SMASK_MIP_SERIAL)		s -> s_errno = SC_PROTOCOL;	    break;	case SPDU_MAP: 	    If_Reset (SMASK_MAP_SERIAL)		s -> s_errno = SC_PROTOCOL;	    break;	case SPDU_MIA: 	    If_Reset (SMASK_MIA_SERIAL)		s -> s_errno = SC_PROTOCOL;	    break;	case SPDU_MAA: 	    If_Reset (SMASK_MAA_SERIAL)		s -> s_errno = SC_PROTOCOL;	    break;	case SPDU_RS: 	    If_Reset (SMASK_RS_TYPE)		s -> s_errno = SC_PROTOCOL;	    If_Reset (SMASK_RS_SSN)		s -> s_errno = SC_PROTOCOL;	    break;	case SPDU_RA: 	    If_Reset (SMASK_RA_SSN)		s -> s_errno = SC_PROTOCOL;	    break;	case SPDU_PR: 	    If_Reset (SMASK_PR_TYPE)		s -> s_errno = SC_PROTOCOL;	    break;	case SPDU_ED: 	    If_Reset (SMASK_ED_REASON)		s -> s_errno = SC_PROTOCOL;	    break;	case SPDU_AS: 	    If_Reset (SMASK_AS_ID)		s -> s_errno = SC_PROTOCOL;	    break;	case SPDU_AR: 	    If_Reset (SMASK_AR_OID)		s -> s_errno = SC_PROTOCOL;	    If_Reset (SMASK_AR_SSN)		s -> s_errno = SC_PROTOCOL;	    If_Reset (SMASK_AR_ID)		s -> s_errno = SC_PROTOCOL;	    break;    }#ifdef	DEBUG    if (ssaplevel & ISODELOG_PDUS) {	if (strcmp (ssapfile, "-")) {	    char    file[BUFSIZ];	    FILE   *fp;	    (void) sprintf (file, ssapfile, getpid ());	    if (fp = fopen (file, "a")) {		spkt2text (fp, s, 1);		(void) fclose (fp);	    }	}	else {	    (void) fflush (stdout);	    spkt2text (stderr, s, 1);	}    }#endif    return s;}#ifdef HULA/*  */struct ssapkt *udtsdu2spkt (qb, len)struct qbuf *qb;int	len;{    register int    li;    int     nread,	    pktlen,	    pmask,	    xlen;    register char *base;    unsigned char   code,                    si;    register struct ssapkt  *s;    /*       *  Get si.     */    base = qb -> qb_data;    if  ( (s = newspkt ((int) (si = *base++))) == NULL )	return NULLSPKT;    nread = 1;    /*     *  Get li.     */    if (*((u_char *) base) == 255)	{	base += 2;		nread += 2;	s -> s_li = 		(*((u_char *) base) << 8) + *((u_char *) (base + 1));        }    else	{	s -> s_li = *((u_char *) base);	nread++;	}        pktlen = s -> s_li;    /*     *  Process the unit data PDU.     */    switch (si)	{        case SPDU_UD:	    Set (SMASK_SPDU_UD);#ifdef HULADEBUG	    printf ("\n     decoding UNITDATASPDU \n");#endif		    break;	    default:		s -> s_errno = SC_PROTOCOL;	        return s;	}    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 = OK;    base++;    while (pktlen && (s -> s_errno == OK))	{	code = *base++;#ifdef HULADEBUG	    printf ("\n     code = %x \n", code);#endif		if (*((u_char *) base) == 255)	    {	    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++;    	if (code >= PI_TABLE_LEN || !(pmask & pi_table[code]))	    {	    s -> s_errno = SC_PROTOCOL;	    break;	    }	pktlen -= (xlen + 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 PI_VERSION: 		switch (si) 		    {		    case SPDU_UD: #ifdef HULADEBUG	    printf ("\n     PIVERSION \n");#endif				s -> s_ud_version = *base++;			Set (SMASK_UD_VERSION);			break;		    default: 			s -> s_errno = SC_PROTOCOL;			break;		    }		break;	    case PI_SSAP_CALLING: #ifdef HULADEBUG	    printf ("\n     PISSAPCALLING \n");#endif			bcopy (base, s -> s_ud_calling, s -> s_ud_callinglen = li);		Set (SMASK_UD_CALLING);		base += li;		break;	    case PI_SSAP_CALLED: #ifdef HULADEBUG	    printf ("\n     PISSAPCALLED \n");#endif			bcopy (base, s -> s_ud_called, s -> s_ud_calledlen = li);		Set (SMASK_UD_CALLED);		base += li;		break;	    default: 		s -> s_errno = SC_PROTOCOL;		break;	    }       }    /* end while loop *//* NB: caller responsible for mapping user info to s -> s_qbuf */#ifdef	DEBUG    if (ssaplevel & ISODELOG_PDUS) {	if (strcmp (ssapfile, "-")) {	    char    file[BUFSIZ];	    FILE   *fp;	    (void) sprintf (file, ssapfile, getpid ());	    if (fp = fopen (file, "a")) {		spkt2text (fp, s, 1);		(void) fclose (fp);	    }	}	else {	    (void) fflush (stdout);	    spkt2text (stderr, s, 1);	}    }#endif    /*     *  Update the pointer to the user information.     */    qb -> qb_len -= (int) ( base - qb -> qb_data );    qb -> qb_data = base; #ifdef HULADEBUG	    printf ("\n     smask = %x", s -> s_mask);	    printf ("\n     calledlen = %d", s -> s_ud_calledlen);	    printf ("\n     qb_len  = %d \n", qb -> qb_len);	    for (li=0; li < 25; li++) 	    	printf (" %x ", *(base + li));	#endif	       return s;}#endif/*  */struct ssapkt *newspkt (code)int	code;{    register struct ssapkt *s;    s = (struct ssapkt *) calloc (1, sizeof *s);    if (s == NULL)	return NULL;    s -> s_code = code;    s -> s_qbuf.qb_forw = s -> s_qbuf.qb_back = &s -> s_qbuf;    return s;}int	freespkt (s)register struct ssapkt *s;{    register struct qbuf *qb,			 *qp;    if (s == NULL)	return;    switch (s -> s_code) {#ifdef HULA	case SPDU_UD:	    /*             *  Do not free any data since the user will free it.	     */	    for (qb = s -> s_qbuf.qb_forw; qb != &s -> s_qbuf; qb = qp)		{		qp = qb -> qb_forw;		remque (qb);		}	     break;#endif	case SPDU_RF: 	    if (s -> s_rdata)		free (s -> s_rdata);/* and fall... */	default: 	    if (s -> s_udata)		free (s -> s_udata);	    for (qb = s -> s_qbuf.qb_forw; qb != &s -> s_qbuf; qb = qp) {		qp = qb -> qb_forw;		remque (qb);		free ((char *) qb);	    }	    break;    }    free ((char *) s);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?