diff options
Diffstat (limited to 'sys/netatm/uni/unisig_util.c')
-rw-r--r-- | sys/netatm/uni/unisig_util.c | 389 |
1 files changed, 389 insertions, 0 deletions
diff --git a/sys/netatm/uni/unisig_util.c b/sys/netatm/uni/unisig_util.c new file mode 100644 index 000000000000..ec4fbd06752b --- /dev/null +++ b/sys/netatm/uni/unisig_util.c @@ -0,0 +1,389 @@ +/* + * + * =================================== + * HARP | Host ATM Research Platform + * =================================== + * + * + * This Host ATM Research Platform ("HARP") file (the "Software") is + * made available by Network Computing Services, Inc. ("NetworkCS") + * "AS IS". NetworkCS does not provide maintenance, improvements or + * support of any kind. + * + * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED, + * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE + * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE. + * In no event shall NetworkCS be responsible for any damages, including + * but not limited to consequential damages, arising from or relating to + * any use of the Software or related support. + * + * Copyright 1994-1998 Network Computing Services, Inc. + * + * Copies of this Software may be made, however, the above copyright + * notice must be reproduced on all copies. + * + * @(#) $Id: unisig_util.c,v 1.9 1998/08/26 23:29:24 mks Exp $ + * + */ + +/* + * ATM Forum UNI 3.0/3.1 Signalling Manager + * ---------------------------------------- + * + * Protocol processing module + * + */ + +#ifndef lint +static char *RCSid = "@(#) $Id: unisig_util.c,v 1.9 1998/08/26 23:29:24 mks Exp $"; +#endif + +#include <netatm/kern_include.h> + +#include <netatm/uni/unisig.h> +#include <netatm/uni/unisig_var.h> +#include <netatm/uni/unisig_msg.h> + + +/* + * Free a UNISIG signalling message + * + * Free the passed message and any IEs that are attached to it + * + * Arguments: + * msg pointer to UNISIG protocol instance + * + * Returns: + * none + * + */ +void +unisig_free_msg(msg) + struct unisig_msg *msg; +{ + int i; + struct ie_generic *ie, *ienxt; + + ATM_DEBUG1("unisig_free_msg: msg=0x%x\n", msg); + + /* + * First free all the IEs + */ + for (i=0; i<UNI_MSG_IE_CNT; i++) { + ie = msg->msg_ie_vec[i]; + while (ie) { + ienxt = ie->ie_next; + atm_free(ie); + ie = ienxt; + } + } + + /* + * Finally, free the message structure itself + */ + atm_free(msg); +} + + +/* + * Verify a VCCB + * + * Search UNISIG's VCCB queue to verify that a VCCB belongs to UNISIG. + * + * Arguments: + * usp pointer to UNISIG protocol instance + * svp pointer to a VCCB + * + * Returns: + * TRUE the VCCB belongs to UNISIG + * FALSE the VCCB doesn't belong to UNISIG + * + */ +int +unisig_verify_vccb(usp, uvp) + struct unisig *usp; + struct unisig_vccb *uvp; + +{ + struct unisig_vccb *utp, *uvnext; + + for (utp = Q_HEAD(usp->us_vccq, struct unisig_vccb); + utp; utp = uvnext){ + uvnext = Q_NEXT(utp, struct unisig_vccb, uv_sigelem); + if (uvp == utp) { + return(TRUE); + } + } + return(FALSE); +} + + +/* + * Find a connection + * + * Find a VCCB given the call reference + * + * Arguments: + * usp pointer to UNISIG protocol instance + * cref the call reference to search for + * + * Returns: + * 0 there is no such VCCB + * uvp the address of the VCCB + * + */ +struct unisig_vccb * +unisig_find_conn(usp, cref) + struct unisig *usp; + u_int cref; + +{ + struct unisig_vccb *uvp, *uvnext; + + for (uvp = Q_HEAD(usp->us_vccq, struct unisig_vccb); uvp; + uvp = uvnext){ + uvnext = Q_NEXT(uvp, struct unisig_vccb, uv_sigelem); + if (uvp->uv_call_ref == cref) + break; + } + return(uvp); +} + + +/* + * Find a VCCB + * + * Find a VCCB given the VPI and VCI. + * + * Arguments: + * usp pointer to UNISIG protocol instance + * vpi the VPI to search for + * vci the VCI to search for + * dir the direction of the VCC (VCC_IN, VCC_OUT, or both). + * If dir is set to zero, return the address of any VCCB + * with the given VPI/VCI, regardless of direction. + * + * Returns: + * 0 there is no such VCCB + * uvp the address of the VCCB + * + */ +struct unisig_vccb * +unisig_find_vpvc(usp, vpi, vci, dir) + struct unisig *usp; + int vpi, vci; + u_char dir; + +{ + struct unisig_vccb *uvp, *uvnext; + + for (uvp = Q_HEAD(usp->us_vccq, struct unisig_vccb); uvp; + uvp = uvnext){ + uvnext = Q_NEXT(uvp, struct unisig_vccb, uv_sigelem); + if (uvp->uv_vpi == vpi && + uvp->uv_vci == vci && + (uvp->uv_type & dir) == dir) + break; + } + return(uvp); +} + + +/* + * Allocate a call reference value + * + * Arguments: + * usp pointer to UNISIG protocol instance + * + * Returns: + * 0 call reference not available + * cref the call reference value + * + */ +int +unisig_alloc_call_ref(usp) + struct unisig *usp; + +{ + int cref; + + /* + * Get the next call reference value + */ + cref = usp->us_cref; + + /* + * Make sure it hasn't got too large + */ + if (cref >= UNI_MSG_CALL_REF_DUMMY) { + /* XXX */ + log(LOG_ERR, "uni: call reference limit reached\n"); + return(0); + } + + /* + * Bump the call reference value + */ + usp->us_cref++; + + return(cref); +} + + +/* + * Print an ATM address + * + * Convert an ATM address into an ASCII string suitable for printing. + * + * Arguments: + * p pointer to an ATM address + * + * Returns: + * the address of a string with the ASCII representation of the + * address. This routine returns the address of a statically- + * allocated buffer, so if repeated calls to this routine are made, + * each call will destroy the result of the previous call. + * + */ +char * +unisig_addr_print(p) + Atm_addr *p; +{ + int i; + char *fp, *op, t_buff[16]; + u_char *cp; + static char strbuff[256]; + + static char nf_DCC[] = "0xX.XX.X.XXX.XX.XX.XX.XXXXXX.X"; + static char nf_ICD[] = "0xX.XX.X.XXX.XX.XX.XX.XXXXXX.X"; + static char nf_E164[] = "0xX.XXXXXXXX.XX.XX.XXXXXX.X"; + + union { + int w; + char c[4]; + } u1, u2; + + /* + * Clear the print buffer + */ + KM_ZERO(strbuff, sizeof(strbuff)); + + /* + * Select appropriate printing format + */ + switch(p->address_format) { + case T_ATM_ENDSYS_ADDR: + /* + * Select format by NSAP type + */ + switch(((Atm_addr_nsap *)p->address)->aan_afi) { + default: + case AFI_DCC: + fp = nf_DCC; + break; + case AFI_ICD: + fp = nf_ICD; + break; + case AFI_E164: + fp = nf_E164; + break; + } + + /* + * Loop through the format string, converting the NSAP + * to ASCII + */ + cp = (u_char *) p->address; + op = strbuff; + while (*fp) { + if (*fp == 'X') { + /* + * If format character is an 'X', put a + * two-digit hex representation of the + * NSAP byte in the output buffer + */ + sprintf(t_buff, "%x", *cp + 512); + strcpy(op, &t_buff[strlen(t_buff)-2]); + op++; op++; + cp++; + } else { + /* + * If format character isn't an 'X', + * just copy it to the output buffer + */ + *op = *fp; + op++; + } + fp++; + } + + break; + + case T_ATM_E164_ADDR: + /* + * Print the IA5 characters of the E.164 address + */ + for(i=0; i<p->address_length; i++) { + sprintf(&strbuff[strlen(strbuff)], "%c\0", + ((Atm_addr_e164 *)p->address)->aae_addr[i]); + } + break; + + case T_ATM_SPANS_ADDR: + /* + * Get address into integers + */ + u1.c[0] = ((Atm_addr_spans *)p->address)->aas_addr[0]; + u1.c[1] = ((Atm_addr_spans *)p->address)->aas_addr[1]; + u1.c[2] = ((Atm_addr_spans *)p->address)->aas_addr[2]; + u1.c[3] = ((Atm_addr_spans *)p->address)->aas_addr[3]; + u2.c[0] = ((Atm_addr_spans *)p->address)->aas_addr[4]; + u2.c[1] = ((Atm_addr_spans *)p->address)->aas_addr[5]; + u2.c[2] = ((Atm_addr_spans *)p->address)->aas_addr[6]; + u2.c[3] = ((Atm_addr_spans *)p->address)->aas_addr[7]; + + /* + * Print the address as two words xxxxx.yyyyyyyy + */ + sprintf(strbuff, "%x.%x", u1.w, u2.w); + break; + + case T_ATM_ABSENT: + default: + strcpy(strbuff, "-"); + } + + return(strbuff); +} + + +/* + * Print the contents of a message buffer chain + * + * Arguments: + * m pointer to a buffer + * + * Returns: + * none + * + */ +void +unisig_print_mbuf(m) + KBuffer *m; +{ + int i; + caddr_t cp; + + printf("unisig_print_mbuf:\n"); + while (m) { + KB_DATASTART(m, cp, caddr_t); + for (i = 0; i < KB_LEN(m); i++) { + if (i == 0) + printf(" bfr=0x%x: ", (int)m); + printf("%x ", (u_char)*cp++); + } + printf("<end_bfr>\n"); + m = KB_NEXT(m); + } +} |