--- /dev/null
+/*
+ * packet.c
+ *
+ * dns packet implementation
+ *
+ * a Net::DNS like library for C
+ *
+ * (c) NLnet Labs, 2004
+ *
+ * See the file LICENSE for the license
+ */
+
+#include "config.h"
+
+#include "rdata.h"
+#include "rr.h"
+#include "prototype.h"
+#include "packet.h"
+
+/* Access functions
+ * do this as functions to get type checking
+ */
+
+/* read */
+uint16_t
+packet_id(t_packet *packet)
+{
+ return packet->header->id;
+}
+
+uint8_t
+packet_qr(t_packet *packet)
+{
+ return packet->header->qr;
+}
+
+uint8_t
+packet_aa(t_packet *packet)
+{
+ return packet->header->aa;
+}
+
+uint8_t
+packet_tc(t_packet *packet)
+{
+ return packet->header->tc;
+}
+
+uint8_t
+packet_rd(t_packet *packet)
+{
+ return packet->header->rd;
+}
+
+uint8_t
+packet_cd(t_packet *packet)
+{
+ return packet->header->cd;
+}
+
+uint8_t
+packet_ra(t_packet *packet)
+{
+ return packet->header->ra;
+}
+
+uint8_t
+packet_ad(t_packet *packet)
+{
+ return packet->header->ad;
+}
+
+uint8_t
+packet_opcode(t_packet *packet)
+{
+ return packet->header->opcode;
+}
+
+uint8_t
+packet_rcode(t_packet *packet)
+{
+ return packet->header->rcode;
+}
+
+uint16_t
+packet_qdcount(t_packet *packet)
+{
+ return packet->header->qdcount;
+}
+
+uint16_t
+packet_ancount(t_packet *packet)
+{
+ return packet->header->ancount;
+}
+
+uint16_t
+packet_nscount(t_packet *packet)
+{
+ return packet->header->nscount;
+}
+
+uint16_t
+packet_arcount(t_packet *packet)
+{
+ return packet->header->arcount;
+}
+
+
+/* write */
+void
+packet_set_id(t_packet *packet, uint16_t id)
+{
+ packet->header->id = id;
+}
+
+void
+packet_set_qr(t_packet *packet, uint8_t qr)
+{
+ packet->header->qr = qr;
+}
+
+void
+packet_set_aa(t_packet *packet, uint8_t aa)
+{
+ packet->header->aa = aa;
+}
+
+void
+packet_set_tc(t_packet *packet, uint8_t tc)
+{
+ packet->header->tc = tc;
+}
+
+void
+packet_set_rd(t_packet *packet, uint8_t rd)
+{
+ packet->header->rd = rd;
+}
+
+void
+packet_set_cd(t_packet *packet, uint8_t cd)
+{
+ packet->header->cd = cd;
+}
+
+void
+packet_set_ra(t_packet *packet, uint8_t ra)
+{
+ packet->header->ra = ra;
+}
+
+void
+packet_set_ad(t_packet *packet, uint8_t ad)
+{
+ packet->header->ad = ad;
+}
+
+void
+packet_set_opcode(t_packet *packet, uint8_t opcode)
+{
+ packet->header->opcode = opcode;
+}
+
+void
+packet_set_rcode(t_packet *packet, uint8_t rcode)
+{
+ packet->header->rcode = rcode;
+}
+
+void
+packet_set_qdcount(t_packet *packet, uint16_t qdcount)
+{
+ packet->header->qdcount = qdcount;
+}
+
+void
+packet_set_ancount(t_packet *packet, uint16_t ancount)
+{
+ packet->header->ancount = ancount;
+}
+
+void
+packet_set_nscount(t_packet *packet, uint16_t nscount)
+{
+ packet->header->nscount = nscount;
+}
+
+void
+packet_set_arcount(t_packet *packet, uint16_t arcount)
+{
+ packet->header->arcount = arcount;
+}
+
+
+/* Create/destroy/convert functions
+ */
+
+t_packet *
+dns_packet_new()
+{
+ t_packet *packet;
+ packet = xmalloc(sizeof(t_packet));
+ packet->header = xmalloc(sizeof(t_header));
+ packet->question = NULL;
+ packet->answer = NULL;
+ packet->authority = NULL;
+ packet->additional = NULL;
+ return packet;
+}
+
+size_t
+dns_wire2packet_header(uint8_t *wire, size_t pos, t_packet *packet)
+{
+ size_t len = 0;
+ uint16_t int16;
+ uint8_t int8;
+
+ memcpy(&int16, &wire[pos+len], 2);
+ packet_set_id(packet, ntohs(int16));
+ len += 2;
+
+ memcpy(&int8, &wire[pos+len], 1);
+ packet_set_qr(packet, (int8 & (uint8_t) 0x80) >> 7);
+ packet_set_opcode(packet, (int8 & (uint8_t) 0x78) >> 3);
+ packet_set_aa(packet, (int8 & (uint8_t) 0x04) >> 2);
+ packet_set_tc(packet, (int8 & (uint8_t) 0x02) >> 1);
+ packet_set_rd(packet, (int8 & (uint8_t) 0x01));
+ len++;
+
+ memcpy(&int8, &wire[pos+len], 1);
+ packet_set_ra(packet, (int8 & (uint8_t) 0x80) >> 7);
+ packet_set_ad(packet, (int8 & (uint8_t) 0x20) >> 5);
+ packet_set_cd(packet, (int8 & (uint8_t) 0x10) >> 4);
+ packet_set_rcode(packet, (int8 & (uint8_t) 0x0f));
+ len++;
+
+ memcpy(&int16, &wire[pos+len], 2);
+ packet_set_qdcount(packet, ntohs(int16));
+ len += 2;
+
+ memcpy(&int16, &wire[pos+len], 2);
+ packet_set_ancount(packet, ntohs(int16));
+ len += 2;
+
+ memcpy(&int16, &wire[pos+len], 2);
+ packet_set_nscount(packet, ntohs(int16));
+ len += 2;
+
+ memcpy(&int16, &wire[pos+len], 2);
+ packet_set_arcount(packet, ntohs(int16));
+ len += 2;
+
+ return len;
+}
+
+size_t
+dns_wire2packet(uint8_t *wire, t_packet *packet)
+{
+ size_t pos = 0;
+
+ pos += dns_wire2packet_header(wire, pos, packet);
+
+ /* TODO: rrs :) */
+
+ return pos;
+}
+
#ifdef _PACKET_H
#else
#define _PACKET_H
-
-#include "rdata.h"
-#include "rr.h"
+#include "config.h"
/**
* \brief Header of a dns packet
/** \brief auth sec */
uint16_t nscount;
/** \brief add sec */
- uint16_t acount;
+ uint16_t arcount;
};
typedef struct type_struct_header t_header;
*
* This structure contains a complete DNS packet (either a query or an answer)
*/
-struct struct_packet_type
+struct type_struct_packet
{
/** \brief header section */
t_header *header;
t_rrset *additional;
};
typedef struct type_struct_packet t_packet;
-
-#endif /* _PACKET_H */
+
+/* prototypes */
+uint16_t packet_id(t_packet *);
+uint8_t packet_qr(t_packet *);
+uint8_t packet_aa(t_packet *);
+uint8_t packet_tc(t_packet *);
+uint8_t packet_rd(t_packet *);
+uint8_t packet_cd(t_packet *);
+uint8_t packet_ra(t_packet *);
+uint8_t packet_ad(t_packet *);
+uint8_t packet_opcode(t_packet *);
+uint8_t packet_rcode(t_packet *);
+uint16_t packet_qdcount(t_packet *);
+uint16_t packet_ancount(t_packet *);
+uint16_t packet_nscount(t_packet *);
+uint16_t packet_arcount(t_packet *);
+
+void packet_set_id(t_packet *, uint16_t);
+void packet_set_qr(t_packet *, uint8_t);
+void packet_set_aa(t_packet *, uint8_t);
+void packet_set_tc(t_packet *, uint8_t);
+void packet_set_rd(t_packet *, uint8_t);
+void packet_set_cd(t_packet *, uint8_t);
+void packet_set_ra(t_packet *, uint8_t);
+void packet_set_ad(t_packet *, uint8_t);
+void packet_set_opcode(t_packet *, uint8_t);
+void packet_set_rcode(t_packet *, uint8_t);
+void packet_set_qdcount(t_packet *, uint16_t);
+void packet_set_ancount(t_packet *, uint16_t);
+void packet_set_nscount(t_packet *, uint16_t);
+void packet_set_arcount(t_packet *, uint16_t);
+
+/**
+ * Allocates and initializes a t_packet structure
+ */
+t_packet *dns_packet_new();
+
+/**
+ * Converts the data on the uint8_t bytearray (in wire format) to a DNS packet
+ *
+ * Returns the number of bytes read from the wire
+ */
+size_t dns_wire2packet(uint8_t *, t_packet *);
+
+#endif
{
t_rdata_field *rd_f;
t_rr *rr;
-
+ uint8_t *wire;
+ t_packet *packet;
+
rr = rr_new();
rd_f = rd_field_new(20, RD_DNAME_T, (uint8_t*)"hallo.nl");
rr_push_rd_field(rr, rd_f);
xprintf_rr(rr);
+
+ wire = xmalloc(100);
+ wire[0] = 0xc2;
+ wire[1] = 0xb4;
+ wire[2] = 0x81;
+ wire[3] = 0x80;
+ wire[4] = 0x00;
+ wire[5] = 0x01;
+ wire[6] = 0x00;
+ wire[7] = 0x01;
+ wire[8] = 0x00;
+ wire[9] = 0x02;
+ wire[10] = 0x00;
+ wire[11] = 0x02;
+ wire[12] = 0x03;
+ wire[13] = 0x77;
+ wire[14] = 0x77;
+ wire[15] = 0x77;
+ wire[16] = 0x0b;
+ wire[17] = 0x6b;
+ wire[18] = 0x61;
+ wire[19] = 0x6e;
+
+ packet = dns_packet_new();
+ dns_wire2packet(wire, packet);
+
+ printf("packet id: %d\n", packet_id(packet));
+ printf("qr bit: %d\n", packet_qr(packet));
+ printf("opcode: %d\n", packet_opcode(packet));
+ printf("aa bit: %d\n", packet_aa(packet));
+ printf("tc bit: %d\n", packet_tc(packet));
+ printf("rd bit: %d\n", packet_rd(packet));
+ printf("cd bit: %d\n", packet_cd(packet));
+ printf("ra bit: %d\n", packet_ra(packet));
+ printf("ad bit: %d\n", packet_ad(packet));
+ printf("rcode: %d\n", packet_rcode(packet));
+ printf("qdcount: %d\n", packet_qdcount(packet));
+ printf("ancount: %d\n", packet_ancount(packet));
+ printf("nscount: %d\n", packet_nscount(packet));
+ printf("arcount: %d\n", packet_arcount(packet));
return 0;
}