~jakub/helenos/ia64-revival

« back to all changes in this revision

Viewing changes to uspace/lib/c/generic/net/inet.c

  • Committer: Jakub Jermar
  • Date: 2011-04-13 14:45:41 UTC
  • mfrom: (527.1.397 main-clone)
  • Revision ID: jakub@jermar.eu-20110413144541-x0j3r1zxqhsljx1o
MergeĀ mainlineĀ changes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
27
 */
28
28
 
29
 
/** @addtogroup net
 
29
/** @addtogroup libc
30
30
 *  @{
31
31
 */
32
32
 
33
33
/** @file
34
 
 *  Internet protocol address conversion functions implementation.
 
34
 * Internet protocol address conversion functions implementation.
35
35
 */
36
36
 
 
37
#include <net/socket_codes.h>
 
38
#include <net/in.h>
 
39
#include <net/in6.h>
 
40
#include <net/inet.h>
 
41
 
37
42
#include <errno.h>
38
43
#include <mem.h>
39
44
#include <stdio.h>
40
45
#include <str.h>
41
46
 
42
 
#include <in.h>
43
 
#include <in6.h>
44
 
#include <inet.h>
45
 
#include <socket_codes.h>
46
 
 
47
 
int inet_ntop(uint16_t family, const uint8_t * data, char * address, size_t length){
48
 
        if((! data) || (! address)){
 
47
/** Prints the address into the character buffer.
 
48
 *
 
49
 *  @param[in] family   The address family.
 
50
 *  @param[in] data     The address data.
 
51
 *  @param[out] address The character buffer to be filled.
 
52
 *  @param[in] length   The buffer length.
 
53
 *  @return             EOK on success.
 
54
 *  @return             EINVAL if the data or address parameter is NULL.
 
55
 *  @return             ENOMEM if the character buffer is not long enough.
 
56
 *  @return             ENOTSUP if the address family is not supported.
 
57
 */
 
58
int
 
59
inet_ntop(uint16_t family, const uint8_t *data, char *address, size_t length)
 
60
{
 
61
        if ((!data) || (!address))
49
62
                return EINVAL;
50
 
        }
51
 
 
52
 
        switch(family){
53
 
                case AF_INET:
54
 
                        // check the output buffer size
55
 
                        if(length < INET_ADDRSTRLEN){
56
 
                                return ENOMEM;
57
 
                        }
58
 
                        // fill the buffer with the IPv4 address
59
 
                        snprintf(address, length, "%hhu.%hhu.%hhu.%hhu", data[0], data[1], data[2], data[3]);
60
 
                        return EOK;
61
 
                case AF_INET6:
62
 
                        // check the output buffer size
63
 
                        if(length < INET6_ADDRSTRLEN){
64
 
                                return ENOMEM;
65
 
                        }
66
 
                        // fill the buffer with the IPv6 address
67
 
                        snprintf(address, length, "%hhx%hhx:%hhx%hhx:%hhx%hhx:%hhx%hhx:%hhx%hhx:%hhx%hhx:%hhx%hhx:%hhx%hhx", data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15]);
68
 
                        return EOK;
69
 
                default:
70
 
                        return ENOTSUP;
 
63
 
 
64
        switch (family) {
 
65
        case AF_INET:
 
66
                /* Check output buffer size */
 
67
                if (length < INET_ADDRSTRLEN)
 
68
                        return ENOMEM;
 
69
                        
 
70
                /* Fill buffer with IPv4 address */
 
71
                snprintf(address, length, "%hhu.%hhu.%hhu.%hhu",
 
72
                    data[0], data[1], data[2], data[3]);
 
73
 
 
74
                return EOK;
 
75
 
 
76
        case AF_INET6:
 
77
                /* Check output buffer size */
 
78
                if (length < INET6_ADDRSTRLEN)
 
79
                        return ENOMEM;
 
80
                
 
81
                /* Fill buffer with IPv6 address */
 
82
                snprintf(address, length,
 
83
                    "%hhx%hhx:%hhx%hhx:%hhx%hhx:%hhx%hhx:%hhx%hhx:%hhx%hhx:"
 
84
                    "%hhx%hhx:%hhx%hhx",
 
85
                    data[0], data[1], data[2], data[3], data[4], data[5],
 
86
                    data[6], data[7], data[8], data[9], data[10], data[11],
 
87
                    data[12], data[13], data[14], data[15]);
 
88
                
 
89
                return EOK;
 
90
 
 
91
        default:
 
92
                return ENOTSUP;
71
93
        }
72
94
}
73
95
 
74
 
int inet_pton(uint16_t family, const char * address, uint8_t * data){
75
 
        /** The base number of the values.
76
 
         */
 
96
/** Parses the character string into the address.
 
97
 *
 
98
 *  If the string is shorter than the full address, zero bytes are added.
 
99
 *
 
100
 *  @param[in] family   The address family.
 
101
 *  @param[in] address  The character buffer to be parsed.
 
102
 *  @param[out] data    The address data to be filled.
 
103
 *  @return             EOK on success.
 
104
 *  @return             EINVAL if the data parameter is NULL.
 
105
 *  @return             ENOENT if the address parameter is NULL.
 
106
 *  @return             ENOTSUP if the address family is not supported.
 
107
 */
 
108
int inet_pton(uint16_t family, const char *address, uint8_t *data)
 
109
{
 
110
        /** The base number of the values. */
77
111
        int base;
78
 
        /** The number of bytes per a section.
79
 
         */
 
112
        /** The number of bytes per a section. */
80
113
        size_t bytes;
81
 
        /** The number of bytes of the address data.
82
 
         */
 
114
        /** The number of bytes of the address data. */
83
115
        int count;
84
116
 
85
 
        const char * next;
86
 
        char * last;
 
117
        const char *next;
 
118
        char *last;
87
119
        int index;
88
120
        size_t shift;
89
121
        unsigned long value;
90
122
 
91
 
        if(! data){
 
123
        if (!data)
92
124
                return EINVAL;
93
 
        }
94
 
 
95
 
        // set the processing parameters
96
 
        switch(family){
97
 
                case AF_INET:
98
 
                        count = 4;
99
 
                        base = 10;
100
 
                        bytes = 1;
101
 
                        break;
102
 
                case AF_INET6:
103
 
                        count = 16;
104
 
                        base = 16;
105
 
                        bytes = 4;
106
 
                        break;
107
 
                default:
108
 
                        return ENOTSUP;
109
 
        }
110
 
 
111
 
        // erase if no address
112
 
        if(! address){
 
125
 
 
126
        /* Set processing parameters */
 
127
        switch (family) {
 
128
        case AF_INET:
 
129
                count = 4;
 
130
                base = 10;
 
131
                bytes = 1;
 
132
                break;
 
133
 
 
134
        case AF_INET6:
 
135
                count = 16;
 
136
                base = 16;
 
137
                bytes = 4;
 
138
                break;
 
139
 
 
140
        default:
 
141
                return ENOTSUP;
 
142
        }
 
143
 
 
144
        /* Erase if no address */
 
145
        if (!address) {
113
146
                bzero(data, count);
114
147
                return ENOENT;
115
148
        }
116
149
 
117
 
        // process the string from the beginning
 
150
        /* Process string from the beginning */
118
151
        next = address;
119
152
        index = 0;
120
 
        do{
121
 
                // if the actual character is set
122
 
                if(next && (*next)){
 
153
        do {
 
154
                /* If the actual character is set */
 
155
                if (next && *next) {
123
156
 
124
 
                        // if not on the first character
125
 
                        if(index){
126
 
                                // move to the next character
127
 
                                ++ next;
 
157
                        /* If not on the first character */
 
158
                        if (index) {
 
159
                                /* Move to the next character */
 
160
                                ++next;
128
161
                        }
129
162
 
130
 
                        // parse the actual integral value
 
163
                        /* Parse the actual integral value */
131
164
                        value = strtoul(next, &last, base);
132
 
                        // remember the last problematic character
133
 
                        // should be either '.' or ':' but is ignored to be more generic
 
165
                        /*
 
166
                         * Remember the last problematic character
 
167
                         * should be either '.' or ':' but is ignored to be
 
168
                         * more generic
 
169
                         */
134
170
                        next = last;
135
171
 
136
 
                        // fill the address data byte by byte
 
172
                        /* Fill the address data byte by byte */
137
173
                        shift = bytes - 1;
138
 
                        do{
139
 
                                // like little endian
 
174
                        do {
 
175
                                /* like little endian */
140
176
                                data[index + shift] = value;
141
177
                                value >>= 8;
142
 
                        }while(shift --);
 
178
                        } while(shift --);
143
179
 
144
180
                        index += bytes;
145
 
                }else{
146
 
                        // erase the rest of the address
 
181
                } else {
 
182
                        /* Erase the rest of the address */
147
183
                        bzero(data + index, count - index);
148
184
                        return EOK;
149
185
                }
150
 
        }while(index < count);
 
186
        } while (index < count);
151
187
 
152
188
        return EOK;
153
189
}