Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: EthernetNetIf mbed
Revision 0:477d4e2f281a, committed 2011-07-21
- Comitter:
- okini3939
- Date:
- Thu Jul 21 16:53:11 2011 +0000
- Commit message:
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/EthernetNetIf.lib Thu Jul 21 16:53:11 2011 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/donatien/code/EthernetNetIf/#bc7df6da7589
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/TinyResolver.cpp Thu Jul 21 16:53:11 2011 +0000
@@ -0,0 +1,181 @@
+/*
+ * mbed Tiny DNS Resolver
+ * Copyright (c) 2011 Hiroshi Suga
+ * Released under the MIT License: http://mbed.org/license/mit
+ */
+
+/** @file
+ * @brief Tiny DNS Resolver
+ */
+
+#include "mbed.h"
+#include "EthernetNetIf.h"
+#include "UDPSocket.h"
+#include "TinyResolver.h"
+
+// host to network short
+#define htons( x ) ( (( (x) << 8 ) & 0xFF00) | (( (x) >> 8 ) & 0x00FF) )
+#define ntohs( x ) htons(x)
+// host to network long
+#define htonl( x ) ( (( (x) << 24 ) & 0xFF000000) \
+ | (( (x) << 8 ) & 0x00FF0000) \
+ | (( (x) >> 8 ) & 0x0000FF00) \
+ | (( (x) >> 24 ) & 0x000000FF) )
+#define ntohl( x ) htonl(x)
+
+extern EthernetNetIf eth;
+static UDPSocket *dns;
+static volatile unsigned long dnsaddr;
+static volatile unsigned long id;
+
+int createDnsRequest (char *name, char *buf) {
+ struct DnsHeader *dnsHeader;
+ struct DnsQuestionEnd *dnsEnd;
+ int len, num;
+
+ id ++;
+ dnsHeader = (struct DnsHeader*)buf;
+ dnsHeader->id = htons(id);
+ dnsHeader->flags = htons(0x100);
+ dnsHeader->questions = htons(1);
+ dnsHeader->answers = 0;
+ dnsHeader->authorities = 0;
+ dnsHeader->additional = 0;
+
+ len = sizeof(struct DnsHeader);
+ while ((num = (int)strchr(name, '.')) != NULL) {
+ num = num - (int)name;
+ buf[len] = num;
+ len ++;
+ strncpy(&buf[len], name, num);
+ name = name + num + 1;
+ len = len + num;
+ }
+
+ if ((num = strlen(name)) != NULL) {
+ buf[len] = num;
+ len ++;
+ strncpy(&buf[len], name, num);
+ len = len + num;
+ }
+ buf[len] = 0;
+ len ++;
+
+ dnsEnd = (struct DnsQuestionEnd *)&buf[len];
+ dnsEnd->type = htons(DNS_QUERY_A);
+ dnsEnd->clas = htons(DNS_CLASS_IN);
+
+ return len + sizeof(struct DnsQuestionEnd);
+}
+
+int getDnsResponse (const char *buf, int len, uint32_t *addr) {
+ int i;
+ struct DnsHeader *dnsHeader;
+ struct DnsAnswer *dnsAnswer;
+
+ // header
+ dnsHeader = (struct DnsHeader*)buf;
+ if (ntohs(dnsHeader->id) != id || (ntohs(dnsHeader->flags) & 0x800f) != 0x8000) {
+ return -1;
+ }
+
+ // skip question
+ for (i = sizeof(struct DnsHeader); buf[i] && i < len; i ++);
+ i = i + 1 + sizeof(struct DnsQuestionEnd);
+
+ // answer
+ while (i < len) {
+ dnsAnswer = (struct DnsAnswer*)&buf[i];
+
+ if (dnsAnswer->clas != htons(DNS_CLASS_IN)) {
+ return -1;
+ }
+
+ i = i + sizeof(struct DnsAnswer);
+ if (dnsAnswer->type == htons(DNS_QUERY_A)) {
+ // A record
+ *addr = ((uint32_t)buf[i] << 24) + ((uint32_t)buf[i + 1] << 16) + ((uint32_t)buf[i + 2] << 8) + (uint32_t)buf[i + 3];
+ return 0;
+ }
+ // next answer
+ i = i + dnsAnswer->length;
+ }
+
+ return -1;
+}
+
+void isr_dns (UDPSocketEvent e) {
+ char buf[512];
+ Host dsthost;
+ int len;
+
+ if (e == UDPSOCKET_READABLE) {
+ // recv responce;
+ len = dns->recvfrom(buf, sizeof(buf), &dsthost);
+#ifdef DEBUG
+ for (int i = 0; i < len; i ++) {
+ printf(" %02x", (unsigned char)buf[i]);
+ }
+ puts("\r");
+#endif
+ if (len >= sizeof(struct DnsHeader)) {
+ getDnsResponse(buf, len, (uint32_t*)&dnsaddr);
+ }
+ }
+}
+
+int getHostByName (IpAddr nameserver, const char *name, uint32_t *addr) {
+ UDPSocketErr err;
+ Host myhost, dnshost;
+ char buf[100];
+ int i, len;
+
+ // localhost
+ if (!strcmp(name, "localhost")) {
+ *addr = 0x0f000001;
+ return 0;
+ }
+
+ dnsaddr = 0;
+ dns = new UDPSocket;
+ dns->setOnEvent(isr_dns);
+
+ // bind
+ myhost.setIp(eth.getIp());
+ myhost.setPort(DNS_SRC_PORT);
+ err = dns->bind(myhost);
+ if (err != UDPSOCKET_OK) goto exit;
+
+ // send request
+ dnshost.setIp(nameserver);
+ dnshost.setPort(DNS_PORT);
+ len = createDnsRequest((char*)name, buf);
+#ifdef DEBUG
+ for (int i = 0; i < len; i ++) {
+ printf(" %02x", (unsigned char)buf[i]);
+ }
+ puts("\r");
+#endif
+ dns->sendto(buf, len, &dnshost);
+
+ // wait responce
+ for (i = 0; i < DNS_TIMEOUT / 10; i ++) {
+ if (dnsaddr) {
+ // responce
+ *addr = dnsaddr;
+ break;
+ }
+ if (i % 500 == 499) {
+ // retry
+ dns->sendto(buf, len, &dnshost);
+ }
+ Net::poll();
+ wait_ms(10);
+ }
+
+exit:
+ dns->resetOnEvent();
+ delete dns;
+
+ return dnsaddr ? 0 : -1;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/TinyResolver.h Thu Jul 21 16:53:11 2011 +0000
@@ -0,0 +1,65 @@
+/*
+ * mbed Tiny DNS Resolver
+ * Copyright (c) 2011 Hiroshi Suga
+ * Released under the MIT License: http://mbed.org/license/mit
+ */
+
+/** @file
+ * @brief Tiny DNS Resolver
+ */
+
+#ifndef TinyResolver_h
+#define TinyResolver_h
+
+#include <inttypes.h>
+
+#define DEBUG
+
+#define DNS_PORT 53
+#define DNS_SRC_PORT 1234
+#define DNS_TIMEOUT 15000 // ms
+
+// dns
+#define DNS_QUERY_A 1
+#define DNS_QUERY_NS 2
+#define DNS_QUERY_CNAME 5
+#define DNS_QUERY_PTR 12
+#define DNS_QUERY_MX 15
+#define DNS_QUERY_AAAA 28
+#define DNS_QUERY_ANY 255
+#define DNS_CLASS_IN 1
+
+struct DnsHeader {
+ uint16_t id;
+ uint16_t flags;
+ uint16_t questions;
+ uint16_t answers;
+ uint16_t authorities;
+ uint16_t additional;
+};
+
+struct DnsQuestionEnd {
+ uint16_t type;
+ uint16_t clas;
+};
+
+struct DnsAnswer {
+ uint16_t name;
+ uint16_t type;
+ uint16_t clas;
+ uint32_t ttl;
+ uint16_t length;
+} __attribute__((packed));
+
+int createDnsRequest (char *name, char *buf);
+int getDnsResponse (const char *buf, int len, uint32_t *addr);
+
+/** resolv host by name
+ * @param nameserver DNS server
+ * @param name hostname
+ * @param addr IP address (return)
+ * @return 0:success, -1:failue
+ */
+int getHostByName (IpAddr nameserver, const char *name, uint32_t *addr);
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Thu Jul 21 16:53:11 2011 +0000
@@ -0,0 +1,26 @@
+#include "mbed.h"
+#include "EthernetNetIf.h"
+#include "TinyResolver.h"
+
+DigitalOut myled(LED1);
+Serial pc(USBTX, USBRX);
+EthernetNetIf eth;
+
+int main () {
+ EthernetErr ethErr;
+ uint32_t addr;
+
+ myled = 1;
+
+ ethErr = eth.setup();
+ if(ethErr) {
+ return -1;
+ }
+
+ getHostByName(IpAddr(192,168,1,1), "mbed.org", &addr);
+
+ printf("IP address: %d.%d.%d.%d\r\n", (addr >> 24) & 0xff, (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff);
+
+ myled = 0;
+ return 0;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Thu Jul 21 16:53:11 2011 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/63bcd7ba4912