From d9bec9f42ab34383737c8a94429aa02fe76d7946 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sat, 18 Jul 2009 21:04:08 -0400 Subject: net: rename NetRxPkt to NetRxPacket The net code is mostly consistent in using 'Packet' rather than 'Pkt', so rename the minor detractor to follow suite. Signed-off-by: Mike Frysinger Signed-off-by: Ben Warren --- net/bootp.c | 2 +- net/net.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'net') diff --git a/net/bootp.c b/net/bootp.c index 77057c6c0a..d5f9c4be6d 100644 --- a/net/bootp.c +++ b/net/bootp.c @@ -124,7 +124,7 @@ static void BootpCopyNetParams(Bootp_t *bp) NetCopyIP(&tmp_ip, &bp->bp_siaddr); if (tmp_ip != 0) NetCopyIP(&NetServerIP, &bp->bp_siaddr); - memcpy (NetServerEther, ((Ethernet_t *)NetRxPkt)->et_src, 6); + memcpy (NetServerEther, ((Ethernet_t *)NetRxPacket)->et_src, 6); #endif if (strlen(bp->bp_file) > 0) copy_filename (BootFile, bp->bp_file, sizeof(BootFile)); diff --git a/net/net.c b/net/net.c index 5637cf54f6..e215fd8d9a 100644 --- a/net/net.c +++ b/net/net.c @@ -139,8 +139,8 @@ uchar NetServerEther[6] = /* Boot server enet address */ { 0, 0, 0, 0, 0, 0 }; IPaddr_t NetOurIP; /* Our IP addr (0 = unknown) */ IPaddr_t NetServerIP; /* Server IP addr (0 = unknown) */ -volatile uchar *NetRxPkt; /* Current receive packet */ -int NetRxPktLen; /* Current rx packet length */ +volatile uchar *NetRxPacket; /* Current receive packet */ +int NetRxPacketLen; /* Current rx packet length */ unsigned NetIPID; /* IP packet ID */ uchar NetBcastAddr[6] = /* Ethernet bcast address */ { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; @@ -1122,8 +1122,8 @@ NetReceive(volatile uchar * inpkt, int len) printf("packet received\n"); #endif - NetRxPkt = inpkt; - NetRxPktLen = len; + NetRxPacket = inpkt; + NetRxPacketLen = len; et = (Ethernet_t *)inpkt; /* too small packet? */ -- cgit From 1a32bf41881b5dbe3119cb77a33572b4d462cabf Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Mon, 20 Jul 2009 14:53:54 -0400 Subject: Add DNS support On 04 Oct 2008 Pieter posted a dns implementation for U-Boot. http://www.mail-archive.com/u-boot-users@lists.sourceforge.net/msg10216.html > > DNS can be enabled by setting CFG_CMD_DNS. After performing a query, > the serverip environment var is updated. > > Probably there are some cosmetic issues with the patch. Unfortunatly I > do not have the time to correct these. So if anybody else likes DNS > support in U-Boot and has the time, feel free to patch it in the main tree. Here it is again - slightly modified & smaller: - update to 2009-06 (Pieter's patch was for U-Boot 1.2.0) - README.dns is added - syntax is changed (now takes a third option, the env var to store the result in) - add a random port() function in net.c - sort Makefile in ./net/Makefile - dns just returns unless a env var is given - run through checkpatch, and clean up style issues - remove packet from stack - cleaned up some comments - failure returns much faster (if server responds, don't wait for timeout) - use built in functions (memcpy) rather than byte copy. Signed-off-by: Robin Getz Signed-off-by: Pieter Voorthuijsen Signed-off-by: Ben Warren --- net/Makefile | 7 +- net/dns.c | 211 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ net/dns.h | 39 +++++++++++ net/net.c | 29 ++++++++ 4 files changed, 283 insertions(+), 3 deletions(-) create mode 100644 net/dns.c create mode 100644 net/dns.h (limited to 'net') diff --git a/net/Makefile b/net/Makefile index d341874250..835a04af45 100644 --- a/net/Makefile +++ b/net/Makefile @@ -27,13 +27,14 @@ include $(TOPDIR)/config.mk LIB = $(obj)libnet.a -COBJS-y += net.o -COBJS-y += tftp.o COBJS-y += bootp.o -COBJS-y += rarp.o +COBJS-$(CONFIG_CMD_DNS) += dns.o COBJS-y += eth.o +COBJS-y += net.o COBJS-y += nfs.o +COBJS-y += rarp.o COBJS-$(CONFIG_CMD_SNTP) += sntp.o +COBJS-y += tftp.o COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) diff --git a/net/dns.c b/net/dns.c new file mode 100644 index 0000000000..f25c3f8c24 --- /dev/null +++ b/net/dns.c @@ -0,0 +1,211 @@ +/* + * DNS support driver + * + * Copyright (c) 2008 Pieter Voorthuijsen + * Copyright (c) 2009 Robin Getz + * + * This is a simple DNS implementation for U-Boot. It will use the first IP + * in the DNS response as NetServerIP. This can then be used for any other + * network related activities. + * + * The packet handling is partly based on TADNS, original copyrights + * follow below. + * + */ + +/* + * Copyright (c) 2004-2005 Sergey Lyubka + * + * "THE BEER-WARE LICENSE" (Revision 42): + * Sergey Lyubka wrote this file. As long as you retain this notice you + * can do whatever you want with this stuff. If we meet some day, and you think + * this stuff is worth it, you can buy me a beer in return. + */ + +#include +#include +#include + +#include "dns.h" + +char *NetDNSResolve; /* The host to resolve */ +char *NetDNSenvvar; /* The envvar to store the answer in */ + +static int DnsOurPort; + +static void +DnsSend(void) +{ + struct header *header; + int n, name_len; + uchar *p, *pkt; + const char *s; + const char *name; + enum dns_query_type qtype = DNS_A_RECORD; + + name = NetDNSResolve; + pkt = p = (uchar *)(NetTxPacket + NetEthHdrSize() + IP_HDR_SIZE); + + /* Prepare DNS packet header */ + header = (struct header *) pkt; + header->tid = 1; + header->flags = htons(0x100); /* standard query */ + header->nqueries = htons(1); /* Just one query */ + header->nanswers = 0; + header->nauth = 0; + header->nother = 0; + + /* Encode DNS name */ + name_len = strlen(name); + p = (uchar *) &header->data; /* For encoding host name into packet */ + + do { + s = strchr(name, '.'); + if (!s) + s = name + name_len; + + n = s - name; /* Chunk length */ + *p++ = n; /* Copy length */ + memcpy(p, name, n); /* Copy chunk */ + p += n; + + if (*s == '.') + n++; + + name += n; + name_len -= n; + } while (*s != '\0'); + + *p++ = 0; /* Mark end of host name */ + *p++ = 0; /* Some servers require double null */ + *p++ = (unsigned char) qtype; /* Query Type */ + + *p++ = 0; + *p++ = 1; /* Class: inet, 0x0001 */ + + n = p - pkt; /* Total packet length */ + debug("Packet size %d\n", n); + + DnsOurPort = random_port(); + + NetSendUDPPacket(NetServerEther, NetOurDNSIP, DNS_SERVICE_PORT, + DnsOurPort, n); + debug("DNS packet sent\n"); +} + +static void +DnsTimeout(void) +{ + puts("Timeout\n"); + NetState = NETLOOP_FAIL; +} + +static void +DnsHandler(uchar *pkt, unsigned dest, unsigned src, unsigned len) +{ + struct header *header; + const unsigned char *p, *e, *s; + u16 type, i; + int found, stop, dlen; + char IPStr[22]; + IPaddr_t IPAddress; + short tmp; + + + debug("%s\n", __func__); + if (dest != DnsOurPort) + return; + + for (i = 0; i < len; i += 4) + debug("0x%p - 0x%.2x 0x%.2x 0x%.2x 0x%.2x\n", + pkt+i, pkt[i], pkt[i+1], pkt[i+2], pkt[i+3]); + + /* We sent 1 query. We want to see more that 1 answer. */ + header = (struct header *) pkt; + if (ntohs(header->nqueries) != 1) + return; + + /* Received 0 answers */ + if (header->nanswers == 0) { + puts("DNS server returned no answers\n"); + NetState = NETLOOP_SUCCESS; + return; + } + + /* Skip host name */ + s = &header->data[0]; + e = pkt + len; + for (p = s; p < e && *p != '\0'; p++) + continue; + + /* We sent query class 1, query type 1 */ + tmp = p[1] | (p[2] << 8); + if (&p[5] > e || ntohs(tmp) != DNS_A_RECORD) { + puts("DNS response was not A record\n"); + NetState = NETLOOP_SUCCESS; + return; + } + + /* Go to the first answer section */ + p += 5; + + /* Loop through the answers, we want A type answer */ + for (found = stop = 0; !stop && &p[12] < e; ) { + + /* Skip possible name in CNAME answer */ + if (*p != 0xc0) { + while (*p && &p[12] < e) + p++; + p--; + } + debug("Name (Offset in header): %d\n", p[1]); + + tmp = p[2] | (p[3] << 8); + type = ntohs(tmp); + debug("type = %d\n", type); + if (type == DNS_CNAME_RECORD) { + /* CNAME answer. shift to the next section */ + debug("Found canonical name\n"); + tmp = p[10] | (p[11] << 8); + dlen = ntohs(tmp); + debug("dlen = %d\n", dlen); + p += 12 + dlen; + } else if (type == DNS_A_RECORD) { + debug("Found A-record\n"); + found = stop = 1; + } else { + debug("Unknown type\n"); + stop = 1; + } + } + + if (found && &p[12] < e) { + + tmp = p[10] | (p[11] << 8); + dlen = ntohs(tmp); + p += 12; + memcpy(&IPAddress, p, 4); + + if (p + dlen <= e) { + ip_to_string(IPAddress, IPStr); + printf("%s\n", IPStr); + if (NetDNSenvvar) + setenv(NetDNSenvvar, IPStr); + } else + puts("server responded with invalid IP number\n"); + } + + NetState = NETLOOP_SUCCESS; +} + +void +DnsStart(void) +{ + debug("%s\n", __func__); + + NetSetTimeout(DNS_TIMEOUT, DnsTimeout); + NetSetHandler(DnsHandler); + + DnsSend(); +} + diff --git a/net/dns.h b/net/dns.h new file mode 100644 index 0000000000..277c093ed3 --- /dev/null +++ b/net/dns.h @@ -0,0 +1,39 @@ +/* + * (C) Masami Komiya 2005 + * Copyright 2009, Robin Getz + * + * 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, or (at + * your option) any later version. + */ + +#ifndef __DNS_H__ +#define __DNS_H__ + +#define DNS_SERVICE_PORT 53 +#define DNS_TIMEOUT 10000UL + +/* http://en.wikipedia.org/wiki/List_of_DNS_record_types */ +enum dns_query_type { + DNS_A_RECORD = 0x01, + DNS_CNAME_RECORD = 0x05, + DNS_MX_RECORD = 0x0f, +}; + +/* + * DNS network packet + */ +struct header { + uint16_t tid; /* Transaction ID */ + uint16_t flags; /* Flags */ + uint16_t nqueries; /* Questions */ + uint16_t nanswers; /* Answers */ + uint16_t nauth; /* Authority PRs */ + uint16_t nother; /* Other PRs */ + unsigned char data[1]; /* Data, variable length */ +}; + +extern void DnsStart(void); /* Begin DNS */ + +#endif diff --git a/net/net.c b/net/net.c index e215fd8d9a..4bbe5313c3 100644 --- a/net/net.c +++ b/net/net.c @@ -92,6 +92,9 @@ #if defined(CONFIG_CDP_VERSION) #include #endif +#if defined(CONFIG_CMD_DNS) +#include "dns.h" +#endif #if defined(CONFIG_CMD_NET) @@ -291,6 +294,9 @@ NetInitLoop(proto_t protocol) NetServerIP = getenv_IPaddr ("serverip"); NetOurNativeVLAN = getenv_VLAN("nvlan"); NetOurVLAN = getenv_VLAN("vlan"); +#if defined(CONFIG_CMD_DNS) + NetOurDNSIP = getenv_IPaddr("dnsip"); +#endif env_changed_id = env_id; } @@ -425,6 +431,11 @@ restart: case SNTP: SntpStart(); break; +#endif +#if defined(CONFIG_CMD_DNS) + case DNS: + DnsStart(); + break; #endif default: break; @@ -1518,6 +1529,14 @@ static int net_check_prereq (proto_t protocol) } goto common; #endif +#if defined(CONFIG_CMD_DNS) + case DNS: + if (NetOurDNSIP == 0) { + puts("*** ERROR: DNS server address not given\n"); + return 1; + } + goto common; +#endif #if defined(CONFIG_CMD_NFS) case NFS: #endif @@ -1681,6 +1700,16 @@ void copy_filename (char *dst, char *src, int size) #endif +#if defined(CONFIG_CMD_NFS) || defined(CONFIG_CMD_SNTP) || defined(CONFIG_CMD_DNS) +/* + * make port a little random, but use something trivial to compute + */ +unsigned int random_port(void) +{ + return 1024 + (get_timer(0) % 0x8000);; +} +#endif + void ip_to_string (IPaddr_t x, char *s) { x = ntohl (x); -- cgit From 3bd0a877b74b9c005ae7cb892480ccedfa308c20 Mon Sep 17 00:00:00 2001 From: Ben Warren Date: Fri, 17 Jul 2009 00:50:15 -0700 Subject: Add warning about upcoming removal of old Ethernet API Signed-off-by: Ben Warren --- net/eth.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'net') diff --git a/net/eth.c b/net/eth.c index 3d93966918..8e1d6921ca 100644 --- a/net/eth.c +++ b/net/eth.c @@ -500,6 +500,8 @@ char *eth_get_name (void) } #elif defined(CONFIG_CMD_NET) && !defined(CONFIG_NET_MULTI) +#warning Ethernet driver is deprecated. Please update to use CONFIG_NET_MULTI + extern int at91rm9200_miiphy_initialize(bd_t *bis); extern int mcf52x2_miiphy_initialize(bd_t *bis); extern int ns7520_miiphy_initialize(bd_t *bis); -- cgit From 09133f8580f0106429ba3600f1855bd3577ae58b Mon Sep 17 00:00:00 2001 From: Michael Zaidman Date: Tue, 14 Jul 2009 23:37:12 +0300 Subject: DHCP regression on 2009-06 Fixed the DHCP/BOOTP/RARP regression introduced in u-boot-2009.06 by initializing our IP addr to 0 in order to accept any IP addr assigned to us by the DHCP/BOOTP/RARP server. Ack-by: Robin Getz Signed-off-by: Michael Zaidman Signed-off-by: Ben Warren --- net/net.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'net') diff --git a/net/net.c b/net/net.c index 4bbe5313c3..7ce947db30 100644 --- a/net/net.c +++ b/net/net.c @@ -394,17 +394,20 @@ restart: #if defined(CONFIG_CMD_DHCP) case DHCP: BootpTry = 0; + NetOurIP = 0; DhcpRequest(); /* Basically same as BOOTP */ break; #endif case BOOTP: BootpTry = 0; + NetOurIP = 0; BootpRequest (); break; case RARP: RarpTry = 0; + NetOurIP = 0; RarpRequest (); break; #if defined(CONFIG_CMD_PING) -- cgit From 97cfe86163505ea18e7ff7b71e78df5bb03dad57 Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Tue, 21 Jul 2009 12:15:28 -0400 Subject: Save server's MAC address in environment Linux's netconsole works much better when you can pass it the MAC address of the server. (otherwise it just uses broadcast, which everyone else on my network complains about :) This sets the env var "serveraddr" (to match ethaddr), so that you can pass it to linux with whatever bootargs you want to.... addnetconsole=set bootargs $(bootargs) netconsole=@$(ipaddr)/eth0,@$(serverip)/$(serveraddr) Signed-of-by: Robin Getz Signed-off-by: Ben Warren --- net/net.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'net') diff --git a/net/net.c b/net/net.c index 7ce947db30..641c37cb8f 100644 --- a/net/net.c +++ b/net/net.c @@ -1287,6 +1287,15 @@ NetReceive(volatile uchar * inpkt, int len) /* are we waiting for a reply */ if (!NetArpWaitPacketIP || !NetArpWaitPacketMAC) break; + +#ifdef CONFIG_KEEP_SERVERADDR + if (NetServerIP == NetArpWaitPacketIP) { + char buf[20]; + sprintf(buf, "%pM", arp->ar_data); + setenv("serveraddr", buf); + } +#endif + #ifdef ET_DEBUG printf("Got ARP REPLY, set server/gtwy eth addr (%pM)\n", arp->ar_data); -- cgit