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