329 lines
6.9 KiB
C
329 lines
6.9 KiB
C
/*
|
|
*
|
|
* ===================================
|
|
* 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.
|
|
*/
|
|
|
|
#ifndef lint
|
|
#if 0 /* original (broken) import id */
|
|
static char *RCSid = "@(#) $Id: atm_addr.c,v 1.1 1998/07/09 21:45:18 johnc Exp $";
|
|
#endif
|
|
#endif
|
|
#include <sys/cdefs.h>
|
|
__FBSDID("$FreeBSD$");
|
|
|
|
/*
|
|
* User Space Library Functions
|
|
* ----------------------------
|
|
*
|
|
* ATM address utility functions
|
|
*
|
|
*/
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/param.h>
|
|
#include <sys/socket.h>
|
|
#include <net/if.h>
|
|
#include <netinet/in.h>
|
|
#include <netatm/port.h>
|
|
#include <netatm/atm.h>
|
|
#include <netatm/atm_if.h>
|
|
#include <netatm/atm_sap.h>
|
|
#include <netatm/atm_sys.h>
|
|
#include <netatm/atm_ioctl.h>
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include "libatm.h"
|
|
|
|
extern char *prog;
|
|
|
|
/*
|
|
* Get NSAP, NSAP prefix or MAC address
|
|
*
|
|
* Arguments:
|
|
* in pointer to an address in ASCII
|
|
* out pointer to a buffer for the converted address
|
|
* len the length of the output buffer
|
|
*
|
|
* Returns:
|
|
* 0 error in format
|
|
* len the length of the data in the output buffer
|
|
*
|
|
*/
|
|
int
|
|
get_hex_atm_addr(const char *in, u_char *out, int len)
|
|
{
|
|
int c_type, c_value, i, out_len, state, val = 0;
|
|
|
|
/*
|
|
* Character table
|
|
*/
|
|
static struct {
|
|
char c;
|
|
int type;
|
|
int value;
|
|
} char_table[] = {
|
|
{'.', 0, 0}, /* Type 0 -- period */
|
|
{':', 0, 0}, /* Type 0 -- colon */
|
|
{'0', 1, 0}, /* Type 1 -- hex digit */
|
|
{'1', 1, 1},
|
|
{'2', 1, 2},
|
|
{'3', 1, 3},
|
|
{'4', 1, 4},
|
|
{'5', 1, 5},
|
|
{'6', 1, 6},
|
|
{'7', 1, 7},
|
|
{'8', 1, 8},
|
|
{'9', 1, 9},
|
|
{'a', 1, 10},
|
|
{'b', 1, 11},
|
|
{'c', 1, 12},
|
|
{'d', 1, 13},
|
|
{'e', 1, 14},
|
|
{'f', 1, 15},
|
|
{'A', 1, 10},
|
|
{'B', 1, 11},
|
|
{'C', 1, 12},
|
|
{'D', 1, 13},
|
|
{'E', 1, 14},
|
|
{'F', 1, 15},
|
|
{'\0', 2, 0}, /* Type 2 -- end of input */
|
|
};
|
|
|
|
/*
|
|
* State table
|
|
*/
|
|
static struct {
|
|
int action;
|
|
int state;
|
|
} state_table[3][3] = {
|
|
/* Period Hex End */
|
|
{ { 0, 0 }, { 1, 1 }, { 2, 0} }, /* Init */
|
|
{ { 4, 0 }, { 3, 2 }, { 4, 0} }, /* C1 */
|
|
{ { 0, 2 }, { 1, 1 }, { 2, 0} }, /* C2 */
|
|
};
|
|
|
|
/*
|
|
* Initialize
|
|
*/
|
|
state = 0;
|
|
out_len = 0;
|
|
if (!strncasecmp(in, "0x", 2)) {
|
|
in += 2;
|
|
}
|
|
|
|
/*
|
|
* Loop through input until state table says to return
|
|
*/
|
|
while (1) {
|
|
/*
|
|
* Get the character type and value
|
|
*/
|
|
for (i=0; char_table[i].c; i++)
|
|
if (char_table[i].c == *in)
|
|
break;
|
|
if (char_table[i].c != *in)
|
|
return(0);
|
|
c_type = char_table[i].type;
|
|
c_value = char_table[i].value;
|
|
|
|
/*
|
|
* Process next character based on state and type
|
|
*/
|
|
switch(state_table[state][c_type].action) {
|
|
case 0:
|
|
/*
|
|
* Ignore the character
|
|
*/
|
|
break;
|
|
|
|
case 1:
|
|
/*
|
|
* Save the character's value
|
|
*/
|
|
val = c_value;
|
|
break;
|
|
|
|
case 2:
|
|
/*
|
|
* Return the assembled NSAP
|
|
*/
|
|
return(out_len);
|
|
|
|
case 3:
|
|
/*
|
|
* Assemble and save the output byte
|
|
*/
|
|
val = val << 4;
|
|
val += c_value;
|
|
out[out_len] = (u_char) val;
|
|
out_len++;
|
|
if (out_len > len)
|
|
(void)fprintf(stderr, "%s() out_len > len (%d > %d)\n",
|
|
__func__, out_len, len);
|
|
|
|
break;
|
|
|
|
case 4:
|
|
/*
|
|
* Invalid input sequence
|
|
*/
|
|
return(0);
|
|
|
|
default:
|
|
return(0);
|
|
}
|
|
|
|
/*
|
|
* Set the next state and go on to the next character
|
|
*/
|
|
state = state_table[state][c_type].state;
|
|
in++;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* Format an ATM address into a string
|
|
*
|
|
* Arguments:
|
|
* addr pointer to an atm address
|
|
*
|
|
* Returns:
|
|
* none
|
|
*
|
|
*/
|
|
char *
|
|
format_atm_addr(const Atm_addr *addr)
|
|
{
|
|
int i;
|
|
const char *nsap_format;
|
|
const Atm_addr_nsap *atm_nsap;
|
|
const Atm_addr_e164 *atm_e164;
|
|
const Atm_addr_spans *atm_spans;
|
|
const Atm_addr_pvc *atm_pvc;
|
|
static char str[256];
|
|
union {
|
|
int w;
|
|
char c[4];
|
|
} u1, u2;
|
|
|
|
static const char nsap_format_DCC[] = "0x%02x.%02x%02x.%02x.%02x%02x%02x.%02x%02x.%02x%02x.%02x%02x.%02x%02x%02x%02x%02x%02x.%02x";
|
|
static const char nsap_format_ICD[] = "0x%02x.%02x%02x.%02x.%02x%02x%02x.%02x%02x.%02x%02x.%02x%02x.%02x%02x%02x%02x%02x%02x.%02x";
|
|
static const char nsap_format_E164[] = "0x%02x.%02x%02x%02x%02x%02x%02x%02x%02x.%02x%02x.%02x%02x.%02x%02x%02x%02x%02x%02x.%02x";
|
|
|
|
/*
|
|
* Clear the returned string
|
|
*/
|
|
bzero(str, sizeof(str));
|
|
strcpy(str, "-");
|
|
|
|
/*
|
|
* Print format is determined by address type
|
|
*/
|
|
switch (addr->address_format) {
|
|
case T_ATM_ENDSYS_ADDR:
|
|
atm_nsap = (const Atm_addr_nsap *)addr->address;
|
|
switch(atm_nsap->aan_afi) {
|
|
default:
|
|
case AFI_DCC:
|
|
nsap_format = nsap_format_DCC;
|
|
break;
|
|
case AFI_ICD:
|
|
nsap_format = nsap_format_ICD;
|
|
break;
|
|
case AFI_E164:
|
|
nsap_format = nsap_format_E164;
|
|
break;
|
|
}
|
|
sprintf(str, nsap_format,
|
|
atm_nsap->aan_afi,
|
|
atm_nsap->aan_afspec[0],
|
|
atm_nsap->aan_afspec[1],
|
|
atm_nsap->aan_afspec[2],
|
|
atm_nsap->aan_afspec[3],
|
|
atm_nsap->aan_afspec[4],
|
|
atm_nsap->aan_afspec[5],
|
|
atm_nsap->aan_afspec[6],
|
|
atm_nsap->aan_afspec[7],
|
|
atm_nsap->aan_afspec[8],
|
|
atm_nsap->aan_afspec[9],
|
|
atm_nsap->aan_afspec[10],
|
|
atm_nsap->aan_afspec[11],
|
|
atm_nsap->aan_esi[0],
|
|
atm_nsap->aan_esi[1],
|
|
atm_nsap->aan_esi[2],
|
|
atm_nsap->aan_esi[3],
|
|
atm_nsap->aan_esi[4],
|
|
atm_nsap->aan_esi[5],
|
|
atm_nsap->aan_sel);
|
|
break;
|
|
|
|
case T_ATM_E164_ADDR:
|
|
atm_e164 = (const Atm_addr_e164 *)addr->address;
|
|
for(i=0; i<addr->address_length; i++) {
|
|
sprintf(&str[strlen(str)], "%c",
|
|
atm_e164->aae_addr[i]);
|
|
}
|
|
break;
|
|
|
|
case T_ATM_SPANS_ADDR:
|
|
/*
|
|
* Print SPANS address as two words, xxxx.yyyy
|
|
*/
|
|
atm_spans = (const Atm_addr_spans *)addr->address;
|
|
u1.c[0] = atm_spans->aas_addr[0];
|
|
u1.c[1] = atm_spans->aas_addr[1];
|
|
u1.c[2] = atm_spans->aas_addr[2];
|
|
u1.c[3] = atm_spans->aas_addr[3];
|
|
|
|
u2.c[0] = atm_spans->aas_addr[4];
|
|
u2.c[1] = atm_spans->aas_addr[5];
|
|
u2.c[2] = atm_spans->aas_addr[6];
|
|
u2.c[3] = atm_spans->aas_addr[7];
|
|
|
|
if (!(u1.w == 0 && u2.w == 0))
|
|
sprintf(str, "0x%08lx.%08lx",
|
|
(u_long)ntohl(u1.w), (u_long)ntohl(u2.w));
|
|
break;
|
|
|
|
case T_ATM_PVC_ADDR:
|
|
/*
|
|
* Print PVC as VPI, VCI
|
|
*/
|
|
atm_pvc = (const Atm_addr_pvc *)addr->address;
|
|
sprintf(str, "%d, %d",
|
|
ATM_PVC_GET_VPI(atm_pvc),
|
|
ATM_PVC_GET_VCI(atm_pvc));
|
|
break;
|
|
|
|
case T_ATM_ABSENT:
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return(str);
|
|
}
|