-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtest.c
206 lines (174 loc) · 4.97 KB
/
test.c
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
194
195
196
197
198
199
200
201
202
203
204
205
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <netdb.h>
uint8_t *processName(uint8_t *bstart, uint8_t *bcur, char *name);
void dns_format(char* dns, char* host);
struct UDP_header{
unsigned int id : 16;
unsigned int qr : 1; /*query or response*/
unsigned int Opcode : 4;/**/
unsigned int aa : 1; /**/
unsigned int tc : 1; /**/
unsigned int rd : 1;/**/
unsigned int ra : 1;/**/
unsigned int z : 1;/**/
unsigned int ad : 1;/**/
unsigned int cd : 1;/**/
unsigned int rcode : 4;/**/
unsigned int qcount;/*question count*/
unsigned int acount;/*answer count*/
unsigned int nscount;/*authority count*/
unsigned int arcount;/*addition info count*/
};
struct DNS_query{
unsigned int type;
unsigned int class;
};
typedef struct{
char *name;
struct DNS_query *q;
}QUERY;
struct response_fields{
unsigned int type;
unsigned int class;
unsigned int ttl;
unsigned int dl;
};
struct response{
char *name;
struct response_fields *rf;
char *res_data;
};
int main(int argc, char **argv){
char buff[65536], *name, buff_rec[65536];
struct DNS_query *question;
int bytes, bytes_rec;
int sockfd;
struct UDP_header *uheader;
struct sockaddr_in dest_address;
char ip_text[INET_ADDRSTRLEN];
/*printf("entered hostname: %s\n", argv[1]);*/
uheader = (struct UDP_header *) buff;
uheader->id = getpid();
uheader->qr = 0;
uheader->Opcode = 0;
uheader->aa = 0;
uheader->tc = 0;
uheader->rd = 1; /*query is recursive*/
uheader->ra = 0;
uheader->z = 0;
uheader->ad = 0;
uheader->cd = 0;
uheader->rcode = 0;
uheader->qcount = htons(1);
uheader->acount = 0;
uheader->nscount = 0;
uheader->arcount = 0;
/*create a UDP socket*/
sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(sockfd < 0){
perror("error creating socket\n");
}
/* dest_address = (struct sockaddr_in *) &address;*/
bzero(&dest_address, sizeof(dest_address));
dest_address.sin_family = AF_INET;
dest_address.sin_port = htons(53);
dest_address.sin_addr.s_addr = inet_addr("8.8.8.8");
/* printf("sin_port: %u\n", dest_address->sin_port); */
inet_ntop(AF_INET, &(dest_address.sin_addr), ip_text, INET_ADDRSTRLEN);
/*!!!*/
name = &buff[sizeof(struct UDP_header)];
/*processName(buff, q, argv[1]);*/
dns_format(name, argv[1]);
question = (struct DNS_query *) &buff[sizeof(struct UDP_header) + strlen(name) + 1];
/*query type*/
question->type = htons(1);
question->class = htons(1);
/* printf("%s\n", name);*/
/* printf("%d\n", question->type);*/
bytes = sendto(sockfd, &buff, sizeof(struct UDP_header) + sizeof(struct DNS_query) + strlen(name) + 1, 0, (struct sockaddr *) &dest_address, sizeof(struct sockaddr_in));
printf("bytes sent: %d\n", bytes);
/*processName(&uheader, hostname);*/
if (bytes < -1){
perror("sendto error\n");
return -1;
}
bytes_rec = recvfrom(sockfd, &buff_rec, 65536, NULL, 0);
printf("bytes in response: %d\n", bytes_rec);
return 0;
}
/* Processes one string in a DNS resource record.
*
* bstart (in): pointer to the start of the DNS message (UDP payload)
* bcur (in): pointer to the currently processed position in a message.
This should point to the start of compressed or uncompressed
name string.
* name (out): buffer for storing the name string in dot-separated format
* "www.google.com" = name
* returns: updated position of bcur, pointing to the next position
* following the name
*/
uint8_t *processName(uint8_t *bstart, uint8_t *bcur, char *name)
{
uint8_t *p = bcur;
char strbuf[80];
char *strp;
int compressed = 0;
name[0] = 0;
do {
strp = strbuf;
if ((*p & 0xc0) == 0xc0) { /* first two bits are set =>
compressed format */
uint16_t offset = (*p & 0x3f);
offset = (offset << 8) + *(p+1);
p = bstart + offset; /* move the read pointer to the
offset given in message */
if (!compressed) bcur += 2; /* adjustment of bcur must
only be done once, in
case there are multiple
nested pointers in msg */
compressed = 1;
} else if (*p > 0) {
/* strbuf contains one element of name, not full name*/
memcpy(strbuf, p+1, *p);
strp += *p;
p += *p + 1;
if (!compressed)
bcur = p; /* adjustment of bcur based on string
string length is only done if it
was not compressed, otherwise it
is assumed to be 16 bits always */
*strp = '.';
*(strp+1) = 0;
strcat(name, strbuf);
}
} while (*p > 0);
if (!compressed) bcur++; /* compensate for trailing 0 (unless name was
compressed) */
return bcur;
}
void dns_format(char* dns, char* host)
{
int lock=0 , i;
strcat((char*)host,".");
for(i=0 ; i<(int)strlen((char*)host) ; i++)
{
if(host[i]=='.')
{
*dns++=i-lock;
for(;lock<i;lock++)
{
*dns++=host[lock];
}
lock++; /*or lock=i+1;*/
}
}
*dns++='\0';
}