1 /*
2  * Copyright (C) 2006  Justin Karneges
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sublicense, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included
13  * in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23 
24 #ifndef JDNS_PACKET_H
25 #define JDNS_PACKET_H
26 
27 #include "jdns.h"
28 
29 /* -- howto --
30 //
31 // writing packets:
32 //   1) call jdns_packet_new()
33 //   2) populate the jdns_packet_t structure, using the functions
34 //      as necessary
35 //   3) call jdns_packet_export() to populate the raw data of the packet
36 //
37 // reading packets:
38 //   1) call jdns_packet_new()
39 //   2) call jdns_packet_import() with the raw data
40 //   3) the jdns_packet_t structure is now populated
41 //
42 // IMPORTANT: all names must be valid. that is, ending in a dot character */
43 
44 int jdns_packet_name_isvalid(const unsigned char *name, int size); /* 0 if not valid */
45 
46 typedef struct jdns_packet_question
47 {
48 	JDNS_OBJECT
49 	jdns_string_t *qname;
50 	unsigned short int qtype, qclass;
51 } jdns_packet_question_t;
52 
53 jdns_packet_question_t *jdns_packet_question_new();
54 jdns_packet_question_t *jdns_packet_question_copy(const jdns_packet_question_t *a);
55 void jdns_packet_question_delete(jdns_packet_question_t *a);
56 
57 typedef struct jdns_packet_write jdns_packet_write_t;
58 typedef struct jdns_packet jdns_packet_t;
59 
60 typedef struct jdns_packet_resource
61 {
62 	JDNS_OBJECT
63 	jdns_string_t *qname;
64 	unsigned short int qtype, qclass;
65 	unsigned long int ttl; /* 31-bit number, top bit always 0 */
66 	unsigned short int rdlength;
67 	unsigned char *rdata;
68 
69 	/* private */
70 	jdns_list_t *writelog; /* jdns_packet_write_t */
71 } jdns_packet_resource_t;
72 
73 jdns_packet_resource_t *jdns_packet_resource_new();
74 jdns_packet_resource_t *jdns_packet_resource_copy(const jdns_packet_resource_t *a);
75 void jdns_packet_resource_delete(jdns_packet_resource_t *a);
76 void jdns_packet_resource_add_bytes(jdns_packet_resource_t *a, const unsigned char *data, int size);
77 void jdns_packet_resource_add_name(jdns_packet_resource_t *a, const jdns_string_t *name);
78 int jdns_packet_resource_read_name(const jdns_packet_resource_t *a, const jdns_packet_t *p, int *at, jdns_string_t **name);
79 
80 struct jdns_packet
81 {
82 	JDNS_OBJECT
83 	unsigned short int id;
84 	struct
85 	{
86 		unsigned short qr, opcode, aa, tc, rd, ra, z, rcode;
87 	} opts;
88 
89 	/* item counts as specified by the packet.  do not use these
90 	//   for iteration over the item lists, since they can be wrong
91 	//   if the packet is truncated. */
92 	int qdcount, ancount, nscount, arcount;
93 
94 	/* value lists */
95 	jdns_list_t *questions;         /* jdns_packet_question_t */
96 	jdns_list_t *answerRecords;     /* jdns_packet_resource_t */
97 	jdns_list_t *authorityRecords;  /* jdns_packet_resource_t */
98 	jdns_list_t *additionalRecords; /* jdns_packet_resource_t */
99 
100 	/* since dns packets are allowed to be truncated, it is possible
101 	//   for a packet to not get fully parsed yet still be considered
102 	//   successfully parsed.  this flag means the packet was fully
103 	//   parsed also. */
104 	int fully_parsed;
105 
106 	int raw_size;
107 	unsigned char *raw_data;
108 };
109 
110 jdns_packet_t *jdns_packet_new();
111 jdns_packet_t *jdns_packet_copy(const jdns_packet_t *a);
112 void jdns_packet_delete(jdns_packet_t *a);
113 int jdns_packet_import(jdns_packet_t **a, const unsigned char *data, int size); /* 0 on fail */
114 int jdns_packet_export(jdns_packet_t *a, int maxsize); /* 0 on fail */
115 
116 #endif
117