source: roaraudio/libroar/nnode.c @ 3727:9905711fb84a

Last change on this file since 3727:9905711fb84a was 3517:1a3218a3fc5b, checked in by phi, 14 years ago

updated license headers, FSF moved office

File size: 8.2 KB
Line 
1//nnode.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009
5 *
6 *  This file is part of libroar a part of RoarAudio,
7 *  a cross-platform sound system for both, home and professional use.
8 *  See README for details.
9 *
10 *  This file is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License version 3
12 *  as published by the Free Software Foundation.
13 *
14 *  libroar is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this software; see the file COPYING.  If not, write to
21 *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
23 *
24 *  NOTE for everyone want's to change something and send patches:
25 *  read README and HACKING! There a addition information on
26 *  the license of this document you need to read before you send
27 *  any patches.
28 *
29 *  NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc
30 *  or libpulse*:
31 *  The libs libroaresd, libroararts and libroarpulse link this lib
32 *  and are therefore GPL. Because of this it may be illigal to use
33 *  them with any software that uses libesd, libartsc or libpulse*.
34 */
35
36#include "libroar.h"
37
38#define _CHECK(x) if ( (x) == NULL ) return -1
39
40int roar_nnode_new        (struct roar_nnode * nnode, int socktype) {
41 _CHECK(nnode);
42
43 memset(nnode, 0, sizeof(struct roar_nnode));
44
45 nnode->socktype = socktype;
46
47 return 0;
48}
49
50int roar_nnode_new_from_af(struct roar_nnode * nnode, int af) {
51 int socktype;
52
53 _CHECK(nnode);
54
55 switch (af) {
56#ifdef ROAR_HAVE_IPV4
57  case AF_INET:   socktype = ROAR_SOCKET_TYPE_INET;   break;
58#endif
59#ifdef ROAR_HAVE_IPV6
60  case AF_INET6:  socktype = ROAR_SOCKET_TYPE_INET6;  break;
61#endif
62#ifdef ROAR_HAVE_UNIX
63  case AF_UNIX:   socktype = ROAR_SOCKET_TYPE_UNIX;   break;
64#endif
65#ifdef ROAR_HAVE_LIBDNET
66  case AF_DECnet: socktype = ROAR_SOCKET_TYPE_DECNET; break;
67#endif
68#ifdef ROAR_HAVE_IPX
69  case AF_IPX:    socktype = ROAR_SOCKET_TYPE_IPX;    break;
70#endif
71  default:
72    return -1;
73   break;
74 }
75
76 if ( roar_nnode_new(nnode, socktype) == -1 )
77  return -1;
78
79 return 0;
80}
81
82int roar_nnode_new_from_sockaddr(struct roar_nnode * nnode, struct sockaddr * addr, socklen_t len) {
83 _CHECK(nnode);
84 _CHECK(addr);
85
86 ROAR_DBG("roar_nnode_new_from_sockaddr(nnode=%p, addr=%p, len=%lu) = ?", nnode, addr, (unsigned long)len);
87
88 if ( len < sizeof(addr->sa_family) )
89  return -1;
90
91 ROAR_DBG("roar_nnode_new_from_sockaddr(nnode=%p, addr=%p, len=%lu) = ?", nnode, addr, (unsigned long)len);
92
93 if ( roar_nnode_new_from_af(nnode, addr->sa_family) == -1 )
94  return -1;
95
96 ROAR_DBG("roar_nnode_new_from_sockaddr(nnode=%p, addr=%p, len=%lu) = ?", nnode, addr, (unsigned long)len);
97
98 switch (addr->sa_family) {
99#ifdef ROAR_HAVE_IPV4
100  case AF_INET:
101    if ( len < sizeof(struct sockaddr_in) )
102     return -1;
103
104    memcpy(nnode->addr.inet4, &(((struct sockaddr_in*)addr)->sin_addr), sizeof(nnode->addr.inet4));
105   break;
106#endif
107#ifdef ROAR_HAVE_IPV6
108  case AF_INET6:
109    if ( len < sizeof(struct sockaddr_in6) )
110     return -1;
111
112    memcpy(nnode->addr.inet6, ((struct sockaddr_in6*)addr)->sin6_addr.s6_addr, sizeof(nnode->addr.inet6));
113   break;
114#endif
115#ifdef ROAR_HAVE_UNIX
116  case AF_UNIX:
117    // nothing to do/save here.
118   break;
119#endif
120#ifdef ROAR_HAVE_LIBDNET
121  case AF_DECnet:
122    if ( len < sizeof(struct sockaddr_dn) )
123     return -1;
124
125    nnode->addr.decnet.node  =  ((struct sockaddr_dn*)addr)->sdn_add.a_addr[0];
126    nnode->addr.decnet.node |= (((struct sockaddr_dn*)addr)->sdn_add.a_addr[1] & 0x03) << 8;
127    nnode->addr.decnet.area  =  ((struct sockaddr_dn*)addr)->sdn_add.a_addr[1] >> 2;
128   break;
129#endif
130#ifdef ROAR_HAVE_IPX
131  case AF_IPX:
132    return -1;
133   break;
134#endif
135  default:
136    return -1;
137   break;
138 }
139
140 ROAR_DBG("roar_nnode_new_from_sockaddr(nnode=%p, addr=%p, len=%lu) = 0", nnode, addr, (unsigned long)len);
141 return 0;
142}
143
144int roar_nnode_free       (struct roar_nnode * nnode) {
145 _CHECK(nnode);
146
147 return 0;
148}
149
150int roar_nnode_get_socktype (struct roar_nnode * nnode) {
151 _CHECK(nnode);
152
153 return nnode->socktype;
154}
155
156int roar_nnode_to_str     (struct roar_nnode * nnode, char * str, size_t len) {
157 // Format: PROTO: nodename[nodeaddr]
158 char proto[7]    = "???";
159 char nodename[4] = "";
160 char nodeaddr[48 /* IPv6 */] = "???";
161
162 _CHECK(nnode);
163
164 if ( len == 0 )
165  return 0;
166
167 _CHECK(str);
168
169 if ( len == 1 ) {
170  *str = 0;
171  return 0;
172 }
173
174 switch (nnode->socktype) {
175  case ROAR_SOCKET_TYPE_UNIX:
176    strcpy(proto,     "UNIX");
177    strcpy(nodeaddr, "LOCAL");
178   break;
179  case ROAR_SOCKET_TYPE_INET:
180    strcpy(proto,     "IPv4");
181    sprintf(nodeaddr, "%i.%i.%i.%i",
182                 nnode->addr.inet4[0], nnode->addr.inet4[1],
183                 nnode->addr.inet4[2], nnode->addr.inet4[3]
184           );
185   break;
186  case ROAR_SOCKET_TYPE_DECNET:
187    strcpy(proto,     "DECnet");
188    sprintf(nodeaddr, "%i.%i", nnode->addr.decnet.area, nnode->addr.decnet.node);
189   break;
190  case ROAR_SOCKET_TYPE_INET6:
191    strcpy(proto,     "IPv6");
192   break;
193  case ROAR_SOCKET_TYPE_IPX:
194    strcpy(proto,     "IPX");
195   break;
196  default:
197    sprintf(proto, "P#%i", nnode->socktype);
198   break;
199 }
200
201 if ( *nodename ) {
202  snprintf(str, len, "%s: %s[%s]", proto, nodename, nodeaddr);
203 } else {
204  snprintf(str, len, "%s: %s", proto, nodeaddr);
205 }
206
207 str[len-1] = 0;
208
209 return 0;
210}
211
212int roar_nnode_from_blob  (struct roar_nnode * nnode, void * blob, size_t * len) {
213 uint16_t socktype;
214
215 _CHECK(nnode);
216 _CHECK(blob);
217 _CHECK(len);
218
219 if ( *len < 2 )
220  return -1;
221
222 memcpy(&socktype, blob, 2);
223
224 socktype = ROAR_NET2HOST16(socktype);
225
226 if ( roar_nnode_new(nnode, socktype) == -1 )
227  return -1;
228
229 switch (socktype) {
230  case ROAR_SOCKET_TYPE_UNIX:
231    *len = 2;
232   break;
233  case ROAR_SOCKET_TYPE_INET:
234    if ( *len < 6 )
235     return -1;
236
237    memcpy(nnode->addr.inet4, blob+2, 4);
238
239    *len = 6;
240   break;
241  case ROAR_SOCKET_TYPE_DECNET:
242    if ( *len < 4 )
243     return -1;
244
245    nnode->addr.decnet.node   =  ((unsigned char*)blob)[2];
246    nnode->addr.decnet.node   = (((unsigned char*)blob)[3] & 0x03) << 8;
247    nnode->addr.decnet.area   =  ((unsigned char*)blob)[3] >> 2;
248
249    *len = 4;
250   break;
251  case ROAR_SOCKET_TYPE_INET6:
252    if ( *len < 18 )
253     return -1;
254
255    memcpy(nnode->addr.inet4, blob+2, 16);
256
257    *len = 18;
258   break;
259  case ROAR_SOCKET_TYPE_IPX:
260  default:
261    return -1;
262   break;
263 }
264
265 return 0;
266}
267
268int roar_nnode_to_blob    (struct roar_nnode * nnode, void * blob, size_t * len) {
269 uint16_t socktype_net;
270
271 _CHECK(nnode);
272 _CHECK(blob);
273 _CHECK(len);
274
275 if ( *len < 2 )
276  return -1;
277
278 socktype_net = ROAR_HOST2NET16(nnode->socktype);
279
280 memcpy(blob, &socktype_net, 2);
281
282 switch (nnode->socktype) {
283  case ROAR_SOCKET_TYPE_UNIX:
284    // all UNIX sockets allways match.
285    *len = 2;
286   break;
287  case ROAR_SOCKET_TYPE_INET:
288    if ( *len < 6 )
289     return -1;
290
291    memcpy(blob+2, nnode->addr.inet4, 4);
292    *len = 6;
293
294   break;
295  case ROAR_SOCKET_TYPE_DECNET:
296    if ( *len < 4 )
297     return -1;
298
299    ((unsigned char*)blob)[2] =   nnode->addr.decnet.node & 0x00FF;
300    ((unsigned char*)blob)[3] = ((nnode->addr.decnet.node & 0x0300) >> 8) | (nnode->addr.decnet.area << 2);
301    *len = 4;
302
303    return -1;
304   break;
305  case ROAR_SOCKET_TYPE_INET6:
306    if ( *len < 18 )
307     return -1;
308
309    memcpy(blob+2, nnode->addr.inet4, 16);
310    *len = 18;
311
312   break;
313  case ROAR_SOCKET_TYPE_IPX:
314  default:
315    return -1;
316   break;
317 }
318
319 return 0;
320}
321
322int roar_nnode_cmp        (struct roar_nnode * n0, struct roar_nnode * n1) {
323 _CHECK(n0);
324 _CHECK(n1);
325
326 if ( n0->socktype != n1->socktype )
327  return 1;
328
329 switch (n0->socktype) {
330  case ROAR_SOCKET_TYPE_UNIX:
331    // all UNIX sockets allways match.
332   break;
333  case ROAR_SOCKET_TYPE_INET:
334    if ( memcmp(n0->addr.inet4, n1->addr.inet4, sizeof(n0->addr.inet4)) != 0 )
335     return 1;
336   break;
337  case ROAR_SOCKET_TYPE_DECNET:
338    if ( n0->addr.decnet.area != n1->addr.decnet.area ||
339         n0->addr.decnet.node != n1->addr.decnet.node   )
340     return 1;
341   break;
342  case ROAR_SOCKET_TYPE_INET6:
343    if ( memcmp(n0->addr.inet6, n1->addr.inet6, sizeof(n0->addr.inet6)) != 0 )
344     return 1;
345   break;
346  case ROAR_SOCKET_TYPE_IPX:
347  default:
348    return -1;
349   break;
350 }
351
352 return 0;
353}
354
355//ll
Note: See TracBrowser for help on using the repository browser.