xref: /onnv-gate/usr/src/lib/libnsl/dial/stoa.c (revision 1219:f89f56c2d9ac)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
70Sstevel@tonic-gate  * with the License.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate  * See the License for the specific language governing permissions
120Sstevel@tonic-gate  * and limitations under the License.
130Sstevel@tonic-gate  *
140Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * CDDL HEADER END
210Sstevel@tonic-gate  */
22132Srobinson 
23132Srobinson /*
24*1219Sraf  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
25132Srobinson  * Use is subject to license terms.
26132Srobinson  */
27132Srobinson 
280Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
290Sstevel@tonic-gate /*	  All Rights Reserved  	*/
300Sstevel@tonic-gate 
31132Srobinson #pragma ident	"%Z%%M%	%I%	%E% SMI"
320Sstevel@tonic-gate 
33*1219Sraf #include "mt.h"
34*1219Sraf #include "uucp.h"
350Sstevel@tonic-gate 
360Sstevel@tonic-gate #ifdef TLI
370Sstevel@tonic-gate 
380Sstevel@tonic-gate #include <stdio.h>
390Sstevel@tonic-gate #include <string.h>
400Sstevel@tonic-gate #include <memory.h>
410Sstevel@tonic-gate #include <malloc.h>
420Sstevel@tonic-gate #include <sys/tiuser.h>
430Sstevel@tonic-gate #include <ctype.h>
44132Srobinson #define	OCT	0
45132Srobinson #define	HEX	1
46132Srobinson /*
47132Srobinson  * #include <nsaddr.h>
48132Srobinson  */
490Sstevel@tonic-gate #define	toupper(c)	(islower(c) ? _toupper(c) : (c))
500Sstevel@tonic-gate #define	todigit(c)	((int)((c) - '0'))	/* char to digit */
510Sstevel@tonic-gate #define	toxdigit(c)	((isdigit(c))?todigit(c):(toupper(c)-(int)'A'+10))
520Sstevel@tonic-gate #define	isodigit(c)	(isdigit(c) && ((c) != '9') && ((c) != '8'))
53132Srobinson #define	itoac(i)	(((i) > 9) ? ((char)((i)-10) + 'A'):((char)(i) + '0'))
540Sstevel@tonic-gate #define	MASK(n)		((1 << (n)) - 1)
550Sstevel@tonic-gate 
560Sstevel@tonic-gate #define	SBUFSIZE	128
570Sstevel@tonic-gate 
58132Srobinson /*
59132Srobinson  * #define	TRUE	1
60132Srobinson  * #define	FALSE	0
610Sstevel@tonic-gate  */
620Sstevel@tonic-gate 
630Sstevel@tonic-gate /*	local static functions	*/
64132Srobinson static int dobase(char *, char *, int);
65132Srobinson static void memcp(char *, char *, int);
66132Srobinson static char *xfer(char *, char *, unsigned, unsigned);
670Sstevel@tonic-gate 
680Sstevel@tonic-gate /*
69132Srobinson  *	stoa - convert string to address
70132Srobinson  *
71132Srobinson  *	If a string begins in \o or \O, the following address is octal
72132Srobinson  *	"  "   "       "    " \x or \X, the following address is hex
73132Srobinson  *
74132Srobinson  *	If ok, return pointer to netbuf structure.
75132Srobinson  *	A  NULL is returned on any error(s).
76132Srobinson  */
770Sstevel@tonic-gate 
78132Srobinson /* Return netbuf ptr if success */
79132Srobinson static struct netbuf *
stoa(char * str,struct netbuf * addr)80132Srobinson stoa(char *str, struct netbuf *addr)
810Sstevel@tonic-gate {
820Sstevel@tonic-gate 	int	myadr;		/* was netbuf struct allocated here ? */
830Sstevel@tonic-gate 	static	char *sbuf;
840Sstevel@tonic-gate 
850Sstevel@tonic-gate 	myadr = FALSE;
860Sstevel@tonic-gate 
87132Srobinson 	if (!str)
880Sstevel@tonic-gate 		return (NULL);
890Sstevel@tonic-gate 	while (*str && isspace(*str))	/* leading whites are OK */
900Sstevel@tonic-gate 		++str;
910Sstevel@tonic-gate 
92132Srobinson 	if (!str || !*str)	/* Nothing to convert */
930Sstevel@tonic-gate 		return (NULL);
940Sstevel@tonic-gate 
950Sstevel@tonic-gate 	if (!addr) {
96132Srobinson 		if ((addr = malloc(sizeof (struct netbuf))) == NULL)
970Sstevel@tonic-gate 			return (NULL);
98132Srobinson 
990Sstevel@tonic-gate 		myadr = TRUE;
1000Sstevel@tonic-gate 		addr->buf = NULL;
1010Sstevel@tonic-gate 		addr->maxlen = 0;
1020Sstevel@tonic-gate 		addr->len = 0;
1030Sstevel@tonic-gate 	}
1040Sstevel@tonic-gate 
1050Sstevel@tonic-gate 	if (sbuf == NULL) {
106132Srobinson 		sbuf = malloc(SBUFSIZE);
1070Sstevel@tonic-gate 		if (sbuf == NULL)
1080Sstevel@tonic-gate 			return (NULL);
1090Sstevel@tonic-gate 	}
1100Sstevel@tonic-gate 
1110Sstevel@tonic-gate 	/* Now process the address */
1120Sstevel@tonic-gate 	if (*str == '\\') {
1130Sstevel@tonic-gate 		++str;
1140Sstevel@tonic-gate 		switch (*str) {
1150Sstevel@tonic-gate 
1160Sstevel@tonic-gate 		case 'X':	/* hex */
1170Sstevel@tonic-gate 		case 'x':
1180Sstevel@tonic-gate 			addr->len = dobase(++str, sbuf, HEX);
1190Sstevel@tonic-gate 			break;
1200Sstevel@tonic-gate 
1210Sstevel@tonic-gate 		case 'o':	/* octal */
1220Sstevel@tonic-gate 		case 'O':
1230Sstevel@tonic-gate 			addr->len = dobase(++str, sbuf, OCT);
1240Sstevel@tonic-gate 			break;
1250Sstevel@tonic-gate 
1260Sstevel@tonic-gate 		default:	/* error */
1270Sstevel@tonic-gate 			addr->len = 0;
1280Sstevel@tonic-gate 			break;
1290Sstevel@tonic-gate 		}
1300Sstevel@tonic-gate 	}
1310Sstevel@tonic-gate 
1320Sstevel@tonic-gate 	if (addr->len == 0) {	/* Error in conversion */
1330Sstevel@tonic-gate 		if (myadr)
1340Sstevel@tonic-gate 			free(addr);
1350Sstevel@tonic-gate 		return (NULL);
1360Sstevel@tonic-gate 	}
137132Srobinson 	if ((addr->buf = xfer(addr->buf, sbuf, addr->len, addr->maxlen)) ==
138132Srobinson 									NULL)
1390Sstevel@tonic-gate 		return (NULL);
140132Srobinson 	return (addr);
1410Sstevel@tonic-gate }
1420Sstevel@tonic-gate 
1430Sstevel@tonic-gate /*
144132Srobinson  *	dobase :	converts a hex or octal ASCII string
145132Srobinson  *		to a binary address. Only HEX or OCT may be used
146132Srobinson  *		for type.
147132Srobinson  *	return length of binary string (in bytes), 0 if error.
148132Srobinson  *	The binary result is placed at buf.
149132Srobinson  */
1500Sstevel@tonic-gate 
1510Sstevel@tonic-gate static int
dobase(char * s,char * buf,int type)152132Srobinson dobase(char *s, char *buf, int type)
1530Sstevel@tonic-gate {
1540Sstevel@tonic-gate 	int	bp = SBUFSIZE - 1;
1550Sstevel@tonic-gate 	int	shift = 0;
1560Sstevel@tonic-gate 	char	*end;
1570Sstevel@tonic-gate 
1580Sstevel@tonic-gate 	for (end = s; *end && ((type == OCT) ? isodigit(*end) :
159132Srobinson 							isxdigit(*end)); ++end)
160132Srobinson 		;
1610Sstevel@tonic-gate 
162132Srobinson 	/*
163132Srobinson 	 * any non-white, non-digits cause address to be rejected,
164132Srobinson 	 * other fields are ignored
165132Srobinson 	 */
1660Sstevel@tonic-gate 	if ((*s == 0) || (end == s) || (!isspace(*end) && *end)) {
167132Srobinson 		(void) fprintf(stderr,
168132Srobinson 				"dobase: Illegal trailer on address string\n");
1690Sstevel@tonic-gate 		buf[0] = '\0';
1700Sstevel@tonic-gate 		return (0);
1710Sstevel@tonic-gate 	}
1720Sstevel@tonic-gate 	--end;
1730Sstevel@tonic-gate 
1740Sstevel@tonic-gate 	buf[bp] = '\0';
1750Sstevel@tonic-gate 
1760Sstevel@tonic-gate 	while (bp > 0 && end >= s) {
1770Sstevel@tonic-gate 		buf[bp] |= toxdigit(*end) << shift;
1780Sstevel@tonic-gate 		if (type == OCT) {
1790Sstevel@tonic-gate 			if (shift > 5) {
1800Sstevel@tonic-gate 				buf[--bp] = (todigit(*end) >> (8 - shift))
1810Sstevel@tonic-gate 					& MASK(shift-5);
1820Sstevel@tonic-gate 			}
1830Sstevel@tonic-gate 			if ((shift = (shift + 3) % 8) == 0)
1840Sstevel@tonic-gate 				buf[--bp] = 0;
185132Srobinson 		} else	/* hex */
1860Sstevel@tonic-gate 			if ((shift = (shift) ? 0 : 4) == 0)
187132Srobinson 				buf[--bp] = 0;
1880Sstevel@tonic-gate 		--end;
1890Sstevel@tonic-gate 	}
1900Sstevel@tonic-gate 	if (bp == 0) {
191132Srobinson 		(void) fprintf(stderr, "stoa: dobase: number to long\n");
1920Sstevel@tonic-gate 		return (0);
1930Sstevel@tonic-gate 	}
1940Sstevel@tonic-gate 
1950Sstevel@tonic-gate 	/* need to catch end case to avoid extra 0's in front	*/
1960Sstevel@tonic-gate 	if (!shift)
1970Sstevel@tonic-gate 		bp++;
1980Sstevel@tonic-gate 	memcp(buf, &buf[bp], (SBUFSIZE - bp));
1990Sstevel@tonic-gate 	return (SBUFSIZE - bp);
2000Sstevel@tonic-gate }
2010Sstevel@tonic-gate 
2020Sstevel@tonic-gate static void
memcp(char * d,char * s,int n)203132Srobinson memcp(char *d, char *s, int n)
2040Sstevel@tonic-gate {
2050Sstevel@tonic-gate 	while (n--)
2060Sstevel@tonic-gate 		*d++ = *s++;
2070Sstevel@tonic-gate }
2080Sstevel@tonic-gate 
209132Srobinson /*
210132Srobinson  * transfer block to a given destination or allocate one of the
211132Srobinson  *	right size
212132Srobinson  *	if max = 0 : ignore max
213132Srobinson  */
2140Sstevel@tonic-gate 
2150Sstevel@tonic-gate static char *
xfer(char * dest,char * src,unsigned len,unsigned max)216132Srobinson xfer(char *dest, char *src, unsigned len, unsigned max)
2170Sstevel@tonic-gate {
2180Sstevel@tonic-gate 	if (max && dest && max < len) {		/* No room */
219132Srobinson 		(void) fprintf(stderr, "xfer: destination not long enough\n");
2200Sstevel@tonic-gate 		return (NULL);
2210Sstevel@tonic-gate 	}
2220Sstevel@tonic-gate 	if (!dest)
2230Sstevel@tonic-gate 		if ((dest = malloc(len)) == NULL) {
224132Srobinson 			(void) fprintf(stderr, "xfer: malloc failed\n");
2250Sstevel@tonic-gate 			return (NULL);
2260Sstevel@tonic-gate 		}
2270Sstevel@tonic-gate 
228132Srobinson 	(void) memcpy(dest, src, (size_t)len);
2290Sstevel@tonic-gate 	return (dest);
2300Sstevel@tonic-gate }
2310Sstevel@tonic-gate #endif /* TLI */
232