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