xref: /illumos-gate/usr/src/cmd/listen/nlsaddr.c (revision 2a8bcb4e)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
22113f4232Sakaplan 
23113f4232Sakaplan /*
24113f4232Sakaplan  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
25113f4232Sakaplan  * Use is subject to license terms.
26113f4232Sakaplan  */
27113f4232Sakaplan 
287c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
297c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
307c478bd9Sstevel@tonic-gate 
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate /*
337c478bd9Sstevel@tonic-gate  * nlsaddr.c:
347c478bd9Sstevel@tonic-gate  *
357c478bd9Sstevel@tonic-gate  * name/address conversion routines for listener and nlsadmin
367c478bd9Sstevel@tonic-gate  * and other user processes.  Converts internal address <--> external addr
377c478bd9Sstevel@tonic-gate  *
387c478bd9Sstevel@tonic-gate  * internal address is any number of octets. (length must be provided)
397c478bd9Sstevel@tonic-gate  * external address is ascii/hex string. (implicit length)
407c478bd9Sstevel@tonic-gate  *
417c478bd9Sstevel@tonic-gate  *
427c478bd9Sstevel@tonic-gate  * nlscalloc:	dynamically allocates a t_call structure large enough
437c478bd9Sstevel@tonic-gate  *		to hold the external representations of addr, opt and udata.
447c478bd9Sstevel@tonic-gate  *		Use t_free to release the call structure.
457c478bd9Sstevel@tonic-gate  *
467c478bd9Sstevel@tonic-gate  * nlsaddr2c:	Convert internal address to external form.
477c478bd9Sstevel@tonic-gate  *
487c478bd9Sstevel@tonic-gate  * nlsc2addr:	Convert external address to internal form.
497c478bd9Sstevel@tonic-gate  *
507c478bd9Sstevel@tonic-gate  */
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate #include <ctype.h>
537c478bd9Sstevel@tonic-gate #include <sys/tiuser.h>
547c478bd9Sstevel@tonic-gate 
557c478bd9Sstevel@tonic-gate #ifndef	T_NONE
567c478bd9Sstevel@tonic-gate #define	T_NONE	0
577c478bd9Sstevel@tonic-gate #endif
587c478bd9Sstevel@tonic-gate 
597c478bd9Sstevel@tonic-gate /*
607c478bd9Sstevel@tonic-gate  * define DEBUGMODE for diagnostic printf's to stderr
617c478bd9Sstevel@tonic-gate  */
627c478bd9Sstevel@tonic-gate 
637c478bd9Sstevel@tonic-gate /* #define	DEBUGMODE */
647c478bd9Sstevel@tonic-gate 
657c478bd9Sstevel@tonic-gate #ifdef	DEBUGMODE
667c478bd9Sstevel@tonic-gate #include <stdio.h>
677c478bd9Sstevel@tonic-gate #endif
687c478bd9Sstevel@tonic-gate 
697c478bd9Sstevel@tonic-gate /* use to debug in listener *only* (not in user programs) */
707c478bd9Sstevel@tonic-gate /* #define DEBUG(args)	debug args */
717c478bd9Sstevel@tonic-gate 
727c478bd9Sstevel@tonic-gate #ifndef	DEBUG
737c478bd9Sstevel@tonic-gate #define DEBUG(args)
747c478bd9Sstevel@tonic-gate #endif
757c478bd9Sstevel@tonic-gate 
767c478bd9Sstevel@tonic-gate 
777c478bd9Sstevel@tonic-gate /*
787c478bd9Sstevel@tonic-gate  * asctohex(X):  convert char X to integer value
797c478bd9Sstevel@tonic-gate  *		 assumes isxdigit(X). returns integer value.
807c478bd9Sstevel@tonic-gate  *		 Note that 'a' > 'A'.  See usage in code below.
817c478bd9Sstevel@tonic-gate  */
827c478bd9Sstevel@tonic-gate 
837c478bd9Sstevel@tonic-gate #define asctohex(X)	\
847c478bd9Sstevel@tonic-gate     ((int)(isdigit(X) ? (int)(X-'0') : (X>='a') ? (X-'a')+10 : (X-'A')+10))
857c478bd9Sstevel@tonic-gate 
867c478bd9Sstevel@tonic-gate /*
877c478bd9Sstevel@tonic-gate  * externsz(I):	returns the number of chars required to hold an external
887c478bd9Sstevel@tonic-gate  *		address whose internal representation contains I octets.
897c478bd9Sstevel@tonic-gate  *		Adds enough space for a 16 char environ name to be prepended
907c478bd9Sstevel@tonic-gate  *		to the external name for the listener.
917c478bd9Sstevel@tonic-gate  */
927c478bd9Sstevel@tonic-gate 
937c478bd9Sstevel@tonic-gate #define	externsz(I)	(unsigned int)((I<<1) + 41)
947c478bd9Sstevel@tonic-gate 
957c478bd9Sstevel@tonic-gate 
967c478bd9Sstevel@tonic-gate /*
977c478bd9Sstevel@tonic-gate  * nlscalloc:	allocate a call structure large enough to hold the
987c478bd9Sstevel@tonic-gate  *		external representation of the addr, opt and udata fields.
99*2a8bcb4eSToomas Soome  *		similar to the way t_alloc works for the internal
1007c478bd9Sstevel@tonic-gate  *		representation of an address.
1017c478bd9Sstevel@tonic-gate  *
1027c478bd9Sstevel@tonic-gate  *		returns a pointer to the t_call strucure if successful,
1037c478bd9Sstevel@tonic-gate  *		a NULL pointer indicates failure. The external integer
1047c478bd9Sstevel@tonic-gate  *		t_errno will contain an error code.
1057c478bd9Sstevel@tonic-gate  *
1067c478bd9Sstevel@tonic-gate  */
1077c478bd9Sstevel@tonic-gate 
1087c478bd9Sstevel@tonic-gate struct t_call *
nlscalloc(fd)1097c478bd9Sstevel@tonic-gate nlscalloc(fd)
1107c478bd9Sstevel@tonic-gate int fd;
1117c478bd9Sstevel@tonic-gate {
1127c478bd9Sstevel@tonic-gate 	struct t_info info;
1137c478bd9Sstevel@tonic-gate 	struct t_call *call;
1147c478bd9Sstevel@tonic-gate 	register unsigned size;
1157c478bd9Sstevel@tonic-gate 	register char *p;
1167c478bd9Sstevel@tonic-gate 	extern char *malloc(), *t_alloc();
1177c478bd9Sstevel@tonic-gate 	extern int t_getinfo();
1187c478bd9Sstevel@tonic-gate 	extern char *malloc();
1197c478bd9Sstevel@tonic-gate 	extern int t_errno, errno;
1207c478bd9Sstevel@tonic-gate 
1217c478bd9Sstevel@tonic-gate 	if (t_getinfo(fd, &info) == -1)  {
1227c478bd9Sstevel@tonic-gate 		DEBUG((5, "nlscalloc: t_getinfo failed, t_errno %d errno %d"));
1237c478bd9Sstevel@tonic-gate 		return ((struct t_call *)0);
1247c478bd9Sstevel@tonic-gate 	}
1257c478bd9Sstevel@tonic-gate 
1267c478bd9Sstevel@tonic-gate 	if (!(call = (struct t_call *)t_alloc(fd, T_CALL, T_NONE)))  {
1277c478bd9Sstevel@tonic-gate 		DEBUG((5, "nlscalloc: t_alloc failed, t_errno %d errno %d"));
1287c478bd9Sstevel@tonic-gate 		return ((struct t_call *)0);
1297c478bd9Sstevel@tonic-gate 	}
1307c478bd9Sstevel@tonic-gate 
1317c478bd9Sstevel@tonic-gate 	if (size = externsz((unsigned)info.addr))
1327c478bd9Sstevel@tonic-gate 		if (!(p = malloc(size)))
1337c478bd9Sstevel@tonic-gate 			goto fail;
1347c478bd9Sstevel@tonic-gate 	if (call->addr.maxlen = size)
1357c478bd9Sstevel@tonic-gate 		call->addr.buf = p;
1367c478bd9Sstevel@tonic-gate 
1377c478bd9Sstevel@tonic-gate 	if (size = externsz((unsigned)info.options))
1387c478bd9Sstevel@tonic-gate 		if (!(p = malloc(size)))
1397c478bd9Sstevel@tonic-gate 			goto fail;
1407c478bd9Sstevel@tonic-gate 	if (call->opt.maxlen = size)
1417c478bd9Sstevel@tonic-gate 		call->opt.buf = p;
1427c478bd9Sstevel@tonic-gate 
1437c478bd9Sstevel@tonic-gate 	if (size = externsz((unsigned)info.connect))
1447c478bd9Sstevel@tonic-gate 		if (!(p = malloc(size)))
1457c478bd9Sstevel@tonic-gate 			goto fail;
1467c478bd9Sstevel@tonic-gate 	if (call->udata.maxlen = size)
1477c478bd9Sstevel@tonic-gate 		call->udata.buf = p;
1487c478bd9Sstevel@tonic-gate 
1497c478bd9Sstevel@tonic-gate 	return(call);
1507c478bd9Sstevel@tonic-gate 
1517c478bd9Sstevel@tonic-gate fail:
1527c478bd9Sstevel@tonic-gate 	DEBUG((1, "nlscalloc: malloc failed!"));
1537c478bd9Sstevel@tonic-gate 	t_free((char *)call, T_CALL);	/* t_free will release allocated mem*/
1547c478bd9Sstevel@tonic-gate 	t_errno = TSYSERR;		/* errno must be ENOMEM	*/
1557c478bd9Sstevel@tonic-gate 	return((struct t_call *)0);
1567c478bd9Sstevel@tonic-gate }
1577c478bd9Sstevel@tonic-gate 
1587c478bd9Sstevel@tonic-gate 
1597c478bd9Sstevel@tonic-gate /*
1607c478bd9Sstevel@tonic-gate  * nlsaddr2c:	given a pointer to a logical address and it's length
1617c478bd9Sstevel@tonic-gate  *		and a receiving buffer, addr2char converts the
1627c478bd9Sstevel@tonic-gate  *		logical address to the hex/ascii char
1637c478bd9Sstevel@tonic-gate  *		representation of that address.
1647c478bd9Sstevel@tonic-gate  *
1657c478bd9Sstevel@tonic-gate  * WARNING:	The receiving buffer must be large enough.
1667c478bd9Sstevel@tonic-gate  *		rcv buffer must be at least (2*len)+1 bytes.
1677c478bd9Sstevel@tonic-gate  *
1687c478bd9Sstevel@tonic-gate  */
1697c478bd9Sstevel@tonic-gate 
1707c478bd9Sstevel@tonic-gate static char hex_digits[] = "0123456789ABCDEF";
1717c478bd9Sstevel@tonic-gate 
1727c478bd9Sstevel@tonic-gate void
nlsaddr2c(charaddr,addr,len)1737c478bd9Sstevel@tonic-gate nlsaddr2c(charaddr, addr, len)
174113f4232Sakaplan char *charaddr, *addr;
175113f4232Sakaplan int len;
1767c478bd9Sstevel@tonic-gate {
1777c478bd9Sstevel@tonic-gate 	register unsigned i;
1787c478bd9Sstevel@tonic-gate 
1797c478bd9Sstevel@tonic-gate 	while (len--)  {
1807c478bd9Sstevel@tonic-gate 		i = (unsigned)*addr++;
1817c478bd9Sstevel@tonic-gate 		*charaddr++ = hex_digits[(i>>4) & 0xf];
1827c478bd9Sstevel@tonic-gate 		*charaddr++ = hex_digits[i & 0xf];
1837c478bd9Sstevel@tonic-gate 	}
1847c478bd9Sstevel@tonic-gate 	*charaddr = (char)0;
1857c478bd9Sstevel@tonic-gate }
1867c478bd9Sstevel@tonic-gate 
1877c478bd9Sstevel@tonic-gate 
1887c478bd9Sstevel@tonic-gate /*
1897c478bd9Sstevel@tonic-gate  * nlsc2addr:	Given a buffer containing the hex/ascii representation
1907c478bd9Sstevel@tonic-gate  *		of a logical address, the buffer's size and an address
1917c478bd9Sstevel@tonic-gate  *		of a receiving buffer, char2addr converts the logical
1927c478bd9Sstevel@tonic-gate  *		addr to internal format and returns the size of the logical
1937c478bd9Sstevel@tonic-gate  *		address.  A negative value is returned and the receiving
1947c478bd9Sstevel@tonic-gate  *		buffers contents are undefined if:
1957c478bd9Sstevel@tonic-gate  *
1967c478bd9Sstevel@tonic-gate  *		A.  The receiving buffer is not large enough. (rc = -1)
197*2a8bcb4eSToomas Soome  *		B.  If 'charaddr' does not contain a series of octets
1987c478bd9Sstevel@tonic-gate  *		    (strlen(charaddr) must be even). (rc = -2)
1997c478bd9Sstevel@tonic-gate  *		C.  Any character in 'charaddr' is not an ASCII hex digit.
2007c478bd9Sstevel@tonic-gate  *		    (rc = -3)
2017c478bd9Sstevel@tonic-gate  *
2027c478bd9Sstevel@tonic-gate  *	NOTE: that even if the internal representation of an address is
2037c478bd9Sstevel@tonic-gate  *	an ASCII string, there is no guarantee that the output will be
2047c478bd9Sstevel@tonic-gate  *	null terminated, thus the returned length must be used when
2057c478bd9Sstevel@tonic-gate  *	accessing the internal address.
2067c478bd9Sstevel@tonic-gate  */
2077c478bd9Sstevel@tonic-gate 
2087c478bd9Sstevel@tonic-gate 
2097c478bd9Sstevel@tonic-gate int
nlsc2addr(addr,maxlen,charaddr)2107c478bd9Sstevel@tonic-gate nlsc2addr(addr, maxlen, charaddr)
211113f4232Sakaplan char *addr, *charaddr;
212113f4232Sakaplan int maxlen;
2137c478bd9Sstevel@tonic-gate {
214113f4232Sakaplan 	int len;
215113f4232Sakaplan 	int i;
216113f4232Sakaplan 	char c;
217113f4232Sakaplan 	unsigned char val;
2187c478bd9Sstevel@tonic-gate 
2197c478bd9Sstevel@tonic-gate 	if (strlen(charaddr) & 1)
2207c478bd9Sstevel@tonic-gate 		return(-1);
2217c478bd9Sstevel@tonic-gate 
2227c478bd9Sstevel@tonic-gate 	for (len = 0; ((maxlen--) && (*charaddr)); ++len)  {
2237c478bd9Sstevel@tonic-gate 		for (i = 2,  val = 0;  i--;  )  {
2247c478bd9Sstevel@tonic-gate 			c = *charaddr++;
2257c478bd9Sstevel@tonic-gate 			if (!(isxdigit(c)))
2267c478bd9Sstevel@tonic-gate 				return(-3);
2277c478bd9Sstevel@tonic-gate 			val = (val << 4) | (unsigned char)asctohex(c);
2287c478bd9Sstevel@tonic-gate 	    	}
2297c478bd9Sstevel@tonic-gate 
2307c478bd9Sstevel@tonic-gate 		*addr++ = (char)val;
2317c478bd9Sstevel@tonic-gate 	}
2327c478bd9Sstevel@tonic-gate 
2337c478bd9Sstevel@tonic-gate #ifdef	DEBUGMODE
2347c478bd9Sstevel@tonic-gate 	fprintf(stderr, "nlsc2addr: returned length = %d\n", len);
2357c478bd9Sstevel@tonic-gate #endif
2367c478bd9Sstevel@tonic-gate 
2377c478bd9Sstevel@tonic-gate 	return(*charaddr ? -2 : len);
2387c478bd9Sstevel@tonic-gate }
2397c478bd9Sstevel@tonic-gate 
240