File: rr.c

package info (click to toggle)
dns2tcp 0.5.2-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,268 kB
  • sloc: ansic: 5,320; sh: 3,553; makefile: 63
file content (125 lines) | stat: -rw-r--r-- 4,085 bytes parent folder | download | duplicates (4)
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
/*
** Copyright (C) 2006 Olivier DEMBOUR
** $Id: rr.c,v 1.4.4.4 2010/02/11 16:06:37 dembour Exp $
**
** 
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with This program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include <string.h>
#include <stdio.h>

#include "dns.h"
#include "client.h"
#include "requests.h"
#include "rr.h"
#include "debug.h"


t_rr_functions rr_function[] = {
  { "TXT",  TYPE_TXT,	0, &rr_decode_next_reply_encode,	0 /* UNUSED */},
  { "KEY",  TYPE_KEY,	0, &rr_decode_next_reply_raw,		0 /* UNUSED */},
  {0,0,0,0,0}
  /*
  { "A",    TYPE_A,	0, &rr_decode_next_reply_encode,	0 },
  { "SIG",  TYPE_SIG,	0, &rr_decode_next_reply_raw,		0 },
  { "NS",  TYPE_NS,	0, 0, 0},
*/
};


t_rr_functions		*get_rr_function_by_type(uint16_t type)
{
  int			i = 0;
  
  while (rr_function[i].type 
	 && (rr_function[i].type != type))
    i++;
  return (rr_function[i].type ? &rr_function[i] : 0);
}

t_rr_functions		*get_rr_function_by_name(char *name)
{
  int			i = 0;
  
  while (rr_function[i].name
	 && (strcmp(rr_function[i].name, name)))
    i++;
  return (rr_function[i].name ? &rr_function[i] : 0);
}


 struct rr_hdr		*jump_next_reply(t_request *req, char *output, int max_len, int idx, uint8_t is_encode)
{
  void			*ptr;
  uint32_t		count;
  struct rr_hdr		*answer;
  struct dns_hdr	*hdr;

  hdr = (struct dns_hdr *) &(req->req_data);
  if (!(ptr  = jump_end_query(&(req->req_data), GET_16(&hdr->qdcount), req->len)))
    {
      fprintf(stderr, "invalid reply\n");
      return (0);
    }
   for (count = GET_16(&hdr->ancount); count ; count--)
    {
      if (idx + 1 >  GET_16(&hdr->ancount))
	return (0);
      if ((answer = jump_qname(ptr, req->len - (int) ((unsigned long) ptr - (unsigned long) hdr))) == 0)
	return (0);
      if ((GET_16(&answer->rdlength) + (uint16_t)((unsigned long)answer-(unsigned long)hdr)) > req->len)
	return (0);
      if ( (JUMP_RR_HDR(answer)[0 + is_encode] - idx) == 'A')
	return (answer);
      ptr = (void *)(JUMP_RR_HDR(answer) + GET_16(&answer->rdlength));
    }
   return (0);
}

int                     rr_decode_next_reply_encode(t_request *req, char *output, int max_len, int idx)
{
  struct rr_hdr	         *reply;
  char                  buffer[MAX_EDNS_LEN - DNS_HDR_SIZE - RR_HDR_SIZE];
  
  if (!(reply = jump_next_reply(req, output, max_len, idx, 1)))
    return (0);
  
  if (ENCODED_LEN(DECODED_BASE64_SIZE(strlen(JUMP_RR_HDR(reply)))) > max_len)
    {
      DPRINTF(1,"Packet seems too big, this part is drop");
      return (0);
    }
  dns_simple_decode_strip_dot(JUMP_RR_HDR(reply), buffer, GET_16(&(reply->rdlength)));
  DPRINTF(3, "%s base64 data was = %s (reply len = %d)\n", __FUNCTION__, &buffer[1],  GET_16(&(reply->rdlength)));
  /*  jump idx  ->  &buffer[1] */
  return (base64_decode((unsigned char *)output, &buffer[1]));
}

int                     rr_decode_next_reply_raw(t_request *req, char *output, int max_len, int idx)
{
  struct rr_hdr		*reply;
  char                  buffer[MAX_EDNS_LEN - DNS_HDR_SIZE - RR_HDR_SIZE];
  
  if (!(reply = jump_next_reply(req, output, max_len, idx, 0)))
    return (0);
  memset(buffer, 0, sizeof(buffer));
  strncpy(buffer, JUMP_RR_HDR(reply), GET_16(&(reply->rdlength)));
  DPRINTF(3, "%s base64 data was = %s (reply len = %d)\n", __FUNCTION__, buffer,  GET_16(&(reply->rdlength)));
  if (DECODED_BASE64_SIZE(strlen(buffer)) > max_len)
    return (0);
  /*  jump idx  ->  &buffer[1] */
  return (base64_decode((unsigned char *)output, &buffer[1]));
 }