/[LeafOK_CVS]/pvpgn-1.7.4/src/common/addr.c
ViewVC logotype

Contents of /pvpgn-1.7.4/src/common/addr.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1.1.1 - (show annotations) (vendor branch)
Tue Jun 6 03:41:38 2006 UTC (19 years, 9 months ago) by sysadm
Branch: GNU, MAIN
CVS Tags: arelease, HEAD
Changes since 1.1: +0 -0 lines
Content type: text/x-csrc
no message

1 /*
2 * Copyright (C) 1999,2000,2001 Ross Combs (rocombs@cs.nmsu.edu)
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18 #define ADDR_INTERNAL_ACCESS
19 #include "common/setup_before.h"
20 #ifdef HAVE_STDDEF_H
21 # include <stddef.h>
22 #else
23 # ifndef NULL
24 # define NULL ((void *)0)
25 # endif
26 #endif
27 #ifdef STDC_HEADERS
28 # include <stdlib.h>
29 #else
30 # ifdef HAVE_MALLOC_H
31 # include <malloc.h>
32 # endif
33 #endif
34 #ifdef HAVE_STRING_H
35 # include <string.h>
36 #else
37 # ifdef HAVE_STRINGS_H
38 # include <strings.h>
39 # endif
40 #endif
41 #ifdef HAVE_MEMORY_H
42 # include <memory.h>
43 #endif
44 #include "compat/memset.h"
45 #include "compat/memcpy.h"
46 #include "compat/strrchr.h"
47 #include "compat/strdup.h"
48 #ifdef HAVE_SYS_TYPES_H
49 # include <sys/types.h>
50 #endif
51 #ifdef HAVE_SYS_SOCKET_H
52 # include <sys/socket.h>
53 #endif
54 #include "compat/socket.h"
55 #ifdef HAVE_SYS_PARAM_H
56 # include <sys/param.h>
57 #endif
58 #ifdef HAVE_NETINET_IN_H
59 # include <netinet/in.h>
60 #endif
61 #include "compat/netinet_in.h"
62 #ifdef HAVE_ARPA_INET_H
63 # include <arpa/inet.h>
64 #endif
65 #include "compat/inet_aton.h"
66 #include "compat/inet_ntoa.h"
67 #ifdef HAVE_NETDB_H
68 # include <netdb.h>
69 #endif
70 #ifdef HAVE_ASSERT_H
71 # include <assert.h>
72 #endif
73 #include "compat/psock.h"
74 #include "common/eventlog.h"
75 #include "common/list.h"
76 #include "common/util.h"
77 #include "common/xalloc.h"
78 #include "common/addr.h"
79 #include "common/setup_after.h"
80
81
82 static char const * netaddr_num_to_addr_str(unsigned int netipaddr, unsigned int netmask);
83
84
85 #define HACK_SIZE 4
86
87 /* both arguments are in host byte order */
88 extern char const * addr_num_to_addr_str(unsigned int ipaddr, unsigned short port)
89 {
90 static unsigned int curr=0;
91 static char temp[HACK_SIZE][64];
92 struct sockaddr_in tsa;
93
94 curr = (curr+1)%HACK_SIZE;
95
96 memset(&tsa,0,sizeof(tsa));
97 tsa.sin_family = PSOCK_AF_INET;
98 tsa.sin_port = htons((unsigned short)0);
99 tsa.sin_addr.s_addr = htonl(ipaddr);
100 sprintf(temp[curr],"%.32s:%hu",inet_ntoa(tsa.sin_addr),port);
101
102 return temp[curr];
103 }
104
105
106 /* ipaddr is in host byte order */
107 extern char const * addr_num_to_ip_str(unsigned int ipaddr)
108 {
109 static unsigned int curr=0;
110 static char temp[HACK_SIZE][64];
111 struct sockaddr_in tsa;
112
113 curr = (curr+1)%HACK_SIZE;
114
115 memset(&tsa,0,sizeof(tsa));
116 tsa.sin_family = PSOCK_AF_INET;
117 tsa.sin_port = htons((unsigned short)0);
118 tsa.sin_addr.s_addr = htonl(ipaddr);
119 sprintf(temp[curr],"%.32s",inet_ntoa(tsa.sin_addr));
120
121 return temp[curr];
122 }
123
124
125 static char const * netaddr_num_to_addr_str(unsigned int netipaddr, unsigned int netmask)
126 {
127 static unsigned int curr=0;
128 static char temp[HACK_SIZE][64];
129 struct sockaddr_in tsa;
130
131 curr = (curr+1)%HACK_SIZE;
132
133 memset(&tsa,0,sizeof(tsa));
134 tsa.sin_family = PSOCK_AF_INET;
135 tsa.sin_port = htons((unsigned short)0);
136 tsa.sin_addr.s_addr = htonl(netipaddr);
137 sprintf(temp[curr],"%.32s/0x%08x",inet_ntoa(tsa.sin_addr),netmask);
138
139 return temp[curr];
140 }
141
142
143
144 extern char const * host_lookup(char const * hoststr, unsigned int * ipaddr)
145 {
146 struct sockaddr_in tsa;
147 #ifdef HAVE_GETHOSTBYNAME
148 struct hostent * hp;
149 #endif
150
151 if (!hoststr)
152 {
153 eventlog(eventlog_level_error,__FUNCTION__,"got NULL hoststr");
154 return NULL;
155 }
156 if (!ipaddr)
157 {
158 eventlog(eventlog_level_error,__FUNCTION__,"got NULL ipaddr");
159 return NULL;
160 }
161
162 memset(&tsa,0,sizeof(tsa));
163 tsa.sin_family = PSOCK_AF_INET;
164 tsa.sin_port = htons(0);
165
166 #ifdef HAVE_GETHOSTBYNAME
167 #ifdef WIN32
168 psock_init();
169 #endif
170 hp = gethostbyname(hoststr);
171 if (!hp || !hp->h_addr_list)
172 #endif
173 {
174 if (inet_aton(hoststr,&tsa.sin_addr))
175 {
176 *ipaddr = ntohl(tsa.sin_addr.s_addr);
177 return hoststr; /* We could call gethostbyaddr() on tsa to try and get the
178 official hostname but most systems would have already found
179 it when sending a dotted-quad to gethostbyname(). This is
180 good enough when that fails. */
181 }
182 eventlog(eventlog_level_error,__FUNCTION__,"could not lookup host \"%s\"",hoststr);
183 return NULL;
184 }
185
186 #ifdef HAVE_GETHOSTBYNAME
187 memcpy(&tsa.sin_addr,(void *)hp->h_addr_list[0],sizeof(struct in_addr)); /* avoid warning */
188 *ipaddr = ntohl(tsa.sin_addr.s_addr);
189 if (hp->h_name)
190 return hp->h_name;
191 return hoststr;
192 #endif
193 }
194
195
196 extern t_addr * addr_create_num(unsigned int ipaddr, unsigned short port)
197 {
198 t_addr * temp;
199
200 temp = xmalloc(sizeof(t_addr));
201 temp->str = xstrdup(addr_num_to_addr_str(ipaddr,port));
202 temp->str = NULL;
203 temp->ip = ipaddr;
204 temp->port = port;
205 temp->data.p = NULL;
206
207 return temp;
208 }
209
210
211 extern t_addr * addr_create_str(char const * str, unsigned int defipaddr, unsigned short defport)
212 {
213 char * tstr;
214 t_addr * temp;
215 unsigned int ipaddr;
216 unsigned short port;
217 char const * hoststr;
218 char * portstr;
219 char const * hostname;
220
221 if (!str)
222 {
223 eventlog(eventlog_level_error,__FUNCTION__,"got NULL str");
224 return NULL;
225 }
226
227 tstr = xstrdup(str);
228
229 if ((portstr = strrchr(tstr,':')))
230 {
231 char * protstr;
232
233 *portstr = '\0';
234 portstr++;
235
236 if ((protstr = strrchr(portstr,'/')))
237 {
238 *protstr = '\0';
239 protstr++;
240 }
241
242 if (portstr[0]!='\0')
243 {
244 if (str_to_ushort(portstr,&port)<0)
245 {
246 #ifdef HAVE_GETSERVBYNAME
247 struct servent * sp;
248
249 if (!(sp = getservbyname(portstr,protstr?protstr:"tcp")))
250 #endif
251 {
252 eventlog(eventlog_level_error,__FUNCTION__,"could not convert \"%s\" to a port number",portstr);
253 xfree(tstr);
254 return NULL;
255 }
256 #ifdef HAVE_GETSERVBYNAME
257 port = ntohs(sp->s_port);
258 #endif
259 }
260 }
261 else
262 port = defport;
263 }
264 else
265 port = defport;
266
267 if (tstr[0]!='\0')
268 hoststr = tstr;
269 else
270 {
271 struct sockaddr_in tsa;
272
273 tsa.sin_addr.s_addr = htonl(defipaddr);
274 hoststr = inet_ntoa(tsa.sin_addr);
275 }
276
277 if (!(hostname = host_lookup(hoststr,&ipaddr)))
278 {
279 eventlog(eventlog_level_error,__FUNCTION__,"could not lookup host \"%s\"",hoststr);
280 xfree(tstr);
281 return NULL;
282 }
283
284 temp = xmalloc(sizeof(t_addr));
285 temp->str = xstrdup(hostname);
286 xfree(tstr);
287
288 temp->ip = ipaddr;
289 temp->port = port;
290 temp->data.p = NULL;
291
292 return temp;
293 }
294
295
296 extern int addr_destroy(t_addr const * addr)
297 {
298 if (!addr)
299 {
300 eventlog(eventlog_level_error,__FUNCTION__,"got NULL addr");
301 return -1;
302 }
303
304 if (addr->str)
305 xfree((void *)addr->str); /* avoid warning */
306 xfree((void *)addr); /* avoid warning */
307
308 return 0;
309 }
310
311
312 /* hostname or IP */
313 extern char * addr_get_host_str(t_addr const * addr, char * str, unsigned int len)
314 {
315 if (!addr)
316 {
317 eventlog(eventlog_level_error,__FUNCTION__,"got NULL addr");
318 return NULL;
319 }
320 if (!str)
321 {
322 eventlog(eventlog_level_error,__FUNCTION__,"got NULL str");
323 return NULL;
324 }
325 if (len<2)
326 {
327 eventlog(eventlog_level_error,__FUNCTION__,"str too short");
328 return NULL;
329 }
330
331 if (!addr->str)
332 {
333 eventlog(eventlog_level_error,__FUNCTION__,"addr has NULL str");
334 return NULL;
335 }
336
337 strncpy(str,addr->str,len-1);
338 str[len-1] = '\0';
339
340 return str;
341 }
342
343
344 /* IP:port */
345 extern char * addr_get_addr_str(t_addr const * addr, char * str, unsigned int len)
346 {
347 if (!addr)
348 {
349 eventlog(eventlog_level_error,__FUNCTION__,"got NULL addr");
350 return NULL;
351 }
352 if (!str)
353 {
354 eventlog(eventlog_level_error,__FUNCTION__,"got NULL str");
355 return NULL;
356 }
357 if (len<2)
358 {
359 eventlog(eventlog_level_error,__FUNCTION__,"str too short");
360 return NULL;
361 }
362
363 strncpy(str,addr_num_to_addr_str(addr->ip,addr->port),len-1);
364 str[len-1] = '\0';
365
366 return str;
367 }
368
369
370 extern unsigned int addr_get_ip(t_addr const * addr)
371 {
372 if (!addr)
373 {
374 eventlog(eventlog_level_error,__FUNCTION__,"got NULL addr");
375 return 0;
376 }
377
378 return addr->ip;
379 }
380
381
382 extern unsigned short addr_get_port(t_addr const * addr)
383 {
384 if (!addr)
385 {
386 eventlog(eventlog_level_error,__FUNCTION__,"got NULL addr");
387 return 0;
388 }
389
390 return addr->port;
391 }
392
393
394 extern int addr_set_data(t_addr * addr, t_addr_data data)
395 {
396 if (!addr)
397 {
398 eventlog(eventlog_level_error,__FUNCTION__,"got NULL addr");
399 return -1;
400 }
401
402 addr->data = data;
403 return 0;
404 }
405
406
407 extern t_addr_data addr_get_data(t_addr const * addr)
408 {
409 t_addr_data tdata;
410
411 if (!addr)
412 {
413 eventlog(eventlog_level_error,__FUNCTION__,"got NULL addr");
414 tdata.p = NULL;
415 return tdata;
416 }
417
418 return addr->data;
419 }
420
421
422 extern t_netaddr * netaddr_create_str(char const * netstr)
423 {
424 t_netaddr * netaddr;
425 char * temp;
426 char const * netipstr;
427 char const * netmaskstr;
428 unsigned int netip;
429 unsigned int netmask;
430
431 if (!netstr)
432 {
433 eventlog(eventlog_level_error,__FUNCTION__,"unable to allocate memory for netaddr");
434 return NULL;
435 }
436
437 temp = xstrdup(netstr);
438 if (!(netipstr = strtok(temp,"/")))
439 {
440 xfree(temp);
441 return NULL;
442 }
443 if (!(netmaskstr = strtok(NULL,"/")))
444 {
445 xfree(temp);
446 return NULL;
447 }
448
449 netaddr = xmalloc(sizeof(t_netaddr));
450
451 /* FIXME: call getnetbyname() first, then host_lookup() */
452 if (!host_lookup(netipstr,&netip))
453 {
454 eventlog(eventlog_level_error,__FUNCTION__,"could not lookup net");
455 xfree(netaddr);
456 xfree(temp);
457 return NULL;
458 }
459 netaddr->ip = netip;
460
461 if (str_to_uint(netmaskstr,&netmask)<0)
462 {
463 struct sockaddr_in tsa;
464
465 if (inet_aton(netmaskstr,&tsa.sin_addr))
466 netmask = ntohl(tsa.sin_addr.s_addr);
467 else
468 {
469 eventlog(eventlog_level_error,__FUNCTION__,"could not convert mask");
470 xfree(netaddr);
471 xfree(temp);
472 return NULL;
473 }
474 }
475 else
476 {
477 if (netmask>32)
478 {
479 eventlog(eventlog_level_error,__FUNCTION__,"network bits must be less than or equal to 32 (%u)",netmask);
480 xfree(netaddr);
481 xfree(temp);
482 return NULL;
483 }
484 /* for example, 8 -> 11111111000000000000000000000000 */
485 if (netmask!=0)
486 netmask = ~((1<<(32-netmask))-1);
487 }
488 netaddr->mask = netmask;
489
490 xfree(temp); // [zap-zero] 20020731 - (hopefully) fixed memory leak
491
492 return netaddr;
493 }
494
495
496 extern int netaddr_destroy(t_netaddr const * netaddr)
497 {
498 if (!netaddr)
499 {
500 eventlog(eventlog_level_error,__FUNCTION__,"got NULL netaddr");
501 return -1;
502 }
503
504 xfree((void *)netaddr); /* avoid warning */
505
506 return 0;
507 }
508
509
510 extern char * netaddr_get_addr_str(t_netaddr const * netaddr, char * str, unsigned int len)
511 {
512 if (!netaddr)
513 {
514 eventlog(eventlog_level_error,__FUNCTION__,"got NULL netaddr");
515 return NULL;
516 }
517 if (!str)
518 {
519 eventlog(eventlog_level_error,__FUNCTION__,"got NULL str");
520 return NULL;
521 }
522 if (len<2)
523 {
524 eventlog(eventlog_level_error,__FUNCTION__,"str too short");
525 return NULL;
526 }
527
528 strncpy(str,netaddr_num_to_addr_str(netaddr->ip,netaddr->mask),len-1); /* FIXME: format nicely with x.x.x.x/bitcount */
529 str[len-1] = '\0';
530
531 return str;
532 }
533
534
535 extern int netaddr_contains_addr_num(t_netaddr const * netaddr, unsigned int ipaddr)
536 {
537 if (!netaddr)
538 {
539 eventlog(eventlog_level_error,__FUNCTION__,"got NULL netaddr");
540 return -1;
541 }
542
543 return (ipaddr&netaddr->mask)==netaddr->ip;
544 }
545
546
547 extern int addrlist_append(t_addrlist * addrlist, char const * str, unsigned int defipaddr, unsigned short defport)
548 {
549 t_addr * addr;
550 char * tstr;
551 char * tok;
552
553 assert(addrlist != NULL);
554
555 if (!str)
556 {
557 eventlog(eventlog_level_error,__FUNCTION__,"got NULL str");
558 return -1;
559 }
560
561 tstr = xstrdup(str);
562 for (tok=strtok(tstr,","); tok; tok=strtok(NULL,",")) /* strtok modifies the string it is passed */
563 {
564 if (!(addr = addr_create_str(tok,defipaddr,defport)))
565 {
566 eventlog(eventlog_level_error,__FUNCTION__,"could not create addr");
567 xfree(tstr);
568 return -1;
569 }
570 list_append_data(addrlist,addr);
571 }
572
573 xfree(tstr);
574
575 return 0;
576 }
577
578 extern t_addrlist * addrlist_create(char const * str, unsigned int defipaddr, unsigned short defport)
579 {
580 t_addrlist * addrlist;
581
582 if (!str)
583 {
584 eventlog(eventlog_level_error,__FUNCTION__,"got NULL str");
585 return NULL;
586 }
587
588 addrlist = list_create();
589
590 if (addrlist_append(addrlist,str,defipaddr,defport)<0) {
591 eventlog(eventlog_level_error,__FUNCTION__,"could not append to newly created addrlist");
592 list_destroy(addrlist);
593 return NULL;
594 }
595
596 return addrlist;
597 }
598
599 extern int addrlist_destroy(t_addrlist * addrlist)
600 {
601 t_elem * curr;
602 t_addr * addr;
603
604 if (!addrlist)
605 {
606 eventlog(eventlog_level_error,__FUNCTION__,"got NULL addrlist");
607 return -1;
608 }
609
610 LIST_TRAVERSE(addrlist,curr)
611 {
612 if (!(addr = elem_get_data(curr)))
613 eventlog(eventlog_level_error,__FUNCTION__,"found NULL addr in list");
614 else
615 addr_destroy(addr);
616 list_remove_elem(addrlist,&curr);
617 }
618
619 return list_destroy(addrlist);
620 }
621
622
623 extern int addrlist_get_length(t_addrlist const * addrlist)
624 {
625 return list_get_length(addrlist);
626 }

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1