1 /*
2  * scamper_host
3  *
4  * $Id: scamper_host.c,v 1.6 2021/08/23 08:31:27 mjl Exp $
5  *
6  * Copyright (C) 2018-2021 Matthew Luckie
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, version 2.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
21  */
22 
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26 #include "internal.h"
27 
28 #include "scamper_list.h"
29 #include "scamper_addr.h"
30 #include "scamper_host.h"
31 
32 #include "utils.h"
33 
scamper_host_query_counts(scamper_host_query_t * q,uint16_t an,uint16_t ns,uint16_t ar)34 int scamper_host_query_counts(scamper_host_query_t *q,
35 			      uint16_t an, uint16_t ns, uint16_t ar)
36 {
37   q->ancount = an;
38   q->nscount = ns;
39   q->arcount = ar;
40 
41   if(an > 0 && (q->an = malloc_zero(sizeof(scamper_host_rr_t *) * an)) == NULL)
42     return -1;
43   if(ns > 0 && (q->ns = malloc_zero(sizeof(scamper_host_rr_t *) * ns)) == NULL)
44     return -1;
45   if(ar > 0 && (q->ar = malloc_zero(sizeof(scamper_host_rr_t *) * ar)) == NULL)
46     return -1;
47 
48   return 0;
49 }
50 
scamper_host_rr_soa_free(scamper_host_rr_soa_t * soa)51 void scamper_host_rr_soa_free(scamper_host_rr_soa_t *soa)
52 {
53   if(soa == NULL)
54     return;
55   if(soa->mname != NULL) free(soa->mname);
56   if(soa->rname != NULL) free(soa->rname);
57   free(soa);
58   return;
59 }
60 
scamper_host_rr_soa_alloc(const char * mn,const char * rn)61 scamper_host_rr_soa_t *scamper_host_rr_soa_alloc(const char *mn,const char *rn)
62 {
63   scamper_host_rr_soa_t *soa;
64   if((soa = malloc_zero(sizeof(scamper_host_rr_soa_t))) == NULL ||
65      (soa->mname = strdup(mn)) == NULL ||
66      (soa->rname = strdup(rn)) == NULL)
67     {
68       scamper_host_rr_soa_free(soa);
69       return NULL;
70     }
71   return soa;
72 }
73 
scamper_host_rr_mx_free(scamper_host_rr_mx_t * mx)74 void scamper_host_rr_mx_free(scamper_host_rr_mx_t *mx)
75 {
76   if(mx == NULL)
77     return;
78   if(mx->exchange != NULL) free(mx->exchange);
79   free(mx);
80   return;
81 }
82 
scamper_host_rr_mx_alloc(uint16_t pref,const char * exch)83 scamper_host_rr_mx_t *scamper_host_rr_mx_alloc(uint16_t pref, const char *exch)
84 {
85   scamper_host_rr_mx_t *mx;
86   if((mx = malloc_zero(sizeof(scamper_host_rr_mx_t))) == NULL ||
87      (mx->exchange = strdup(exch)) == NULL)
88     {
89       scamper_host_rr_mx_free(mx);
90       return NULL;
91     }
92   mx->preference = pref;
93   return mx;
94 }
95 
scamper_host_rr_data_type(uint16_t class,uint16_t type)96 int scamper_host_rr_data_type(uint16_t class, uint16_t type)
97 {
98   if(class == SCAMPER_HOST_CLASS_IN)
99     {
100       switch(type)
101 	{
102 	case SCAMPER_HOST_TYPE_NS:
103 	case SCAMPER_HOST_TYPE_CNAME:
104 	case SCAMPER_HOST_TYPE_PTR:
105 	  return SCAMPER_HOST_RR_DATA_TYPE_STR;
106 
107 	case SCAMPER_HOST_TYPE_A:
108 	case SCAMPER_HOST_TYPE_AAAA:
109 	  return SCAMPER_HOST_RR_DATA_TYPE_ADDR;
110 
111 	case SCAMPER_HOST_TYPE_SOA:
112 	  return SCAMPER_HOST_RR_DATA_TYPE_SOA;
113 
114 	case SCAMPER_HOST_TYPE_MX:
115 	  return SCAMPER_HOST_RR_DATA_TYPE_MX;
116 	}
117     }
118 
119   return -1;
120 }
121 
scamper_host_rr_free(scamper_host_rr_t * rr)122 void scamper_host_rr_free(scamper_host_rr_t *rr)
123 {
124   if(rr == NULL)
125     return;
126 
127   if(rr->name != NULL)
128     free(rr->name);
129 
130   switch(scamper_host_rr_data_type(rr->class, rr->type))
131     {
132     case SCAMPER_HOST_RR_DATA_TYPE_ADDR:
133       if(rr->un.addr != NULL) scamper_addr_free(rr->un.addr);
134       break;
135 
136     case SCAMPER_HOST_RR_DATA_TYPE_STR:
137       if(rr->un.str != NULL) free(rr->un.str);
138       break;
139 
140     case SCAMPER_HOST_RR_DATA_TYPE_SOA:
141       if(rr->un.soa != NULL) scamper_host_rr_soa_free(rr->un.soa);
142       break;
143 
144     case SCAMPER_HOST_RR_DATA_TYPE_MX:
145       if(rr->un.mx != NULL) scamper_host_rr_mx_free(rr->un.mx);
146       break;
147     }
148 
149   free(rr);
150   return;
151 }
152 
scamper_host_rr_alloc(const char * name,uint16_t class,uint16_t type,uint32_t ttl)153 scamper_host_rr_t *scamper_host_rr_alloc(const char *name, uint16_t class,
154 					 uint16_t type, uint32_t ttl)
155 {
156   scamper_host_rr_t *rr;
157 
158   if((rr = malloc_zero(sizeof(scamper_host_rr_t))) == NULL ||
159      (rr->name = strdup(name)) == NULL)
160     {
161       scamper_host_rr_free(rr);
162       return NULL;
163     }
164   rr->class = class;
165   rr->type = type;
166   rr->ttl = ttl;
167   return rr;
168 }
169 
scamper_host_query_free(scamper_host_query_t * query)170 void scamper_host_query_free(scamper_host_query_t *query)
171 {
172   int r;
173 
174   if(query == NULL)
175     return;
176 
177   if(query->an != NULL)
178     {
179       for(r=0; r<query->ancount; r++)
180 	scamper_host_rr_free(query->an[r]);
181       free(query->an);
182     }
183   if(query->ns != NULL)
184     {
185       for(r=0; r<query->nscount; r++)
186 	scamper_host_rr_free(query->ns[r]);
187       free(query->ns);
188     }
189   if(query->ar != NULL)
190     {
191       for(r=0; r<query->arcount; r++)
192 	scamper_host_rr_free(query->ar[r]);
193       free(query->ar);
194     }
195 
196   free(query);
197   return;
198 }
199 
scamper_host_queries_alloc(scamper_host_t * host,int n)200 int scamper_host_queries_alloc(scamper_host_t *host, int n)
201 {
202   size_t len = n * sizeof(scamper_host_query_t *);
203   if((host->queries = malloc_zero(len)) == NULL)
204     return -1;
205   return 0;
206 }
207 
scamper_host_query_rr_alloc(scamper_host_query_t * query)208 int scamper_host_query_rr_alloc(scamper_host_query_t *query)
209 {
210   size_t len;
211   if(query->ancount > 0)
212     {
213       len = query->ancount * sizeof(scamper_host_rr_t *);
214       if((query->an = malloc_zero(len)) == NULL)
215 	return -1;
216     }
217   if(query->nscount > 0)
218     {
219       len = query->nscount * sizeof(scamper_host_rr_t *);
220       if((query->ns = malloc_zero(len)) == NULL)
221 	return -1;
222     }
223   if(query->arcount > 0)
224     {
225       len = query->arcount * sizeof(scamper_host_rr_t *);
226       if((query->ar = malloc_zero(len)) == NULL)
227 	return -1;
228     }
229   return 0;
230 }
231 
scamper_host_query_alloc(void)232 scamper_host_query_t *scamper_host_query_alloc(void)
233 {
234   return malloc_zero(sizeof(scamper_host_query_t));
235 }
236 
scamper_host_free(scamper_host_t * host)237 void scamper_host_free(scamper_host_t *host)
238 {
239   int q;
240 
241   if(host == NULL)
242     return;
243 
244   if(host->queries != NULL)
245     {
246       for(q=0; q<host->qcount; q++)
247 	scamper_host_query_free(host->queries[q]);
248       free(host->queries);
249     }
250 
251   if(host->qname != NULL) free(host->qname);
252   if(host->src != NULL) scamper_addr_free(host->src);
253   if(host->dst != NULL) scamper_addr_free(host->dst);
254   if(host->cycle != NULL) scamper_cycle_free(host->cycle);
255   if(host->list != NULL) scamper_list_free(host->list);
256 
257   free(host);
258   return;
259 }
260 
scamper_host_alloc(void)261 scamper_host_t *scamper_host_alloc(void)
262 {
263   return (scamper_host_t *)malloc_zero(sizeof(scamper_host_t));
264 }
265