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