XINU
Functions
dns.c File Reference
#include <xinu.h>
#include <string.h>
#include <dns.h>
Include dependency graph for dns.c:

Go to the source code of this file.

Functions

local uint32 dns_bldq (char *, char *)
 
local uint32 dns_geta (char *, struct dnspkt *)
 
local uint32 dns_getrname (char *, char *, char *)
 
uint32 dnslookup (char *dname)
 

Function Documentation

◆ dns_bldq()

uint32 dns_bldq ( char *  dname,
char *  data 
)

Definition at line 85 of file dns.c.

References DNS_QC_IN, DNS_QT_A, DNSDATASIZ, htons, memcpy(), strlen(), and SYSERR.

Referenced by dnslookup().

89 {
90  uint32 qlen; /* Length of Question */
91  uint32 dlen; /* Length of domain name */
92  byte *llptr; /* Label length pointer */
93  int32 i; /* Loop index */
94  uint16 tmp; /* Temporary for conversion */
95 
96  /* Get length of the domain name */
97 
98  dlen = strlen(dname);
99 
100  /* Allocate a length byte for the next label and start at zero */
101 
102  llptr = (byte*)(data++);
103  *llptr = 0;
104 
105  /* Initialize the query length */
106 
107  qlen = 1;
108 
109  /* Add each character in the Domain Name to the question */
110 
111  for(i = 0; i < dlen; i++) {
112 
113  if(qlen >= DNSDATASIZ) {
114  return (uint32)SYSERR;
115  }
116  if(dname[i] != '.') {
117  /* Add normal character to the existing label */
118  *data++ = dname[i];
119  *llptr = *llptr + 1;
120  } else {
121  /* Dot means we should start a new label */
122  llptr = (byte*)(data++);
123  *llptr = 0;
124  }
125  qlen++;
126  }
127 
128  /* Terminate the query with a zero length */
129 
130  *data++ = 0;
131  qlen++;
132 
133  /* Set the Qtype to a Type A Address */
134 
135  tmp = htons(DNS_QT_A);
136  memcpy(data, (char *)&tmp, 2);
137  data += 2;
138  qlen += 2;
139 
140  /* Set the QClass to Internet */
141 
142  tmp = htons(DNS_QC_IN);
143  memcpy(data, (char *)&tmp, 2);
144  qlen += 2;
145 
146  /* Return the total packet length */
147 
148  return sizeof(struct dnspkt) - DNSDATASIZ + qlen;
149 }
unsigned char byte
符号なし8ビット値(unsigned char)
Definition: kernel.h:7
#define SYSERR
処理が失敗した場合
Definition: kernel.h:79
#define DNS_QC_IN
Definition: dns.h:42
Definition: dns.h:14
#define DNS_QT_A
Definition: dns.h:37
int strlen(char *str)
NULL終端された文字列の長さを返す。NULL終端は長さに含まない。
Definition: strlen.c:11
int data
データセグメントの開始アドレス(リンカが追加する)
int int32
符号あり32ビット整数(int)
Definition: kernel.h:11
unsigned short uint16
符号なし16ビット整数(unsigned short)
Definition: kernel.h:17
#define DNSDATASIZ
Definition: dns.h:9
unsigned int uint32
符号なし32ビット整数(unsigned int)
Definition: kernel.h:15
#define htons(x)
Definition: prototypes.h:619
void * memcpy(void *, const void *, int32)
メモリAの領域(source)からメモリBの領域(Destination)にN Byteコピーする。
Definition: memcpy.c:13
Here is the call graph for this function:
Here is the caller graph for this function:

◆ dns_geta()

uint32 dns_geta ( char *  dname,
struct dnspkt rpkt 
)

Definition at line 155 of file dns.c.

References dnspkt::ancount, dnspkt::data, dns_getrname(), DNS_QT_A, network::ipmask, network::ipprefix, memcpy(), namlen(), NetData, ntohl, ntohs, dnspkt::qucount, strlen(), strncmp(), and SYSERR.

Referenced by dnslookup().

159 {
160  uint16 qcount; /* Number of Questions */
161  uint16 tmp16; /* Used for endian conversion */
162  uint16 acount; /* Number of Answers */
163  uint32 ipaddr; /* IP address from the response */
164  char *dptr; /* Data pointer */
165  byte llen; /* Label length */
166  int32 i; /* Loop index */
167 
168  /* Pick up the count of questions */
169 
170  memcpy((char *)&tmp16, (char *) &rpkt->qucount, 2);
171  qcount = ntohs(tmp16);
172  dptr = rpkt->data;
173 
174  /* Skip qcount questions */
175 
176  for(i = 0; i < qcount; i++) {
177 
178  /* Get the label length */
179 
180  llen = *((byte *)dptr);
181 
182  /* While we haven't reached the end of this domain name */
183 
184  while(llen != 0) {
185 
186  /* Pointer means end of name */
187 
188  if(llen > 63) {
189  dptr += 2;
190  break;
191  }
192 
193  /* Move to the next label */
194 
195  dptr += (llen + 1);
196  llen = *((byte *)dptr);
197  }
198 
199  /* Move to next question */
200 
201  if (llen == 0) {
202  dptr += 1;
203  }
204 
205  /* Skip the type and class */
206 
207  dptr += (2 + 2);
208  }
209 
210  /* Pick up the count of answers */
211 
212  memcpy((char *)&tmp16, (char *)&rpkt->ancount, 2);
213  acount = ntohs(tmp16);
214 
215  /* Set the IP address to zero */
216 
217  ipaddr = 0;
218 
219  /* Check each answer to see if it matches the local net */
220 
221  for(i = 0; i < acount; i++) {
222 
223  char rname[1024];
224  uint16 tmptype;
225  uint32 tmpip;
226  uint16 tmplen;
227  uint32 namlen;
228 
229  /* Get the name, and the number of bytes it occupied */
230  /* in the packet (may be short if the name contains */
231  /* pointer (e.g.,back to the question) */
232 
233  namlen = dns_getrname( (char *)rpkt, dptr, rname);
234  dptr += namlen;
235 
236  /* Verify that the answer matches and is Type A */
237 
238  memcpy((char *)&tmptype, dptr, 2);
239  if( (strncmp(dname, rname, strlen(dname)) == 0) &&
240  (ntohs(tmptype) == DNS_QT_A) ) {
241 
242  /* Pick up the IP address */
243 
244  memcpy((char *)&tmpip, dptr+10, 4);
245  if ((ipaddr == 0) ||
246  ((NetData.ipmask&ntohl(tmpip)) ==
247  NetData.ipprefix) ) {
248  ipaddr = tmpip;
249  }
250  }
251 
252 
253  /* Move past the type, class, and ttl fields to the length */
254 
255  dptr += 8;
256 
257  /* Move past the length field itself (2 bytes) and data */
258 
259  memcpy((char *)&tmplen, dptr, 2);
260  dptr += ntohs(tmplen) + 2;
261  }
262 
263  if (ipaddr != 0) {
264  return ipaddr;
265  } else {
266  return (uint32)SYSERR;
267  }
268 }
unsigned char byte
符号なし8ビット値(unsigned char)
Definition: kernel.h:7
int32 strncmp(const char *, const char *, int32)
uint32 ipmask
Definition: net.h:57
uint16 qucount
Definition: dns.h:28
struct network NetData
Definition: net.c:6
#define SYSERR
処理が失敗した場合
Definition: kernel.h:79
#define DNS_QT_A
Definition: dns.h:37
uint16 ancount
Definition: dns.h:29
int strlen(char *str)
NULL終端された文字列の長さを返す。NULL終端は長さに含まない。
Definition: strlen.c:11
local uint32 dns_getrname(char *, char *, char *)
Definition: dns.c:274
#define ntohl(x)
Definition: prototypes.h:623
char data[DNSDATASIZ]
Definition: dns.h:32
int int32
符号あり32ビット整数(int)
Definition: kernel.h:11
unsigned short uint16
符号なし16ビット整数(unsigned short)
Definition: kernel.h:17
#define ntohs(x)
Definition: prototypes.h:622
uint32 ipprefix
Definition: net.h:58
int32 namlen(char *, int32)
Definition: mount.c:60
unsigned int uint32
符号なし32ビット整数(unsigned int)
Definition: kernel.h:15
void * memcpy(void *, const void *, int32)
メモリAの領域(source)からメモリBの領域(Destination)にN Byteコピーする。
Definition: memcpy.c:13
Here is the call graph for this function:
Here is the caller graph for this function:

◆ dns_getrname()

uint32 dns_getrname ( char *  sop,
char *  son,
char *  dst 
)

Definition at line 274 of file dns.c.

References memcpy(), ntohs, and NULLCH.

Referenced by dns_geta().

279 {
280  byte llen; /* Label length */
281  uint16 tmpoff; /* Temporary to hold offset */
282  uint16 offset; /* Offset in host byte order */
283  char *sson; /* Saved start of name */
284  int32 i; /* Loop index */
285 
286  /* Record initial position */
287 
288  sson = son;
289 
290  /* Pick up length of initial label */
291 
292  llen = *son++;
293 
294  /* While not at the end of the name, pick up a label */
295 
296  while(llen != 0) {
297 
298  if(llen <= 63) {
299  /* Copy the label into the destination string */
300  for(i = 0; i < llen; i++) {
301  *dst++ = *son++;
302  }
303  *dst++ = '.';
304  llen = *son++;
305  } else {
306  /* Handle pointer to remainder of name */
307  son--;
308  memcpy( (char *)&tmpoff, son, 2);
309  offset = ntohs(tmpoff) & 0x3fff;
310  son += 2;
311  dns_getrname(sop, sop+offset, dst);
312  return (son-sson);
313  }
314  }
315 
316  /* Null-terminate the string */
317 
318  dst--;
319  *dst = NULLCH;
320 
321  return (uint32)(son-sson);
322 }
unsigned char byte
符号なし8ビット値(unsigned char)
Definition: kernel.h:7
local uint32 dns_getrname(char *, char *, char *)
Definition: dns.c:274
int int32
符号あり32ビット整数(int)
Definition: kernel.h:11
unsigned short uint16
符号なし16ビット整数(unsigned short)
Definition: kernel.h:17
#define ntohs(x)
Definition: prototypes.h:622
unsigned int uint32
符号なし32ビット整数(unsigned int)
Definition: kernel.h:15
#define NULLCH
NULL文字(NULL終端)
Definition: kernel.h:70
void * memcpy(void *, const void *, int32)
メモリAの領域(source)からメモリBの領域(Destination)にN Byteコピーする。
Definition: memcpy.c:13
Here is the call graph for this function:
Here is the caller graph for this function:

◆ dnslookup()

uint32 dnslookup ( char *  dname)

Definition at line 15 of file dns.c.

References currpid, dns_bldq(), dns_geta(), DNSLPORT, DNSPORT, DNSRETRY, network::dnsserver, DNSTIMEOUT, getlocalip(), htons, kprintf(), memset(), NetData, ntohl, NULL, SYSERR, TIMEOUT, udp_recv(), udp_register(), udp_release(), and udp_send().

Referenced by xsh_ping().

18 {
19  struct dnspkt qpkt; /* Query Packet buffer */
20  struct dnspkt rpkt; /* Response Packet buffer */
21  uint32 nsaddr; /* Name server IP address */
22  uint32 qlen; /* Query length */
23  uid32 slot; /* UDP Slot */
24  int32 rlen; /* Response length */
25  uint32 ipaddr; /* IP address from response */
26  int32 retval; /* Return value */
27  int32 i; /* Loop index */
28 
29  /* Check if we have a valid name pointer */
30 
31  if(dname == NULL) {
32  return (uint32)SYSERR;
33  }
34 
35  /* Obtain the IP address of a DNS server */
36 
37  retval = getlocalip();
38  nsaddr = NetData.dnsserver;
39  if ( (retval == SYSERR) || (NetData.dnsserver == 0) ) {
40  kprintf("Cannot find a DNS server\n");
41  return (uint32)SYSERR;
42  }
43 
44  /* Register a UDP Slot */
45 
46  slot = udp_register(nsaddr, DNSPORT, DNSLPORT);
47  if(slot == SYSERR) {
48  return (uint32)SYSERR;
49  }
50 
51  /* Build the Query message */
52 
53  memset((char *)&qpkt, 0, sizeof(struct dnspkt));
54 
55  qpkt.id = currpid;
56  qpkt.rd = 1;
57  qpkt.qucount = htons(1);
58 
59  qlen = dns_bldq(dname, qpkt.data);
60 
61  ipaddr = (uint32)SYSERR;
62  for(i = 0; (ipaddr==(uint32)SYSERR) && (i < DNSRETRY); i++) {
63 
64  /* Send the Query message */
65 
66  udp_send(slot, (char*)&qpkt, qlen);
67 
68  /* Wait for the response */
69 
70  rlen = udp_recv(slot, (char*)&rpkt, sizeof(struct dnspkt),
71  DNSTIMEOUT);
72  if ( (rlen == SYSERR) || (rlen == TIMEOUT) ) {
73  continue;
74  }
75  ipaddr = dns_geta(dname, &rpkt);
76  }
77  udp_release(slot);
78  return ntohl(ipaddr);
79 }
syscall kprintf(char *fmt,...)
ポーリングI/Oを使用して、フォーマットされた文字列をコンソールに出力する。
Definition: kprintf.c:98
#define NULL
連結リスト用のNULLポインタ
Definition: kernel.h:68
int32 udp_recv(uid32, char *, int32, uint32)
Definition: udp.c:146
status udp_send(uid32, char *, int32)
Definition: udp.c:316
pid32 currpid
現在実行中のプロセス。
Definition: initialize.c:32
struct network NetData
Definition: net.c:6
#define SYSERR
処理が失敗した場合
Definition: kernel.h:79
Definition: dns.h:14
#define DNSLPORT
Definition: dns.h:8
local uint32 dns_geta(char *, struct dnspkt *)
Definition: dns.c:155
#define TIMEOUT
システムコールがタイムアウトした場合
Definition: kernel.h:83
#define ntohl(x)
Definition: prototypes.h:623
#define DNSTIMEOUT
Definition: dns.h:5
#define DNSRETRY
Definition: dns.h:6
int int32
符号あり32ビット整数(int)
Definition: kernel.h:11
local uint32 dns_bldq(char *, char *)
Definition: dns.c:85
uid32 udp_register(uint32, uint16, uint16)
Definition: udp.c:85
void * memset(void *, const int, int32)
指定のByteブロックに対して、同じ値をNバイト分書き込む。
Definition: memset.c:13
status udp_release(uid32)
Definition: udp.c:502
uint32 getlocalip(void)
Definition: dhcp.c:142
unsigned int uint32
符号なし32ビット整数(unsigned int)
Definition: kernel.h:15
#define htons(x)
Definition: prototypes.h:619
int32 uid32
UDPテーブルディスクリプタのID.
Definition: kernel.h:44
uint32 dnsserver
Definition: net.h:61
#define DNSPORT
Definition: dns.h:7
Here is the call graph for this function:
Here is the caller graph for this function: