]> git.meshlink.io Git - catta/blob - avahi-common/address.c
270292c60794a4b995c758e09c01e63a23e5d79a
[catta] / avahi-common / address.c
1 /* $Id$ */
2
3 /***
4   This file is part of avahi.
5
6   avahi is free software; you can redistribute it and/or modify it
7   under the terms of the GNU Lesser General Public License as
8   published by the Free Software Foundation; either version 2.1 of the
9   License, or (at your option) any later version.
10
11   avahi is distributed in the hope that it will be useful, but WITHOUT
12   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13   or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
14   Public License for more details.
15
16   You should have received a copy of the GNU Lesser General Public
17   License along with avahi; if not, write to the Free Software
18   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19   USA.
20 ***/
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <sys/types.h>
27 #include <netinet/in.h>
28 #include <sys/socket.h>
29 #include <arpa/inet.h>
30 #include <string.h>
31 #include <assert.h>
32 #include <stdio.h>
33
34 #include "address.h"
35 #include "malloc.h"
36
37 static size_t address_get_size(const AvahiAddress *a) {
38     assert(a);
39
40     if (a->proto == AVAHI_PROTO_INET)
41         return 4;
42     else if (a->proto == AVAHI_PROTO_INET6)
43         return 16;
44
45     return 0;
46 }
47
48 int avahi_address_cmp(const AvahiAddress *a, const AvahiAddress *b) {
49     assert(a);
50     assert(b);
51
52     if (a->proto != b->proto)
53         return -1;
54
55     return memcmp(a->data.data, b->data.data, address_get_size(a));
56 }
57
58 char *avahi_address_snprint(char *s, size_t length, const AvahiAddress *a) {
59     assert(s);
60     assert(length);
61     assert(a);
62
63     if (!(inet_ntop(avahi_proto_to_af(a->proto), a->data.data, s, length)))
64         return NULL;
65
66     return s;
67 }
68
69 char* avahi_reverse_lookup_name(const AvahiAddress *a, char *ret_s, size_t length) {
70     assert(ret_s);
71     assert(length > 0);
72     assert(a);
73
74     if (a->proto == AVAHI_PROTO_INET) {
75         uint32_t n = ntohl(a->data.ipv4.address);
76         snprintf(
77             ret_s, length,
78             "%u.%u.%u.%u.in-addr.arpa",
79             n & 0xFF, (n >> 8) & 0xFF, (n >> 16) & 0xFF, n >> 24);
80     } else {
81         assert(a->proto == AVAHI_PROTO_INET6);
82
83         snprintf(
84             ret_s, length,
85             "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.ip6.arpa",
86             a->data.ipv6.address[15] & 0xF, a->data.ipv6.address[15] >> 4,
87             a->data.ipv6.address[14] & 0xF, a->data.ipv6.address[14] >> 4,
88             a->data.ipv6.address[13] & 0xF, a->data.ipv6.address[13] >> 4,
89             a->data.ipv6.address[12] & 0xF, a->data.ipv6.address[12] >> 4,
90             a->data.ipv6.address[11] & 0xF, a->data.ipv6.address[11] >> 4,
91             a->data.ipv6.address[10] & 0xF, a->data.ipv6.address[10] >> 4,
92             a->data.ipv6.address[ 9] & 0xF, a->data.ipv6.address[ 9] >> 4,
93             a->data.ipv6.address[ 8] & 0xF, a->data.ipv6.address[ 8] >> 4,
94             a->data.ipv6.address[ 7] & 0xF, a->data.ipv6.address[ 7] >> 4,
95             a->data.ipv6.address[ 6] & 0xF, a->data.ipv6.address[ 6] >> 4,
96             a->data.ipv6.address[ 5] & 0xF, a->data.ipv6.address[ 5] >> 4,
97             a->data.ipv6.address[ 4] & 0xF, a->data.ipv6.address[ 4] >> 4,
98             a->data.ipv6.address[ 3] & 0xF, a->data.ipv6.address[ 3] >> 4,
99             a->data.ipv6.address[ 2] & 0xF, a->data.ipv6.address[ 2] >> 4,
100             a->data.ipv6.address[ 1] & 0xF, a->data.ipv6.address[ 1] >> 4,
101             a->data.ipv6.address[ 0] & 0xF, a->data.ipv6.address[ 0] >> 4);
102     }
103
104     return ret_s;
105 }
106
107 AvahiAddress *avahi_address_parse(const char *s, AvahiProtocol proto, AvahiAddress *ret_addr) {
108     assert(ret_addr);
109     assert(s);
110
111     if (proto == AVAHI_PROTO_UNSPEC) {
112         if (inet_pton(AF_INET, s, ret_addr->data.data) <= 0) {
113             if (inet_pton(AF_INET6, s, ret_addr->data.data) <= 0)
114                 return NULL;
115             else
116                 ret_addr->proto = AVAHI_PROTO_INET6;
117         } else
118             ret_addr->proto = AVAHI_PROTO_INET;
119     } else {
120         if (inet_pton(avahi_proto_to_af(proto), s, ret_addr->data.data) <= 0)
121             return NULL;
122
123         ret_addr->proto = proto;
124     }
125
126     return ret_addr;
127 }
128
129 int avahi_proto_to_af(AvahiProtocol proto) {
130     if (proto == AVAHI_PROTO_INET)
131         return AF_INET;
132     if (proto == AVAHI_PROTO_INET6)
133         return AF_INET6;
134
135     assert(proto == AVAHI_PROTO_UNSPEC);
136     return AF_UNSPEC;
137 }
138
139 AvahiProtocol avahi_af_to_proto(int af) {
140     if (af == AF_INET)
141         return AVAHI_PROTO_INET;
142     if (af == AF_INET6)
143         return AVAHI_PROTO_INET6;
144
145     assert(af == AF_UNSPEC);
146     return AVAHI_PROTO_UNSPEC;
147 }
148
149 const char* avahi_proto_to_string(AvahiProtocol proto) {
150     if (proto == AVAHI_PROTO_INET)
151         return "IPv4";
152     if (proto == AVAHI_PROTO_INET6)
153         return "IPv6";
154
155     assert(proto == AVAHI_PROTO_UNSPEC);
156     return "UNSPEC";
157 }