• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500v2-V1.0.0.60_1.0.38/ap/gpl/timemachine/netatalk-2.2.0/libatalk/util/
1#ifdef HAVE_CONFIG_H
2#include "config.h"
3#endif
4
5#include <sys/types.h>
6#include <netatalk/at.h>
7#include <netatalk/endian.h>
8#include <atalk/util.h>
9#include <ctype.h>
10
11/*
12 * Check whether "cp" is a valid ascii representation
13 * of an AppleTalk address and convert to a binary address.
14 * Examples of accepted forms are (in decimal, net of 4321,
15 * node of 65):
16 *
17 *	4321.65
18 *	0x10E1.41
19 *	16.225.65
20 *	0x10.E1.41
21 *
22 * If hex is used, and the first digit is one of A-F, the leading
23 * 0x is redundant. Returns 1 if the address is valid, 0 if not.
24 *
25 * Unlike Internet addresses, AppleTalk addresses can have leading
26 * 0's. This means that we can't support octal addressing.
27 */
28
29int atalk_aton(char *cp, struct at_addr *addr)
30{
31    u_int32_t val, base, n;
32    char c;
33
34    val = 0; base = 10;
35    if ( *cp == '0' && ( *++cp == 'x' || *cp == 'X' )) {
36	base = 16, cp++;
37    }
38    if ( !isdigit( *cp ) && isxdigit( *cp )) {
39	base = 16;
40    }
41
42    for ( n = 0;; n++ ) {
43	while (( c = *cp ) != '\0') {
44	    if ( isascii( c ) && isdigit( c )) {
45		val = (val * base) + (c - '0');
46		cp++;
47		continue;
48	    }
49
50	    if ( base == 16 && isascii( c ) && isxdigit( c )) {
51		val = ( val << 4 ) + ( c + 10 - ( islower( c ) ? 'a' : 'A' ));
52		cp++;
53		continue;
54	    }
55	    break;
56	}
57
58	if ( c != '.' && c != '\0' ) {
59	    return( 0 );
60	}
61
62	switch ( n ) {
63	case 0:
64	    if ( addr ) {
65		if ( val > 65535 ) {
66		    return( 0 );
67		}
68		addr->s_net = val;
69	    }
70	    if ( *cp++ ) {
71		val = 0;
72	    } else {
73		break;
74	    }
75	    continue;
76
77	case 2:
78	    if ( addr ) {
79		if ( addr->s_net > 255 ) {
80		    return( 0 );
81		}
82		addr->s_net <<= 8;
83		addr->s_net += addr->s_node;
84	    }
85	    /*FALLTHROUGH*/
86
87	case 1:
88	    if ( addr ) {
89		if ( val > 255 ) {
90		    return( 0 );
91		}
92		addr->s_node = val;
93	    }
94	    if ( *cp++ ) {
95		val = 0;
96	    } else {
97		break;
98	    }
99	    continue;
100
101	default:
102	    return( 0 );
103	}
104	break;
105    }
106
107    if ( n < 1 ) {
108	return( 0 );
109    }
110    if ( addr ) {
111	addr->s_net = htons( addr->s_net );
112    }
113    return (1);
114}
115