Networking - DNS resolution semi-working
[tpg/acess2.git] / Usermode / Libraries / libnet.so_src / hostnames.c
1 /*
2  * Acess2 Networking Toolkit
3  * By John Hodge (thePowersGang)
4  * 
5  * dns.c
6  * - Hostname<->Address resolution
7  */
8 #include <net.h>
9 #include "include/dns.h"
10 #include <string.h>
11 #include <stdlib.h>     // malloc (for loading config)
12 #include <stdbool.h>
13 #include <acess/sys.h>  // _SysDebug
14
15 // === TYPES ===
16 struct sDNSServer
17 {
18          int    AddrType;
19         char    AddrData[16];
20 };
21
22 struct sHostEntry
23 {
24          int    AddrType;
25         char    AddrData[16];
26         char    *Names[];
27 };
28
29 struct sLookupAnyInfo
30 {
31          int    expected_type;
32         void    *dest_ptr;
33         bool    have_result;
34 };
35 struct sDNSCallbackInfo
36 {
37         void    *cb_info;
38         tNet_LookupAddrs_Callback       *callback;
39         enum eTypes     desired_type;
40         enum eClass     desired_class;
41         bool    got_value;
42 };
43
44 // === PROTOTYPES ===
45  int    int_lookupany_callback(void *info_v, int AddrType, const void *Addr);
46 void    int_DNS_callback(void *info, const char *name, enum eTypes type, enum eClass class, unsigned int ttl, size_t rdlength, const void *rdata);
47
48 // === GLOBALS ===
49  int    giNumDNSServers;
50 struct sDNSServer       *gaDNSServers;
51  int    giNumHostEntries;
52 struct sHostEntry       *gaHostEntries;
53
54 // === CODE ===
55 int Net_Lookup_AnyAddr(const char *Name, int AddrType, void *Addr)
56 {
57         struct sLookupAnyInfo   cb_info = {
58                 .expected_type = AddrType,
59                 .dest_ptr = Addr,
60                 .have_result = false,
61                 };
62         return Net_Lookup_Addrs(Name, &cb_info, int_lookupany_callback);
63 }
64 int int_lookupany_callback(void *info_v, int AddrType, const void *Addr)
65 {
66         struct sLookupAnyInfo   *info = info_v;
67         if( AddrType == info->expected_type && info->have_result == false )
68         {
69                 memcpy(info->dest_ptr, Addr, Net_GetAddressSize(AddrType));
70                 
71                 info->have_result = true;
72                 return 1;
73         }
74         return 0;
75 }
76
77 int Net_Lookup_Addrs(const char *Name, void *cb_info, tNet_LookupAddrs_Callback *callback)
78 {
79         _SysDebug("Net_Lookup_Addrs(Name='%s')", Name);
80         // 1. Load (if not loaded) the DNS config from "/Acess/Conf/dns"
81         // - "* <ip> <ip>" for DNS server(s)
82         // - "127.0.0.1 localhost localhost.localdomain"
83         if( !gaDNSServers )
84         {
85                 giNumDNSServers = 1;
86                 gaDNSServers = malloc( 1 * sizeof(gaDNSServers[0]) );
87                 gaDNSServers[0].AddrType = Net_ParseAddress("192.168.1.1", gaDNSServers[0].AddrData);
88         }
89         
90         // 2. Check the hosts list
91         for( int i = 0; i < giNumHostEntries; i ++ )
92         {
93                 const struct sHostEntry* he = &gaHostEntries[i];
94                 for( const char * const *namep = (const char**)he->Names; *namep; namep ++ )
95                 {
96                         if( strcasecmp(Name, *namep) == 0 )
97                         {
98                                 if( callback(cb_info, he->AddrType, he->AddrData) != 0 )
99                                         return 0;
100                         }
101                 }
102         }
103         // 3. Contact DNS server specified in config
104         for( int i = 0; i < giNumDNSServers; i ++ )
105         {
106                 const struct sDNSServer *s = &gaDNSServers[i];
107                 struct sDNSCallbackInfo info = {
108                         .cb_info = cb_info,
109                         .callback = callback,
110                         .desired_type = TYPE_A,
111                         .desired_class = CLASS_IN,
112                         .got_value = false,
113                         };
114                 if( ! DNS_Query(s->AddrType, s->AddrData, Name, info.desired_type, info.desired_class, int_DNS_callback, &info) )
115                 {
116                         if( info.got_value )
117                         {
118                                 return 0;
119                         }
120                         else
121                         {
122                                 // NXDomain, I guess
123                                 return 1;
124                         }
125                 }
126         }
127         return 1;
128 }
129
130 void int_DNS_callback(void *info_v, const char *name, enum eTypes type, enum eClass class, unsigned int ttl, size_t rdlength, const void *rdata)
131 {
132         struct sDNSCallbackInfo *info = info_v;
133         _SysDebug("int_DNS_callback(name='%s', type=%i, class=%i)", name, type, class);
134         
135         // Check type matches (if pattern was provided)
136         if( info->desired_type != QTYPE_STAR && type != info->desired_type )
137                 return ;
138         if( info->desired_class != QCLASS_STAR && class != info->desired_class )
139                 return ;
140         
141         switch( type )
142         {
143         case TYPE_A:
144                 if( rdlength != 4 )
145                         return ;
146                 info->callback( info->cb_info, 4, rdata );
147                 break;
148         //case TYPE_AAAA:
149         //      if( rdlength != 16 )
150         //              return ;
151         //      info->callback( info->cb_info, 6, rdata );
152         //      break;
153         default:
154                 // Ignore anything not A/AAAA
155                 break;
156         }
157         info->got_value = true;
158 }
159
160 int Net_Lookup_Name(int AddrType, const void *Addr, char *Dest[256])
161 {
162         return 1;
163 }
164

UCC git Repository :: git.ucc.asn.au