1 /***
2   This file is part of avahi.
3 
4   avahi is free software; you can redistribute it and/or modify it
5   under the terms of the GNU Lesser General Public License as
6   published by the Free Software Foundation; either version 2.1 of the
7   License, or (at your option) any later version.
8 
9   avahi is distributed in the hope that it will be useful, but WITHOUT
10   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11   or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
12   Public License for more details.
13 
14   You should have received a copy of the GNU Lesser General Public
15   License along with avahi; if not, write to the Free Software
16   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
17   USA.
18 ***/
19 
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23 
24 #include <assert.h>
25 #include <netdb.h>
26 #include <unistd.h>
27 #include <sys/socket.h>
28 #include <netinet/in.h>
29 #include <arpa/inet.h>
30 #include <sys/types.h>
31 
32 #include <avahi-common/gccmacro.h>
33 
34 #include "howl.h"
35 #include "warn.h"
36 
sw_ipv4_address_any(void)37 sw_ipv4_address sw_ipv4_address_any(void) {
38     sw_ipv4_address a;
39 
40     AVAHI_WARN_LINKAGE;
41 
42     a.m_addr = htonl(INADDR_ANY);
43     return a;
44 }
45 
sw_ipv4_address_loopback(void)46 sw_ipv4_address sw_ipv4_address_loopback(void) {
47     sw_ipv4_address a;
48 
49     AVAHI_WARN_LINKAGE;
50 
51     a.m_addr = htonl(INADDR_LOOPBACK);
52     return a;
53 }
54 
sw_ipv4_address_init(sw_ipv4_address * self)55 sw_result sw_ipv4_address_init(sw_ipv4_address * self) {
56     assert(self);
57 
58     AVAHI_WARN_LINKAGE;
59 
60     self->m_addr = htonl(INADDR_ANY);
61     return SW_OKAY;
62 }
63 
sw_ipv4_address_init_from_saddr(sw_ipv4_address * self,sw_saddr addr)64 sw_result sw_ipv4_address_init_from_saddr(
65     sw_ipv4_address *self,
66     sw_saddr addr) {
67 
68     assert(self);
69 
70     AVAHI_WARN_LINKAGE;
71 
72     self->m_addr = addr;
73     return SW_OKAY;
74 }
75 
sw_ipv4_address_init_from_name(sw_ipv4_address * self,sw_const_string name)76 sw_result sw_ipv4_address_init_from_name(
77     sw_ipv4_address *self,
78     sw_const_string name) {
79 
80     struct hostent *he;
81 
82     assert(self);
83     assert(name);
84 
85     AVAHI_WARN_LINKAGE;
86 
87     if (!(he = gethostbyname(name)))
88         return SW_E_UNKNOWN;
89 
90     self->m_addr = *(uint32_t*) he->h_addr;
91     return SW_OKAY;
92 }
93 
sw_ipv4_address_init_from_address(sw_ipv4_address * self,sw_ipv4_address addr)94 sw_result sw_ipv4_address_init_from_address(
95     sw_ipv4_address *self,
96     sw_ipv4_address addr) {
97 
98     assert(self);
99 
100     AVAHI_WARN_LINKAGE;
101 
102     self->m_addr = addr.m_addr;
103     return SW_OKAY;
104 }
105 
sw_ipv4_address_init_from_this_host(sw_ipv4_address * self)106 sw_result sw_ipv4_address_init_from_this_host(sw_ipv4_address *self) {
107     struct sockaddr_in sa;
108     int fd;
109     socklen_t l = sizeof(sa);
110 
111     assert(self);
112 
113     AVAHI_WARN_LINKAGE;
114 
115     /* This is so fucked up ... */
116 
117     memset(&sa, 0, sizeof(sa));
118     sa.sin_family = AF_INET;
119     sa.sin_addr.s_addr = inet_addr("192.168.1.1"); /* Ouch */
120     sa.sin_port = htons(5555);
121 
122     if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0 ||
123         connect(fd, (struct sockaddr*) &sa, sizeof(sa)) < 0 ||
124         getsockname(fd, (struct sockaddr*) &sa, &l) < 0) {
125         if (fd >= 0)
126             close(fd);
127 
128         perror("fuck");
129         return SW_E_UNKNOWN;
130     }
131 
132     assert(l == sizeof(sa));
133     close(fd);
134 
135     self->m_addr = sa.sin_addr.s_addr;
136 
137     return SW_OKAY;
138 }
139 
sw_ipv4_address_fina(AVAHI_GCC_UNUSED sw_ipv4_address self)140 sw_result sw_ipv4_address_fina(AVAHI_GCC_UNUSED sw_ipv4_address self) {
141 
142     AVAHI_WARN_LINKAGE;
143 
144     /* This is ridiculous ... */
145 
146     return SW_OKAY;
147 }
148 
sw_ipv4_address_is_any(sw_ipv4_address self)149 sw_bool sw_ipv4_address_is_any(sw_ipv4_address self) {
150     AVAHI_WARN_LINKAGE;
151     return self.m_addr == htonl(INADDR_ANY);
152 }
153 
sw_ipv4_address_saddr(sw_ipv4_address self)154 sw_saddr sw_ipv4_address_saddr(sw_ipv4_address self) {
155     AVAHI_WARN_LINKAGE;
156     return self.m_addr;
157 }
158 
sw_ipv4_address_name(sw_ipv4_address self,sw_string name,sw_uint32 len)159 sw_string sw_ipv4_address_name(
160     sw_ipv4_address self,
161     sw_string name,
162     sw_uint32 len) {
163 
164     assert(name);
165     assert(len > 0);
166 
167     AVAHI_WARN_LINKAGE;
168 
169     if (len < INET_ADDRSTRLEN)
170         return NULL;
171 
172     if (!(inet_ntop(AF_INET, &self.m_addr, name, len)))
173         return NULL;
174 
175     return name;
176 }
177 
sw_ipv4_address_decompose(sw_ipv4_address self,sw_uint8 * a1,sw_uint8 * a2,sw_uint8 * a3,sw_uint8 * a4)178 sw_result sw_ipv4_address_decompose(
179     sw_ipv4_address self,
180     sw_uint8 * a1,
181     sw_uint8 * a2,
182     sw_uint8 * a3,
183     sw_uint8 * a4) {
184 
185     uint32_t a;
186 
187     AVAHI_WARN_LINKAGE;
188 
189     a = ntohl(self.m_addr);
190 
191     assert(a1);
192     assert(a2);
193     assert(a3);
194     assert(a4);
195 
196     *a1 = (uint8_t) (a >> 24);
197     *a2 = (uint8_t) (a >> 16);
198     *a3 = (uint8_t) (a >> 8);
199     *a4 = (uint8_t) (a);
200 
201     return SW_OKAY;
202 }
203 
sw_ipv4_address_equals(sw_ipv4_address self,sw_ipv4_address addr)204 sw_bool sw_ipv4_address_equals(
205     sw_ipv4_address self,
206     sw_ipv4_address addr) {
207 
208     AVAHI_WARN_LINKAGE;
209 
210     return self.m_addr == addr.m_addr;
211 }
212 
213