145192Ssklower /*
2*48844Ssklower  * Copyright (c) 1990 The Regents of the University of California.
3*48844Ssklower  * All rights reserved.
4*48844Ssklower  *
5*48844Ssklower  * %sccs.include.redist.c%
6*48844Ssklower  *
7*48844Ssklower  *	@(#)ccitt_addr.c	5.2 (Berkeley) 04/29/91
8*48844Ssklower  */
9*48844Ssklower /*
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 
3245192Ssklower ccitt_addr (addr, xp)
3345192Ssklower char *addr;
3445192Ssklower register struct sockaddr_x25 *xp;
3545192Ssklower {
3645192Ssklower 	register char *p, *ap, *limit;
3745192Ssklower 	register int havenet = 0;
3845192Ssklower 
3945192Ssklower 	bzero ((char *)xp, sizeof (*xp));
4045192Ssklower 	xp->x25_family = AF_CCITT;
41*48844Ssklower 	xp->x25_len = sizeof(*xp);
4245192Ssklower 	xp->x25_udlen = 4;
4345192Ssklower 	p = addr;
4445192Ssklower 
4545192Ssklower 	/*
4645192Ssklower 	 * process optional priority and reverse charging flags
4745192Ssklower 	 */
4845192Ssklower 
4945192Ssklower 	if (*p == 'p' || *p == 'r' || *p == 'h') {
5045192Ssklower 		while (*p == 'p' || *p == 'r' || *p == 'h') {
5145192Ssklower 			if (*p == 'p' || *p == 'h')
5245192Ssklower 				xp->x25_opts.op_psize = X25_PS128;
5345192Ssklower 			else if (*p == 'r')
5445192Ssklower 				xp->x25_opts.op_flags |= X25_REVERSE_CHARGE;
5545192Ssklower 			p++;
5645192Ssklower 		}
5745192Ssklower 		if (*p != ',')
5845192Ssklower 			return (0);
5945192Ssklower 		p++;
6045192Ssklower 	}
6145192Ssklower 	if (*p == '\0')
6245192Ssklower 		return (0);
6345192Ssklower 
6445192Ssklower 	/*
6545192Ssklower 	 * [network id:]X.121 address
6645192Ssklower 	 */
6745192Ssklower 
6845192Ssklower 	ap = xp->x25_addr;
6945192Ssklower 	limit = ap + sizeof (xp->x25_addr) - 1;
7045192Ssklower 	while (*p) {
7145192Ssklower 		if (*p == ',')
7245192Ssklower 			break;
7345192Ssklower 		if (*p == '.' || *p == ':') {
7445192Ssklower 			if (havenet)
7545192Ssklower 				return (0);
7645192Ssklower 			havenet++;
7745192Ssklower 			xp->x25_net = atoi (xp->x25_addr);
7845192Ssklower 			p++;
7945192Ssklower 			ap = xp->x25_addr;
8045192Ssklower 			*ap = '\0';
8145192Ssklower 		}
8245192Ssklower 		if (*p < '0' || *p > '9')
8345192Ssklower 			return (0);
8445192Ssklower 		if (ap >= limit)
8545192Ssklower 			return (0);
8645192Ssklower 		*ap++ = *p++;
8745192Ssklower 	}
8845192Ssklower 	if (*p == '\0')
8945192Ssklower 		return (1);
9045192Ssklower 
9145192Ssklower 	/*
9245192Ssklower 	 * optional user data, bytes 4 to 16
9345192Ssklower 	 */
9445192Ssklower 
9545192Ssklower 	p++;
9645192Ssklower 	ap = xp->x25_udata + 4;		/* first four bytes are protocol id */
9745192Ssklower 	limit = ap + sizeof (xp->x25_udata) - 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 	}
10645192Ssklower 	if (*p == '\0')
10745192Ssklower 		return (1);
10845192Ssklower 
10945192Ssklower 	p++;
11045192Ssklower 	ap = xp->x25_udata;		/* protocol id */
11145192Ssklower 	limit = ap + 4;
11245192Ssklower 	while (*p) {
11345192Ssklower 		if (*p == ',')
11445192Ssklower 			return (0);
11545192Ssklower 		if (ap >= limit)
11645192Ssklower 			return (0);
11745192Ssklower 		p = copychar (p, ap++);
11845192Ssklower 	}
11945192Ssklower 	return (1);
12045192Ssklower }
12145192Ssklower 
12245192Ssklower static char *
12345192Ssklower copychar (from, to)
12445192Ssklower register char *from, *to;
12545192Ssklower {
12645192Ssklower 	register int n;
12745192Ssklower 
12845192Ssklower 	if (*from != '\\' || from[1] < '0' || from[1] > '7') {
12945192Ssklower 		*to = *from++;
13045192Ssklower 		return (from);
13145192Ssklower 	}
13245192Ssklower 	n = *++from - '0';
13345192Ssklower 	from++;
13445192Ssklower 	if (*from >= '0' && *from <= '7') {
13545192Ssklower 		register int n1;
13645192Ssklower 
13745192Ssklower 		n = n*8 + *from++ - '0';
13845192Ssklower 		if (*from >= '0' && *from <= '7' && (n1 = n*8 + *from-'0') < 256) {
13945192Ssklower 			n = n1;
14045192Ssklower 			from++;
14145192Ssklower 		}
14245192Ssklower 	}
14345192Ssklower 	*to = n;
14445192Ssklower 	return (from);
14545192Ssklower }
146