2 * Copyright (C) 1993 AmiTCP/IP Group, <amitcp-group@hut.fi>
3 * Helsinki University of Technology, Finland.
5 * Copyright (C) 2005 - 2007 The AROS Dev Team
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
25 #include <proto/dos.h>
26 #include <proto/bsdsocket.h>
29 #include <dos/rdargs.h>
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/syslog.h>
34 #include <sys/socket.h>
35 #include <sys/malloc.h>
38 #include <api/amiga_api.h>
39 #include <kern/amiga_gui.h>
40 #include <kern/amiga_includes.h>
41 #include <kern/amiga_config.h>
42 #include <kern/amiga_netdb.h>
43 #include <kern/accesscontrol.h>
45 #include "net/netdbpaths.h"
46 #include <net/sana2config.h>
47 #include <net/route.h>
48 #include <netinet/in.h>
49 #include <protos/net/if_protos.h>
51 extern struct ifnet
*iface_make(struct ssconfig
*ifc
);
53 LONG
read_netdb(struct NetDataBase
*ndb
, UBYTE
*fname
,
54 UBYTE
** errstrp
, struct CSource
*res
,
55 int prefixindex
, ULONG flags
);
58 * Global pointer for the NetDataBase
60 struct NetDataBase
*NDB
= NULL
;
63 * Global lock for the NetDatabase
65 struct SignalSemaphore ndb_Lock
;
68 * Dynamic items Database (for entries supplied by DHCP)
70 struct DynDataBase DynDB
;
73 * NDB Update Counter (used to keep resolver cache up to date)
78 * Default netdatabase name
80 STRPTR netdbname
= netdb_path
;
83 * Templates for Arexx commands and DB files
86 "WITH,I=INTERFACE,H=HOST,N=NET,S=SERVICE,P=PROTOCOL,R=ROUTE,NS=NAMESERVER,DO=DOMAIN,RC,ACC=ACCESS";
88 enum ndbtype
{ KNDB_WITH
, KNDB_IFACE
, KNDB_HOST
, KNDB_NET
, KNDB_SERV
, KNDB_PROTO
,
89 KNDB_RT
, KNDB_DNS
, KNDB_DOM
, KNDB_RC
, KNDB_ACC
};
91 STRPTR NETDBTEMPLATE
=
92 "$NAME$/A,$ENTRY$/A,$ALIAS$/M";
94 STRPTR PROTOCOL_TEMPLATE
=
95 "$NAME$/A,$NUMBER$/A/N,$ALIAS$/M";
97 enum ndbarg
{ KNDB_NAME
, KNDB_DATA
, KNDB_ALIAS
};
101 STRPTR ROUTE_TEMPLATE
=
102 "HOST/S,NET/S,DEST/A,GW=GATEWAY/A";
104 enum rtarg
{ KRT_HOST
, KRT_NET
, KRT_DEST
, KRT_GATE
, RTARGS
};
106 STRPTR ACCESS_TEMPLATE
=
107 "$PORT$/A,$HOSTMASK$/A,$ACCESS$/A,LOG/S";
109 enum accarg
{ KACC_PORT
, KACC_HOSTMASK
, KACC_ACCESS
, KACC_LOG
};
113 STRPTR WITH_TEMPLATE
=
116 enum witharg
{ WITH_FILE
, WITH_PREFIX
};
118 /* prototypes for the netdb parsing functions */
120 LONG
addwith(struct NetDataBase
*ndb
,
121 struct RDArgs
*rdargs
, UBYTE
**errstrp
, struct CSource
*res
, ULONG flags
);
122 LONG
addifent(struct NetDataBase
*ndb
,
123 struct RDArgs
*rdargs
, UBYTE
**errstrp
, struct CSource
*res
, ULONG flags
);
124 LONG
addhostent(struct NetDataBase
*ndb
,
125 struct RDArgs
*rdargs
, UBYTE
**errstrp
, struct CSource
*res
, ULONG flags
);
126 LONG
addnetent(struct NetDataBase
*ndb
,
127 struct RDArgs
*rdargs
, UBYTE
**errstrp
, struct CSource
*res
, ULONG flags
);
128 LONG
addservent(struct NetDataBase
*ndb
,
129 struct RDArgs
*rdargs
, UBYTE
**errstrp
, struct CSource
*res
, ULONG flags
);
130 LONG
addprotoent(struct NetDataBase
*ndb
,
131 struct RDArgs
*rdargs
, UBYTE
**errstrp
, struct CSource
*res
, ULONG flags
);
132 LONG
addrtent(struct NetDataBase
*ndb
,
133 struct RDArgs
*rdargs
, UBYTE
**errstrp
, struct CSource
*res
, ULONG flags
);
134 LONG
addnameservent(struct NetDataBase
*ndb
,
135 struct RDArgs
*rdargs
, UBYTE
**errstrp
, struct CSource
*res
, ULONG flags
);
136 LONG
adddomainent(struct NetDataBase
*ndb
,
137 struct RDArgs
*rdargs
, UBYTE
**errstrp
, struct CSource
*res
, ULONG flags
);
138 LONG
addrcent(struct NetDataBase
*ndb
,
139 struct RDArgs
*rdargs
, UBYTE
**errstrp
, struct CSource
*res
, ULONG flags
);
140 LONG
addaccessent(struct NetDataBase
*ndb
,
141 struct RDArgs
*rdargs
, UBYTE
**errstrp
, struct CSource
*res
, ULONG flags
);
142 LONG
addndbent(struct NetDataBase
*ndb
,
143 struct RDArgs
*rdargs
, UBYTE
**errstrp
, struct CSource
*res
, ULONG ifflags
);
145 typedef LONG (*ndb_parse_f
)(struct NetDataBase
*ndb
,
146 struct RDArgs
*rdargs
, UBYTE
**errstrp
, struct CSource
*res
, ULONG flags
);
148 /* Array of parsing functions. Note that the order is same as in the
151 ndb_parse_f ndb_parse_funs
[] = {
166 * Alloc a NetDataBase
169 alloc_netdb(struct NetDataBase
*ndb
)
171 #if defined(__AROS__)
172 D(bug("[AROSTCP](amiga_netdb.c) alloc_netdb()\n"));
176 (ndb
= bsd_malloc(sizeof (*NDB
), M_NETDB
, M_WAITOK
))) {
179 for (gl
= (struct MinList
*)&ndb
->ndb_Hosts
;
180 gl
<= (struct MinList
*)&ndb
->ndb_Domains
;
182 NewList((struct List
*)gl
);
186 ndb
->ndb_AccessCount
= 0;
187 if ((ndb
->ndb_AccessTable
=
188 bsd_malloc(TMPACTSIZE
, M_NETDB
, M_WAITOK
)) == NULL
) {
189 bsd_free(ndb
, M_NETDB
);
192 #if defined(__AROS__)
193 D(bug("[AROSTCP](amiga_netdb.c) alloc_netdb: Allocated ndb = 0x%p, ndb_AccessTable = 0x%p\n", ndb
, ndb
->ndb_AccessTable
));
195 DNETDB(else __log(LOG_DEBUG
,"Allocated ndb = 0x%p, ndb_AccessTable = 0x%p", ndb
, ndb
->ndb_AccessTable
);)
201 * Caller must have a write lock on NDB
204 free_netdb(struct NetDataBase
*ndb
)
206 struct GenentNode
*gn
;
208 #if defined(__AROS__)
209 D(bug("[AROSTCP](amiga_netdb.c) free_netdb( 0x%p )\n", ndb
));
211 for (gl
= (struct MinList
*)&ndb
->ndb_Hosts
;
212 gl
<= (struct MinList
*)&ndb
->ndb_Domains
;
214 while (gn
= (struct GenentNode
*)RemHead((struct List
*)gl
))
215 bsd_free(gn
, M_NETDB
);
217 if (ndb
->ndb_AccessTable
!= NULL
) {
218 bsd_free(ndb
->ndb_AccessTable
, M_NETDB
);
219 ndb
->ndb_AccessTable
= NULL
;
221 bsd_free(ndb
, M_NETDB
);
226 static size_t zap_size
;
230 * Copy alias list to ato, alias strings and name to cto
233 aliascpy(UBYTE
*cto
, UBYTE
*name
, UBYTE
**ato
, UBYTE
**afrom
)
236 UBYTE
*logname
= name
;
238 #if defined(__AROS__)
239 D(bug("[AROSTCP](amiga_netdb.c) aliascopy()\n"));
243 while(*cto
++ = *name
++);
244 } while (afrom
&& (name
= *afrom
++) && (*ato
++ = cto
));
249 if (cto
!= zap
+ zap_size
) {
250 __log(LOG_ERR
, "%s: mismatch in size %ld != expected %ld\n",
251 logname
, cto
- (UBYTE
*)zap
, zap_size
);
257 * Allocate a netdb node
259 * nodesize is the size of the base structure, additional space
260 * is allocated for the name and the aliases.
261 * alias is NULL terminated array of alias name pointers.
262 * Number of aliases is returned via aliasp.
264 * size field of the allocated node is set to the total size - size for
265 * the MinNode and the size field itself.
268 node_alloc(size_t nodesize
, UBYTE
*name
, UBYTE
**alias
, int *aliasp
)
270 struct GenentNode
*gn
;
271 #if defined(__AROS__)
272 D(bug("[AROSTCP](amiga_netdb.c) node_alloc()\n"));
275 nodesize
+= strlen(name
) + 1; /* Add space needed for the name */
278 nodesize
+= sizeof (char*); /* Alias list NULL terminator */
280 /* Calculate the size of the aliases */
284 nodesize
+= strlen(*alias
++) + 1 + sizeof (char*);
287 gn
= bsd_malloc(nodesize
, M_NETDB
, M_WAITOK
);
292 gn
->gn_EntSize
= nodesize
- sizeof (struct GenentNode
);
302 * Parse an include entry.
305 addwith(struct NetDataBase
*ndb
,
306 struct RDArgs
*rdargs
,
307 UBYTE
**errstrp
, struct CSource
*res
, ULONG flags
)
309 // UBYTE result[REPLYBUFLEN + 1];
310 //struct CSource res;
311 LONG retval
= RETURN_OK
;
312 IPTR Args
[WITHARGS
] = { 0 };
315 #if defined(__AROS__)
316 D(bug("[AROSTCP](amiga_netdb.c) addwith()\n"));
319 /* res.CS_Buffer = result;
320 res.CS_Length = sizeof (result);
323 if (rdargs
= ReadArgs(WITH_TEMPLATE
, Args
, rdargs
)) {
324 if (Args
[WITH_PREFIX
] == 0) /* no prefix given */
327 /* match given prefix */
328 which
= FindArg(NETDBENTRY
, (UBYTE
*)Args
[WITH_PREFIX
]);
330 *errstrp
= ERR_VALUE
;
331 retval
= RETURN_WARN
;
334 if (retval
== RETURN_OK
) {
335 retval
= read_netdb(ndb
, (UBYTE
*)Args
[WITH_FILE
], errstrp
, res
,
340 *errstrp
= ERR_SYNTAX
; retval
= RETURN_WARN
;
345 /* Copy an address */
346 static int inline setaddr(struct sockaddr_in
*sa
, char *addr
, u_short af
)
348 sa
->sin_len
= sizeof(struct sockaddr_in
);
350 return __inet_aton(addr
, &sa
->sin_addr
);
354 * Parse an interface entry.
357 addifent(struct NetDataBase
*ndb
,
358 struct RDArgs
*rdargs
,
359 UBYTE
**errstrp
, struct CSource
*res
, ULONG flags
)
361 struct ssconfig
*ssc
;
363 struct ifaliasreq ifr
;
365 LONG retval
= RETURN_OK
;
367 #if defined(__AROS__)
368 D(bug("[AROSTCP](amiga_netdb.c) addifent()\n"));
371 if (flags
& (NETDB_IFF_MODIFYOLD
|NETDB_IFF_ADDNEW
)) {
372 ssc
= ssconfig_parse(rdargs
);
374 ifp
= ifunit(ssc
->args
->a_name
);
375 if ((!ifp
) && (flags
& NETDB_IFF_ADDNEW
)) {
376 DIFCONF(Printf("Adding new interface %s\n", ssc
->args
->a_name
);)
377 cp
= strncpy(ssc
->name
, ssc
->args
->a_name
, IFNAMSIZ
);
378 ssc
->name
[IFNAMSIZ
-1] = '\0';
381 if (*cp
>= '0' && *cp
<= '9')
385 for (ssc
->unit
= 0; *cp
>= '0' && *cp
<= '9'; )
386 ssc
->unit
= ssc
->unit
* 10 + *cp
++ - '0';
389 ifp
= iface_make(ssc
);
391 #if defined(__AROS__)
392 D(bug("[AROSTCP](amiga_netdb.c) addifent: failed to create interface '%s'\n", ssc
->args
->a_name
));
394 *errstrp
= ERR_MEMORY
;
395 retval
= RETURN_FAIL
;
399 #if defined(__AROS__)
400 D(bug("[AROSTCP](amiga_netdb.c) addifent: created new interface '%s'\n", ssc
->args
->a_name
));
402 flags
|= NETDB_IFF_MODIFYOLD
;
405 if ((ifp
) && (flags
& NETDB_IFF_MODIFYOLD
))
407 #if defined(__AROS__)
408 D(bug("[AROSTCP](amiga_netdb.c) addifent: configuring interface '%s'\n", ssc
->args
->a_name
));
410 DIFCONF(Printf("Setting up interface %s\n", ssc
->args
->a_name
);)
411 memset (&ifr
, 0, sizeof (ifr
));
412 if (ssc
->args
->a_ip
) {
413 if (!ssc
->args
->a_up
) {
414 DIFCONF(Printf("> No auto-online\n");)
415 ifp
->if_flags
|= IFF_NOUP
;
417 DIFCONF(Printf("> IP address: %s\n", ssc
->args
->a_ip
);)
418 if (stricmp(ssc
->args
->a_ip
, "DHCP")) {
419 ifp
->if_data
.ifi_aros_usedhcp
= 0;
420 if (setaddr ((struct sockaddr_in
*)&ifr
.ifra_addr
, ssc
->args
->a_ip
, AF_INET
)) {
421 if (ssc
->args
->a_netmask
) {
422 DIFCONF(Printf("> Netmask: %s\n", ssc
->args
->a_netmask
);)
423 if (!setaddr ((struct sockaddr_in
*)&ifr
.ifra_mask
, ssc
->args
->a_netmask
, AF_UNSPEC
)) {
424 *errstrp
= ERR_SYNTAX
;
425 retval
= RETURN_WARN
;
428 in_control(NULL
, SIOCAIFADDR
, &ifr
, ifp
);
430 *errstrp
= ERR_SYNTAX
;
431 retval
= RETURN_WARN
;
434 DIFCONF(Printf("> Using DHCP\n");)
435 ifp
->if_data
.ifi_aros_usedhcp
= 1;
436 if (ssc
->args
->a_up
) {
437 if (api_state
== API_SHOWN
)
440 ifp
->if_flags
|= IFF_DELAYUP
;
447 #if defined(__AROS__)
448 D(bug("[AROSTCP](amiga_netdb.c) addifent: Interface named '%s' already exists..\n", ssc
->args
->a_name
));
453 *errstrp
= ERR_SYNTAX
;
454 retval
= RETURN_WARN
;
462 * Parse a service entry.
465 addservent(struct NetDataBase
*ndb
,
466 struct RDArgs
*rdargs
,
467 UBYTE
**errstrp
, struct CSource
*res
, ULONG flags
)
470 IPTR Args
[NDBARGS
] = { 0 };
471 struct ServentNode
*sn
;
474 #if defined(__AROS__)
475 D(bug("[AROSTCP](amiga_netdb.c) addservent()\n"));
478 if (rdargs
= ReadArgs(NETDBTEMPLATE
, Args
, rdargs
)) {
479 /* convert port number */
480 UBYTE
*s_proto
= (UBYTE
*)Args
[KNDB_DATA
];
482 if ((plen
= StrToLong(s_proto
, &tmp
)) > 0 &&
483 s_proto
[plen
++] == '/') {
484 Args
[KNDB_DATA
] = tmp
;
485 int protonamelen
= strlen(s_proto
= s_proto
+ plen
) + 1;
486 sn
= node_alloc(sizeof (*sn
) + protonamelen
,
487 (UBYTE
*)Args
[KNDB_NAME
],
488 (UBYTE
**)Args
[KNDB_ALIAS
], &aliases
);
490 UBYTE
**alias
= (UBYTE
**)(sn
+1);
491 UBYTE
*name
= (UBYTE
*)(alias
+ aliases
);
493 sn
->sn_Ent
.s_port
= Args
[KNDB_DATA
];
494 sn
->sn_Ent
.s_proto
= strcpy(name
, s_proto
);
495 sn
->sn_Ent
.s_name
= name
+ protonamelen
;
496 sn
->sn_Ent
.s_aliases
= (char **)alias
;
499 aliascpy(sn
->sn_Ent
.s_name
, (UBYTE
*)Args
[KNDB_NAME
],
500 alias
, (UBYTE
**)Args
[KNDB_ALIAS
]);
501 AddTail((struct List
*)&ndb
->ndb_Services
, (struct Node
*)sn
);
504 *errstrp
= ERR_MEMORY
; retval
= RETURN_FAIL
;
507 *errstrp
= ERR_VALUE
; retval
= RETURN_WARN
;
511 *errstrp
= ERR_SYNTAX
; retval
= RETURN_WARN
;
517 * Parse a host entry.
519 * NOTE: The host entry has the address in the 'name' and the official name
523 addhostent(struct NetDataBase
*ndb
,
524 struct RDArgs
*rdargs
,
525 UBYTE
**errstrp
, struct CSource
*res
, ULONG flags
)
528 IPTR Args
[NDBARGS
] = { 0 };
529 struct HostentNode
*hn
;
533 #if defined(__AROS__)
534 D(bug("[AROSTCP](amiga_netdb.c) addhostent()\n"));
537 if (rdargs
= ReadArgs(NETDBTEMPLATE
, Args
, rdargs
)) {
538 /* convert ip address */
539 if (__inet_aton((char*)Args
[KNDB_NAME
], &addr
)) {
540 hn
= node_alloc(sizeof (*hn
) + 2*sizeof (&addr
) + sizeof (addr
),
541 (UBYTE
*)Args
[KNDB_DATA
],
542 (UBYTE
**)Args
[KNDB_ALIAS
], &aliases
);
544 struct in_addr
**addrtbl
= (struct in_addr
**)(hn
+ 1);
545 UBYTE
**alias
= (UBYTE
**)((UBYTE
*)(addrtbl
+ 2) + sizeof (addr
));
546 UBYTE
*name
= (UBYTE
*)(alias
+ aliases
);
548 hn
->hn_Ent
.h_addrtype
= AF_INET
;
549 hn
->hn_Ent
.h_length
= sizeof (addr
);
550 hn
->hn_Ent
.h_addr_list
= (char **)addrtbl
;
551 hn
->hn_Ent
.h_name
= name
;
552 hn
->hn_Ent
.h_aliases
= (char **)alias
;
554 /* Make address list */
555 addrtbl
[0] = (struct in_addr
*)(addrtbl
+ 2);
557 bcopy(&addr
, addrtbl
[0], sizeof (addr
));
560 aliascpy(hn
->hn_Ent
.h_name
, (UBYTE
*)Args
[KNDB_DATA
],
561 alias
, (UBYTE
**)Args
[KNDB_ALIAS
]);
562 AddTail((struct List
*)&ndb
->ndb_Hosts
, (struct Node
*)hn
);
565 *errstrp
= ERR_MEMORY
; retval
= RETURN_FAIL
;
568 *errstrp
= ERR_VALUE
; retval
= RETURN_WARN
;
572 *errstrp
= ERR_SYNTAX
; retval
= RETURN_WARN
;
581 addnetent(struct NetDataBase
*ndb
,
582 struct RDArgs
*rdargs
,
583 UBYTE
**errstrp
, struct CSource
*res
, ULONG flags
)
586 IPTR Args
[NDBARGS
] = { 0 };
587 struct NetentNode
*nn
;
591 #if defined(__AROS__)
592 D(bug("[AROSTCP](amiga_netdb.c) addnetent()\n"));
595 if (rdargs
= ReadArgs(NETDBTEMPLATE
, Args
, rdargs
)) {
596 /* convert ip address */
597 if (__inet_aton((char*)Args
[KNDB_DATA
], &addr
)) {
598 nn
= node_alloc(sizeof (*nn
),
599 (UBYTE
*)Args
[KNDB_NAME
],
600 (UBYTE
**)Args
[KNDB_ALIAS
], &aliases
);
602 UBYTE
**alias
= (UBYTE
**)(nn
+ 1);
603 UBYTE
*name
= (UBYTE
*)(alias
+ aliases
);
605 nn
->nn_Ent
.n_addrtype
= AF_INET
;
606 nn
->nn_Ent
.n_name
= name
;
607 nn
->nn_Ent
.n_aliases
= (char **)alias
;
608 bcopy(&addr
, &nn
->nn_Ent
.n_net
, sizeof (unsigned long));
611 aliascpy(nn
->nn_Ent
.n_name
, (UBYTE
*)Args
[KNDB_NAME
],
612 alias
, (UBYTE
**)Args
[KNDB_ALIAS
]);
613 AddTail((struct List
*)&ndb
->ndb_Networks
, (struct Node
*)nn
);
616 *errstrp
= ERR_MEMORY
; retval
= RETURN_FAIL
;
619 *errstrp
= ERR_VALUE
; retval
= RETURN_WARN
;
623 *errstrp
= ERR_SYNTAX
; retval
= RETURN_WARN
;
629 * Parse a protocol entry.
632 addprotoent(struct NetDataBase
*ndb
,
633 struct RDArgs
*rdargs
,
634 UBYTE
**errstrp
, struct CSource
*res
, ULONG flags
)
637 IPTR Args
[NDBARGS
] = { 0 };
638 struct ProtoentNode
*pn
;
641 #if defined(__AROS__)
642 D(bug("[AROSTCP](amiga_netdb.c) addprotoent()\n"));
645 if (rdargs
= ReadArgs(PROTOCOL_TEMPLATE
, Args
, rdargs
)) {
647 if (Args
[KNDB_DATA
]) {
648 pn
= node_alloc(sizeof (*pn
), (UBYTE
*)Args
[KNDB_NAME
],
649 (UBYTE
**)Args
[KNDB_ALIAS
], &aliases
);
651 UBYTE
**alias
= (UBYTE
**)(pn
+1);
652 UBYTE
*name
= (UBYTE
*)(alias
+ aliases
);
654 pn
->pn_Ent
.p_name
= name
;
655 pn
->pn_Ent
.p_aliases
= (char **)alias
;
656 pn
->pn_Ent
.p_proto
= *(LONG
*)Args
[KNDB_DATA
];
658 /* Copy name and aliases */
659 aliascpy(name
, (UBYTE
*)Args
[KNDB_NAME
],
660 alias
, (UBYTE
**)Args
[KNDB_ALIAS
]);
661 AddTail((struct List
*)&ndb
->ndb_Protocols
, (struct Node
*)pn
);
664 *errstrp
= ERR_MEMORY
; retval
= RETURN_FAIL
;
667 *errstrp
= ERR_VALUE
; retval
= RETURN_WARN
;
671 *errstrp
= ERR_SYNTAX
; retval
= RETURN_WARN
;
677 * Parse a route entry
680 addrtent(struct NetDataBase
*ndb
,
681 struct RDArgs
*rdargs
,
682 UBYTE
**errstrp
, struct CSource
*res
, ULONG flags
)
685 IPTR Args
[RTARGS
] = { 0 };
686 struct ortentry route
;
688 #if defined(__AROS__)
689 D(bug("[AROSTCP](amiga_netdb.c) addrtent()\n"));
692 if (rdargs
= ReadArgs(ROUTE_TEMPLATE
, Args
, rdargs
)) {
693 if (!(strcmp(strupr((APTR
)Args
[KRT_DEST
]), "DEFAULT"))){
694 struct sockaddr_in
*rodst_saddr
= (struct sockaddr_in
*)&route
.rt_dst
;
695 rodst_saddr
->sin_addr
.s_addr
= 0;
696 route
.rt_dst
.sa_family
= AF_INET
;
697 route
.rt_dst
.sa_len
= sizeof(struct sockaddr_in
);
699 if (!(setaddr((struct sockaddr_in
*)&route
.rt_dst
, (APTR
)Args
[KRT_DEST
], AF_INET
)))
703 if (setaddr((struct sockaddr_in
*)&route
.rt_gateway
, (APTR
)Args
[KRT_GATE
], AF_INET
)) {
704 route
.rt_flags
= RTF_UP
| RTF_GATEWAY
;
706 route
.rt_flags
|= RTF_HOST
;
707 rtioctl(SIOCADDRT
, (caddr_t
)&route
);
711 *errstrp
= ERR_SYNTAX
;
712 retval
= RETURN_WARN
;
720 * Parse a Name Server entry
723 addnameservent(struct NetDataBase
*ndb
,
724 struct RDArgs
*rdargs
,
725 UBYTE
**errstrp
, struct CSource
*res
, ULONG flags
)
727 UBYTE Buffer
[KEYWORDLEN
];
728 LONG BufLen
= sizeof (Buffer
);
729 struct in_addr ns_addr
;
730 struct NameserventNode
*nsn
;
732 #if defined(__AROS__)
733 D(bug("[AROSTCP](amiga_netdb.c) addnameservent()\n"));
736 /* TODO: NicJA - Where does CHECK_POINTER() Come from? */
737 #if !defined(__AROS__)
741 if (ReadItem(Buffer
, BufLen
, &rdargs
->RDA_Source
) <= 0) {
742 #if defined(__AROS__)
743 D(bug("[AROSTCP](amiga_netdb.c) addnameservent: Error in syntax\n"));
745 *errstrp
= ERR_SYNTAX
;
748 if (!__inet_aton(Buffer
, &ns_addr
)) {
749 #if defined(__AROS__)
750 D(bug("[AROSTCP](amiga_netdb.c) addnameservent: error with address\n"));
752 *errstrp
= ERR_VALUE
;
755 if ((nsn
= bsd_malloc(sizeof (*nsn
), M_NETDB
, M_WAITOK
)) == NULL
) {
756 #if defined(__AROS__)
757 D(bug("[AROSTCP](amiga_netdb.c) addnameservent: couldnt allocate entry\n"));
759 *errstrp
= ERR_MEMORY
;
762 nsn
->nsn_EntSize
= sizeof (nsn
->nsn_Ent
);
763 nsn
->nsn_Ent
.ns_addr
.s_addr
= ns_addr
.s_addr
;
765 /* TODO: NicJA - Where does CHECK_POINTER() Come from? */
766 #if !defined(__AROS__)
770 #if defined(__AROS__)
771 D(bug("[AROSTCP](amiga_netdb.c) addnameservent: Added nameserver %s (0x%08lx) to netdb = 0x%08lx\n",Buffer
, nsn
->nsn_Ent
.ns_addr
.s_addr
, ndb
));
773 DNETDB(__log(LOG_DEBUG
,"Added nameserver %s (0x%08lx) to netdb = 0x%08lx\n",Buffer
, nsn
->nsn_Ent
.ns_addr
.s_addr
, ndb
);)
775 AddTail((struct List
*)&ndb
->ndb_NameServers
, (struct Node
*)nsn
);
780 * Parse a Domain Name entry
783 adddomainent(struct NetDataBase
*ndb
,
784 struct RDArgs
*rdargs
,
785 UBYTE
**errstrp
, struct CSource
*res
, ULONG flags
)
787 UBYTE Buffer
[REPLYBUFLEN
];
788 LONG BufLen
= sizeof (Buffer
);
789 struct DomainentNode
*dn
;
792 #if defined(__AROS__)
793 D(bug("[AROSTCP](amiga_netdb.c) adddomainent()\n"));
796 if (ReadItem(Buffer
, BufLen
, &rdargs
->RDA_Source
) <= 0) {
797 *errstrp
= ERR_SYNTAX
;
800 nodesize
= sizeof (*dn
) + strlen(Buffer
) + 1;
801 if ((dn
= bsd_malloc(nodesize
, M_NETDB
, M_WAITOK
)) == NULL
) {
802 *errstrp
= ERR_MEMORY
;
805 dn
->dn_EntSize
= nodesize
- sizeof (struct GenentNode
);
806 dn
->dn_Ent
.d_name
= (char *)(dn
+ 1);
808 strcpy((char *)(dn
+ 1), Buffer
);
810 AddTail((struct List
*)&ndb
->ndb_Domains
, (struct Node
*)dn
);
815 * Parse an RC script entry
818 addrcent(struct NetDataBase
*ndb
,
819 struct RDArgs
*rdargs
,
820 UBYTE
**errstrp
, struct CSource
*res
, ULONG flags
)
822 UBYTE Buffer
[REPLYBUFLEN
];
823 LONG BufLen
= sizeof (Buffer
);
824 struct RcentNode
*dn
;
827 #if defined(__AROS__)
828 D(bug("[AROSTCP](amiga_netdb.c) addrcent()\n"));
831 if (ReadItem(Buffer
, BufLen
, &rdargs
->RDA_Source
) <= 0) {
832 *errstrp
= ERR_SYNTAX
;
835 nodesize
= sizeof (*dn
) + strlen(Buffer
) + 1;
836 if ((dn
= bsd_malloc(nodesize
, M_NETDB
, M_WAITOK
)) == NULL
) {
837 *errstrp
= ERR_MEMORY
;
840 dn
->rn_EntSize
= nodesize
- sizeof (struct GenentNode
);
841 dn
->rn_Ent
= (char *)(dn
+ 1);
843 strcpy((char *)(dn
+ 1), Buffer
);
845 AddTail((struct List
*)&ndb
->ndb_Rc
, (struct Node
*)dn
);
851 * Parse a access control entry.. after reading the whole netdatabase
852 * access list must be reorganized;
855 addaccessent(struct NetDataBase
*ndb
,
856 struct RDArgs
*rdargs
,
857 UBYTE
**errstrp
, struct CSource
*res
, ULONG ifflags
)
859 LONG retval
= RETURN_WARN
;
860 IPTR Args
[ACCARGS
] = { 0 };
863 UWORD port
, flags
= ACF_CONTINUE
;
865 #if defined(__AROS__)
866 D(bug("[AROSTCP](amiga_netdb.c) addaccessent()\n"));
869 if (ndb
->ndb_AccessCount
>= TMPACTSIZE
/ sizeof (struct AccessItem
)) {
870 *errstrp
= "Too many access control items\n";
871 return retval
; /* copy propagation expected */
874 if ((rdargs
= ReadArgs(ACCESS_TEMPLATE
, Args
, rdargs
)) != NULL
) {
876 if (strcmp((char *)Args
[KACC_PORT
], "*") == 0)
878 else if (strcmp((char *)Args
[KACC_PORT
], "@") == 0) {
879 port
= 0; flags
|= ACF_PRIVONLY
;
881 else if (StrToLong((char *)Args
[KACC_PORT
], (LONG
*)&host
) > 0
884 *errstrp
= "Illegal port value\n";
890 struct ServentNode
* entNode
;
893 findServentNode(ndb
, (char *)Args
[KACC_PORT
], "tcp")) != NULL
)
894 port
= entNode
->sn_Ent
.s_port
;
896 *errstrp
= "Illegal port value\n";
901 int zmask
= 0xFFFFFFFF;
902 int i
= 0, ls
= 0, dots
= 0;
904 #define hm ((char *)Args[KACC_HOSTMASK])
906 while ((hm
[i
] >= '0' && hm
[i
] <= '9') || hm
[i
] == '.' || hm
[i
] == '*') {
911 else if (hm
[i
] == '*') {
914 zmask
^= (0xFF000000 >> 8 * dots
);
920 zmask
^= (0xFF000000 >> 8 * dots
);
924 if (__inet_aton(&hm
[i
], (struct in_addr
*)&mask
) == 0) {
925 *errstrp
= "Illegal mask value\n";
934 if (__inet_aton(hm
, (struct in_addr
*)&host
) == 0) {
935 *errstrp
= "Illegal host value\n";
940 if (strcmp((char *)Args
[KACC_ACCESS
], "allow") == 0)
942 else if (strcmp((char *)Args
[KACC_ACCESS
], "deny") != 0) {
943 *errstrp
= "Illegal access value\n";
950 ndb
->ndb_AccessTable
[ndb
->ndb_AccessCount
].ai_port
= port
;
951 ndb
->ndb_AccessTable
[ndb
->ndb_AccessCount
].ai_host
= host
;
952 ndb
->ndb_AccessTable
[ndb
->ndb_AccessCount
].ai_mask
= mask
;
953 ndb
->ndb_AccessTable
[ndb
->ndb_AccessCount
].ai_flags
= flags
;
954 ndb
->ndb_AccessCount
++;
961 *errstrp
= ERR_SYNTAX
;
967 * Add an entry into NetDB.
968 * Caller must have a write lock on ndb
971 addndbent(struct NetDataBase
*ndb
,
972 struct RDArgs
*rdargs
,
973 UBYTE
**errstrp
, struct CSource
*res
, ULONG flags
)
978 UBYTE Buffer
[KEYWORDLEN
];
980 #if defined(__AROS__)
981 D(bug("[AROSTCP](amiga_netdb.c) addndbent()\n"));
985 item
= ReadItem(Buffer
, sizeof (Buffer
), &rdargs
->RDA_Source
);
988 return RETURN_OK
; /* empty line */
990 DNETDB(Printf("addndbent: syntax error\n");)
991 *errstrp
= ERR_SYNTAX
;
994 if ((which
= FindArg(NETDBENTRY
, Buffer
)) < 0) {
995 DNETDB(Printf("Unknown keyword\n");)
996 *errstrp
= ERR_UNKNOWN
;
1000 DNETDB(Printf("Keyword number: %ld\n", which
);)
1001 which
= ndb_parse_funs
[which
](ndb
, rdargs
, errstrp
, res
, flags
);
1005 *errstrp
= ERR_NONETDB
;
1011 * Read in a NetDataBase file
1014 read_netdb(struct NetDataBase
*ndb
, UBYTE
*fname
,
1015 UBYTE
** errstrp
, struct CSource
*res
, int prefixindex
, ULONG flags
)
1017 LONG warnval
= RETURN_OK
;
1018 LONG retval
= RETURN_OK
, ioerr
= 0;
1019 UBYTE
*p
, *buf
= AllocMem(CONFIGLINELEN
, MEMF_PUBLIC
);
1020 struct RDArgs
*rdargs
;
1026 #if defined(__AROS__)
1027 D(bug("[AROSTCP](amiga_netdb.c) read_netdb('%s')\n", fname
));
1030 DNETDB(Printf("Reading netdb file: %s\n", fname
);)
1031 /* Get an exclusive lock on the database.
1032 * Multiple locks are OK (when this function is called recursively)
1035 if (ndb_Lock
.ss_NestCount
> 10) {
1037 *errstrp
= "Too many files included";
1038 #if defined(__AROS__)
1039 D(bug("[AROSTCP](amiga_netdb.c) read_netdb: Too many files included\n"));
1041 return RETURN_ERROR
;
1045 /* CD to netdb directory */
1046 lock
= Lock(db_path
, ACCESS_READ
);
1048 oldcd
= CurrentDir(lock
);
1050 if (fh
= Open(fname
, MODE_OLDFILE
)) {
1051 if (rdargs
= AllocDosObject(DOS_RDARGS
, NULL
)) {
1052 /* initialize CSource of the rdargs */
1053 rdargs
->RDA_Source
.CS_Buffer
= buf
;
1054 /* initialize rest fields (see dos/rdargs.h) */
1055 rdargs
->RDA_DAList
= 0;
1056 rdargs
->RDA_ExtHelp
= NULL
;
1057 rdargs
->RDA_Flags
= 0;
1059 if (prefixindex
< 0)
1060 parser
= addndbent
; /* no prefix */
1062 parser
= ndb_parse_funs
[prefixindex
];
1064 while (FGets(fh
, buf
, CONFIGLINELEN
- 1)) {
1065 line
++; /* maintain line number */
1066 /* pass by white space */
1067 for (p
= buf
; *p
== ' ' || *p
== '\t' || *p
== '\r'; p
++)
1069 rdargs
->RDA_Source
.CS_CurChr
= p
- buf
;
1070 if (*p
== '#' || *p
== ';' || *p
== '\n') /* only a comment line */
1072 /* remove comments & calc length */
1074 if (*p
== '#' || *p
== ';') {
1076 *p
= '\0'; /* terminate line */
1080 /* ensure that line ends with '\n' (ReadArgs() depends on it) */
1081 if (*(p
- 1) != '\n') {
1085 rdargs
->RDA_Source
.CS_Length
= p
- buf
;
1086 rdargs
->RDA_Buffer
= NULL
;
1087 rdargs
->RDA_BufSiz
= 0;
1088 #if defined(__AROS__)
1089 D(bug("[AROSTCP](amiga_netdb.c) read_netdb: parsing line: %s, prefixindex=%ld\n", buf
, prefixindex
));
1091 DNETDB(Printf("Processing line: %s, prefixindex=%ld\n", buf
, prefixindex
);)
1092 retval
= parser(ndb
, rdargs
, errstrp
, res
, flags
);
1093 if (retval
== RETURN_OK
)
1095 if (retval
!= RETURN_WARN
) { /* severe error */
1096 error_request("Fatal error in NetDB file %s at line %ld, col %ld\n%s\nAROSTCP will quit",
1097 (IPTR
)fname
, (IPTR
)line
, (IPTR
)rdargs
->RDA_Source
.CS_CurChr
, (IPTR
)*errstrp
);
1101 error_request("Error in NetDB file %s at line %ld, col %ld\n%s",
1102 (IPTR
)fname
, (IPTR
)line
, (IPTR
)rdargs
->RDA_Source
.CS_CurChr
, (IPTR
)*errstrp
);
1103 __log(LOG_WARNING
, "NetDB(%s) line %ld: %s before col %ld\n",
1104 fname
, line
, *errstrp
, rdargs
->RDA_Source
.CS_CurChr
);
1108 /* Check file error */
1111 FreeDosObject(DOS_RDARGS
, rdargs
);
1119 #if defined(__AROS__)
1120 D(bug("[AROSTCP](amiga_netdb.c) read_netdb: ioerror\n"));
1122 Fault(ioerr
, "readnetdb", res
->CS_Buffer
, res
->CS_Length
);
1123 *errstrp
= res
->CS_Buffer
;
1124 retval
= RETURN_ERROR
;
1126 if ((!fh
) && (ndb_Lock
.ss_NestCount
== 1))
1127 error_request("Unable to open NetDB file %s\n%s", (IPTR
)fname
, (IPTR
)*errstrp
);
1129 /* return old current directory */
1135 FreeMem(buf
, CONFIGLINELEN
);
1137 #if defined(__AROS__)
1138 D(bug("[AROSTCP](amiga_netdb.c) read_netdb: Failed to allocate buffer\n"));
1140 *errstrp
= ERR_MEMORY
;
1141 retval
= RETURN_FAIL
;
1146 return retval
> warnval
? retval
: warnval
;
1150 * Parse the 'ADD' command
1153 do_netdb(struct CSource
*csarg
, UBYTE
**errstrp
, struct CSource
*res
)
1155 struct RDArgs
*rdargs
;
1158 #if defined(__AROS__)
1159 D(bug("[AROSTCP](amiga_netdb.c) do_netdb()\n"));
1162 if (rdargs
= AllocDosObject(DOS_RDARGS
, NULL
)) {
1163 /* initialize CSource of the rdargs */
1164 rdargs
->RDA_Source
= *csarg
;
1165 /* initialize rest fields (see <dos/rdargs.h>) */
1166 rdargs
->RDA_DAList
= 0;
1167 rdargs
->RDA_Buffer
= NULL
;
1168 rdargs
->RDA_BufSiz
= 0;
1169 rdargs
->RDA_ExtHelp
= NULL
;
1170 rdargs
->RDA_Flags
= 0;
1174 retval
= addndbent(NDB
, rdargs
, errstrp
, res
, 0);
1175 /* TODO: set flags here */
1179 FreeDosObject(DOS_RDARGS
, rdargs
);
1182 retval
= RETURN_FAIL
;
1188 * Initialize the Network Data Base
1193 UBYTE result
[REPLYBUFLEN
+ 1]; /* for error returns */
1198 #if defined(__AROS__)
1199 D(bug("[AROSTCP](amiga_netdb.c) init_netdb()\n"));
1202 res
.CS_Buffer
= result
;
1203 res
.CS_Length
= sizeof (result
);
1206 InitSemaphore (&ndb_Lock
);
1207 InitSemaphore (&DynDB
.dyn_Lock
);
1208 NewList((struct List
*)&DynDB
.dyn_NameServers
);
1209 NewList((struct List
*)&DynDB
.dyn_Domains
);
1212 /* Allocate the NetDataBase */
1213 if (!(NDB
= alloc_netdb(NULL
))) {
1217 /* Read in the default data base file */
1218 retval
= read_netdb(NDB
, netdbname
, &errstr
, &res
, -1, NETDB_IFF_ADDNEW
);
1220 Printf("init_netdb: file %s: %s\n", netdbname, errstr);
1221 __log(LOG_WARNING, "init_netdb: file %s: %s", netdbname, errstr);
1223 if (retval
== RETURN_WARN
)
1227 setup_accesscontroltable(NDB
);
1233 void netdb_deinit(void)
1235 #if defined(__AROS__)
1236 D(bug("[AROSTCP](amiga_netdb.c) netdb_deinit()\n"));
1238 /* A Placeholder for possible future deinitializations */
1242 * Reset the NetDataBase
1244 LONG
reset_netdb(struct CSource
*cs
,
1246 struct CSource
*res
)
1249 struct NetDataBase
*newnetdb
;
1251 #if defined(__AROS__)
1252 D(bug("[AROSTCP](amiga_netdb.c) reset_netdb()\n"));
1255 /* Allocate a temporary NetDataBase */
1256 if (!(newnetdb
= alloc_netdb(NULL
))) {
1257 *errstrp
= ERR_MEMORY
;
1261 retval
= read_netdb(newnetdb
, netdbname
, errstrp
, res
, -1, 0);
1262 /* TODO: set flags here */
1264 if (retval
== RETURN_OK
) {
1265 setup_accesscontroltable(newnetdb
);
1267 /* Now clear the old lists of the NDB */
1276 free_netdb(newnetdb
);