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