summaryrefslogtreecommitdiff
path: root/src/include/s6-dns/s6dns-message.h
blob: eb9c3781f563402097bba2b2905497572509019f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
/* ISC license. */

#ifndef S6DNS_MESSAGE_H
#define S6DNS_MESSAGE_H

#include <stdint.h>

#include <skalibs/stralloc.h>
#include <skalibs/genalloc.h>

#include <s6-dns/s6dns-domain.h>


 /* Header */

typedef struct s6dns_message_counts_s s6dns_message_counts_t, *s6dns_message_counts_t_ref ;
struct s6dns_message_counts_s
{
  uint16_t qd ;
  uint16_t an ;
  uint16_t ns ;
  uint16_t nr ;
} ;

#define S6DNS_MESSAGE_COUNTS_ZERO { .qd = 0, .an = 0, .ns = 0, .nr = 0 }
extern s6dns_message_counts_t const s6dns_message_counts_zero ;

extern void s6dns_message_counts_pack (char *, s6dns_message_counts_t const *) ;
extern void s6dns_message_counts_unpack (char const *, s6dns_message_counts_t *) ;
extern unsigned int s6dns_message_counts_next (s6dns_message_counts_t *) ;

typedef struct s6dns_message_header_s s6dns_message_header_t, *s6dns_message_header_t_ref ;
struct s6dns_message_header_s
{
  uint16_t id ;
  unsigned int qr : 1 ;
  unsigned int opcode : 4 ;
  unsigned int aa : 1 ;
  unsigned int tc : 1 ;
  unsigned int rd : 1 ;
  unsigned int ra : 1 ;
  unsigned int z : 3 ;
  unsigned int rcode : 4 ;
  s6dns_message_counts_t counts ;
} ;

#define S6DNS_MESSAGE_HEADER_ZERO { \
  .id = 0, \
  .qr = 0, \
  .opcode = 0, \
  .aa = 0, \
  .tc = 0, \
  .rd = 0, \
  .ra = 0, \
  .z = 0, \
  .rcode = 0, \
  .counts = S6DNS_MESSAGE_COUNTS_ZERO \
}
extern s6dns_message_header_t const s6dns_message_header_zero ;

extern void s6dns_message_header_pack (char *, s6dns_message_header_t const *) ;
extern void s6dns_message_header_unpack (char const *, s6dns_message_header_t *) ;


 /* Specific RR helpers */

extern int s6dns_message_get_string (s6dns_domain_t *, char const *, unsigned int, unsigned int *) ;
extern int s6dns_message_get_strings (char *, unsigned int, char const *, unsigned int, unsigned int *) ;
extern int s6dns_message_get_domain (s6dns_domain_t *, char const *, unsigned int, unsigned int *) ;
extern size_t s6dns_message_get_domain_nodecode (char *, size_t, char const *, unsigned int, unsigned int *) ;

typedef struct s6dns_message_rr_hinfo_s s6dns_message_rr_hinfo_t, *s6dns_message_rr_hinfo_t_ref ;
struct s6dns_message_rr_hinfo_s
{
  s6dns_domain_t cpu ;
  s6dns_domain_t os ;
} ;

extern int s6dns_message_get_hinfo (s6dns_message_rr_hinfo_t *, char const *, unsigned int, unsigned int *) ;

typedef struct s6dns_message_rr_mx_s s6dns_message_rr_mx_t, *s6dns_message_rr_mx_t_ref ;
struct s6dns_message_rr_mx_s
{
  uint16_t preference ;
  s6dns_domain_t exchange ;
} ;

extern int s6dns_message_get_mx (s6dns_message_rr_mx_t *, char const *, unsigned int, unsigned int *) ;

typedef struct s6dns_message_rr_soa_s s6dns_message_rr_soa_t, *s6dns_message_rr_soa_t_ref ;
struct s6dns_message_rr_soa_s
{
  s6dns_domain_t mname ;
  s6dns_domain_t rname ;
  uint32_t serial ;
  uint32_t refresh ;
  uint32_t retry ;
  uint32_t expire ;
  uint32_t minimum ;
} ;

extern int s6dns_message_get_soa (s6dns_message_rr_soa_t *, char const *, unsigned int, unsigned int *) ;

typedef struct s6dns_message_rr_srv_s s6dns_message_rr_srv_t, *s6dns_message_rr_srv_t_ref ;
struct s6dns_message_rr_srv_s
{
  uint16_t priority ;
  uint16_t weight ;
  uint16_t port ;
  s6dns_domain_t target ;
} ;

extern int s6dns_message_get_srv (s6dns_message_rr_srv_t *, char const *, unsigned int, unsigned int *) ;

typedef struct s6dns_message_rr_caa_s s6dns_message_rr_caa_t, *s6dns_message_rr_caa_t_ref ;
struct s6dns_message_rr_caa_s
{
  uint8_t flags ;
  char tag[256] ;
  char value[256] ;
} ;

extern int s6dns_message_get_caa (s6dns_message_rr_caa_t *, char const *, unsigned int, unsigned int *, uint16_t) ;


 /* The callback function type: how to parse RRs */

typedef struct s6dns_message_rr_s s6dns_message_rr_t, *s6dns_message_rr_t_ref ;
struct s6dns_message_rr_s
{
  s6dns_domain_t name ;
  uint16_t rtype ;
  uint16_t rclass ;
  uint32_t ttl ;
  uint16_t rdlength ;
} ;

typedef int s6dns_message_rr_func (s6dns_message_rr_t const *, char const *, unsigned int, unsigned int, unsigned int, void *) ;
typedef s6dns_message_rr_func *s6dns_message_rr_func_ref ;


 /* mpag: structure to encode several variable-length results */

typedef struct s6dns_mpag_s s6dns_mpag_t, *s6dns_mpag_t_ref ;
struct s6dns_mpag_s
{
  stralloc sa ;
  genalloc offsets ; /* array of size_t */
  uint16_t rtype ;
} ;
#define S6DNS_MPAG_ZERO { .sa = STRALLOC_ZERO, .offsets = GENALLOC_ZERO, .rtype = 0 }


 /* dpag: structure for domain lists */

typedef struct s6dns_dpag_s s6dns_dpag_t, *s6dns_dpag_t_ref ;
struct s6dns_dpag_s
{
  genalloc ds ; /* array of s6dns_domain_t */
  uint16_t rtype ;
} ;
#define S6DNS_DPAG_ZERO { .ds = GENALLOC_ZERO, .rtype = 0 }


extern s6dns_message_rr_func s6dns_message_parse_answer_strings ;
extern s6dns_message_rr_func s6dns_message_parse_answer_domain ;
extern s6dns_message_rr_func s6dns_message_parse_answer_a ;
extern s6dns_message_rr_func s6dns_message_parse_answer_aaaa ;
extern s6dns_message_rr_func s6dns_message_parse_answer_mx ;
extern s6dns_message_rr_func s6dns_message_parse_answer_hinfo ;
extern s6dns_message_rr_func s6dns_message_parse_answer_soa ;
extern s6dns_message_rr_func s6dns_message_parse_answer_srv ;
extern s6dns_message_rr_func s6dns_message_parse_answer_caa ;


 /* The actual parsing function */

extern int s6dns_message_parse (s6dns_message_header_t_ref, char const *, unsigned int, s6dns_message_rr_func_ref, void *) ;


 /* Internals of this function, for lower level access */

extern int s6dns_message_parse_init (s6dns_message_header_t *, s6dns_message_counts_t_ref, char const *, unsigned int, unsigned int *) ;
extern unsigned int s6dns_message_parse_skipqd (s6dns_message_counts_t *, char const *, unsigned int, unsigned int *) ;
extern int s6dns_message_parse_getrr (s6dns_message_rr_t_ref, char const *, unsigned int, unsigned int *) ;
extern unsigned int s6dns_message_parse_next (s6dns_message_counts_t *, s6dns_message_rr_t const *, char const *, unsigned int, unsigned int *) ;


 /* For when you want to write a cache */

extern int s6dns_message_parse_question (s6dns_message_counts_t *, s6dns_domain_t *, uint16_t *, char const *, unsigned int, unsigned int *) ;

#endif