145192Ssklower /*
248844Ssklower  * Copyright (c) 1990 The Regents of the University of California.
348844Ssklower  * All rights reserved.
448844Ssklower  *
548844Ssklower  * %sccs.include.redist.c%
648844Ssklower  *
7*50354Ssklower  *	@(#)ccitt_addr.c	5.3 (Berkeley) 07/01/91
848844Ssklower  */
948844Ssklower /*
1045192Ssklower  * parse CCITT addresses
1145192Ssklower  *
1245192Ssklower  * Addresses must have the format: [hpr],x121address[,userdata][,protocol]
1345192Ssklower  * items enclosed with square brackets are optional
1445192Ssklower  * 'h' or 'p' means hi priority (packet size = 128; specific to Datapac
1545192Ssklower  * and necessary only for X.25(76) and non-negotiating X.25(80) DTE's)
1645192Ssklower  * 'r' means reverse charge (remote DTE pays for call).
1745192Ssklower  * The x121address consists of an optional netid and dot, followed
1845192Ssklower  * by a dte address.
1945192Ssklower  *
2045192Ssklower  * Frank Pronk
2145192Ssklower  * The University of British Columbia
2245192Ssklower  * Laboratory for Computational Vision
2345192Ssklower  * Copyright (c) 1984
2445192Ssklower  */
2545192Ssklower 
2645192Ssklower #include <sys/types.h>
2745192Ssklower #include <sys/socket.h>
2845192Ssklower #include <netccitt/x25.h>
2945192Ssklower 
3045192Ssklower static char *copychar ();
3145192Ssklower 
ccitt_addr(addr,xp)3245192Ssklower ccitt_addr (addr, xp)
3345192Ssklower char *addr;
3445192Ssklower register struct sockaddr_x25 *xp;
3545192Ssklower {
3645192Ssklower 	register char *p, *ap, *limit;
37*50354Ssklower 	int havenet = 0;
3845192Ssklower 
3945192Ssklower 	bzero ((char *)xp, sizeof (*xp));
4045192Ssklower 	xp->x25_family = AF_CCITT;
4148844Ssklower 	xp->x25_len = sizeof(*xp);
4245192Ssklower 	p = addr;
4345192Ssklower 
4445192Ssklower 	/*
4545192Ssklower 	 * process optional priority and reverse charging flags
4645192Ssklower 	 */
4745192Ssklower 
4845192Ssklower 	if (*p == 'p' || *p == 'r' || *p == 'h') {
4945192Ssklower 		while (*p == 'p' || *p == 'r' || *p == 'h') {
5045192Ssklower 			if (*p == 'p' || *p == 'h')
5145192Ssklower 				xp->x25_opts.op_psize = X25_PS128;
5245192Ssklower 			else if (*p == 'r')
5345192Ssklower 				xp->x25_opts.op_flags |= X25_REVERSE_CHARGE;
5445192Ssklower 			p++;
5545192Ssklower 		}
5645192Ssklower 		if (*p != ',')
5745192Ssklower 			return (0);
5845192Ssklower 		p++;
5945192Ssklower 	}
6045192Ssklower 	if (*p == '\0')
6145192Ssklower 		return (0);
6245192Ssklower 
6345192Ssklower 	/*
6445192Ssklower 	 * [network id:]X.121 address
6545192Ssklower 	 */
6645192Ssklower 
6745192Ssklower 	ap = xp->x25_addr;
6845192Ssklower 	limit = ap + sizeof (xp->x25_addr) - 1;
6945192Ssklower 	while (*p) {
7045192Ssklower 		if (*p == ',')
7145192Ssklower 			break;
7245192Ssklower 		if (*p == '.' || *p == ':') {
7345192Ssklower 			if (havenet)
7445192Ssklower 				return (0);
7545192Ssklower 			havenet++;
7645192Ssklower 			xp->x25_net = atoi (xp->x25_addr);
7745192Ssklower 			p++;
7845192Ssklower 			ap = xp->x25_addr;
7945192Ssklower 			*ap = '\0';
8045192Ssklower 		}
8145192Ssklower 		if (*p < '0' || *p > '9')
8245192Ssklower 			return (0);
8345192Ssklower 		if (ap >= limit)
8445192Ssklower 			return (0);
8545192Ssklower 		*ap++ = *p++;
8645192Ssklower 	}
8745192Ssklower 	if (*p == '\0')
8845192Ssklower 		return (1);
8945192Ssklower 
9045192Ssklower 	/*
9145192Ssklower 	 * optional user data, bytes 4 to 16
9245192Ssklower 	 */
9345192Ssklower 
9445192Ssklower 	p++;
9545192Ssklower 	ap = xp->x25_udata + 4;		/* first four bytes are protocol id */
9645192Ssklower 	limit = ap + sizeof (xp->x25_udata) - 4;
97*50354Ssklower 	xp->x25_udlen = 4;
9845192Ssklower 	while (*p) {
9945192Ssklower 		if (*p == ',')
10045192Ssklower 			break;
10145192Ssklower 		if (ap >= limit)
10245192Ssklower 			return (0);
10345192Ssklower 		p = copychar (p, ap++);
10445192Ssklower 		xp->x25_udlen++;
10545192Ssklower 	}
106*50354Ssklower 	if (xp->x25_udlen == 4)
107*50354Ssklower 		xp->x25_udlen = 0;
10845192Ssklower 	if (*p == '\0')
10945192Ssklower 		return (1);
11045192Ssklower 
11145192Ssklower 	p++;
11245192Ssklower 	ap = xp->x25_udata;		/* protocol id */
113*50354Ssklower 	limit = ap + (xp->x25_udlen ? 4 : sizeof(xp->x25_udata));
11445192Ssklower 	while (*p) {
11545192Ssklower 		if (*p == ',')
11645192Ssklower 			return (0);
11745192Ssklower 		if (ap >= limit)
11845192Ssklower 			return (0);
11945192Ssklower 		p = copychar (p, ap++);
12045192Ssklower 	}
121*50354Ssklower 	if (xp->x25_udlen == 0)
122*50354Ssklower 		xp->x25_udlen = ap - xp->x25_udata;
12345192Ssklower 	return (1);
12445192Ssklower }
12545192Ssklower 
12645192Ssklower static char *
copychar(from,to)12745192Ssklower copychar (from, to)
12845192Ssklower register char *from, *to;
12945192Ssklower {
13045192Ssklower 	register int n;
13145192Ssklower 
13245192Ssklower 	if (*from != '\\' || from[1] < '0' || from[1] > '7') {
13345192Ssklower 		*to = *from++;
13445192Ssklower 		return (from);
13545192Ssklower 	}
13645192Ssklower 	n = *++from - '0';
13745192Ssklower 	from++;
13845192Ssklower 	if (*from >= '0' && *from <= '7') {
13945192Ssklower 		register int n1;
14045192Ssklower 
14145192Ssklower 		n = n*8 + *from++ - '0';
14245192Ssklower 		if (*from >= '0' && *from <= '7' && (n1 = n*8 + *from-'0') < 256) {
14345192Ssklower 			n = n1;
14445192Ssklower 			from++;
14545192Ssklower 		}
14645192Ssklower 	}
14745192Ssklower 	*to = n;
14845192Ssklower 	return (from);
14945192Ssklower }
150