From patchwork Tue Nov 16 18:04:31 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: tristan.lelong@blunderer.org X-Patchwork-Id: 71534 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 1EE15B718A for ; Wed, 17 Nov 2010 20:28:04 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 7211928552; Wed, 17 Nov 2010 10:21:42 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 4W+TWllfE9Er; Wed, 17 Nov 2010 10:21:42 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 5C44D2852C; Wed, 17 Nov 2010 10:21:34 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 0CD29284D1 for ; Wed, 17 Nov 2010 10:21:31 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id YME7rHpakd1u for ; Wed, 17 Nov 2010 10:21:29 +0100 (CET) X-policyd-weight: IN_SBL_XBL_SPAMHAUS=4.35 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from wunderer (LPuteaux-156-15-47-90.w82-127.abo.wanadoo.fr [82.127.74.90]) by theia.denx.de (Postfix) with ESMTPS id 6C30A284F4 for ; Wed, 17 Nov 2010 10:21:29 +0100 (CET) Received: from tristan by wunderer with local (Exim 4.72) (envelope-from ) id 1PIPtR-0004GB-J1; Tue, 16 Nov 2010 19:04:33 +0100 From: tristan.lelong@blunderer.org To: u-boot@lists.denx.de Date: Tue, 16 Nov 2010 19:04:31 +0100 Message-Id: <732b4e4395e5c02bb01c1fd7b7f8ce085a208950.1289929762.git.blunderer@blunderer.org> X-Mailer: git-send-email 1.7.2.3 In-Reply-To: References: In-Reply-To: References: Subject: [U-Boot] [PATCH 1/3] Add support for Net Boot Controller (NBC) packet X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.9 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de From: Tristan Lelong This adds the core NBC feature: * Integration into u-boot * NBC packet processing * NetConsole reconfigure Signed-off-by: Tristan Lelong --- common/main.c | 5 ++ include/net.h | 6 ++- net/Makefile | 2 + net/nbc.c | 143 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ net/nbc.h | 39 +++++++++++++++ net/net.c | 17 +++++++ 6 files changed, 211 insertions(+), 1 deletions(-) create mode 100644 net/nbc.c create mode 100644 net/nbc.h diff --git a/common/main.c b/common/main.c index d97ccd7..e23b204 100644 --- a/common/main.c +++ b/common/main.c @@ -259,6 +259,11 @@ static __inline__ int abortboot(int bootdelay) putc('\n'); +#ifdef CONFIG_CMD_NBC + if (!abort) + abort = NBCWait (); +#endif + #ifdef CONFIG_SILENT_CONSOLE if (abort) gd->flags &= ~GD_FLG_SILENT; diff --git a/include/net.h b/include/net.h index a29dafc..25e177f 100644 --- a/include/net.h +++ b/include/net.h @@ -359,7 +359,7 @@ extern int NetState; /* Network loop state */ extern int NetRestartWrap; /* Tried all network devices */ #endif -typedef enum { BOOTP, RARP, ARP, TFTP, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP } proto_t; +typedef enum { BOOTP, RARP, ARP, TFTP, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP, NBC } proto_t; /* from net/net.c */ extern char BootFile[128]; /* Boot File name */ @@ -384,6 +384,10 @@ extern IPaddr_t NetNtpServerIP; /* the ip address to NTP */ extern int NetTimeOffset; /* offset time from UTC */ #endif +#if defined(CONFIG_CMD_NBC) +extern IPaddr_t NetSrcIP; /* Packet Src IP addr (0 = unknown) */ +#endif + /* Initialize the network adapter */ extern int NetLoop(proto_t); diff --git a/net/Makefile b/net/Makefile index 216d1ec..735e8c6 100644 --- a/net/Makefile +++ b/net/Makefile @@ -35,6 +35,8 @@ COBJS-$(CONFIG_CMD_NFS) += nfs.o COBJS-$(CONFIG_CMD_RARP) += rarp.o COBJS-$(CONFIG_CMD_SNTP) += sntp.o COBJS-$(CONFIG_CMD_NET) += tftp.o +COBJS-$(CONFIG_CMD_NBC) += nbc.o + COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) diff --git a/net/nbc.c b/net/nbc.c new file mode 100644 index 0000000..e1788e4 --- /dev/null +++ b/net/nbc.c @@ -0,0 +1,143 @@ +/* + * NBC support driver + * Network Boot Controller + * + * Copyright (c) 2010 Tristan Lelong + * + */ + +#include +#include +#include + +#include "nbc.h" + +#ifndef CONFIG_NETCONSOLE +#error CONFIG_NETCONSOLE should be defined so that nbc can redirect stdin/stdout/stderr +#endif + +static char NBC_Mode_On = 0; + +static void NBCHandler (uchar * pkt, unsigned dest, unsigned src, unsigned len) +{ + int cnt = 0; + char src_ip[16] = ""; + char *nbcsource = NULL; + char ip[16] = ""; + char mac[18] = ""; + char hostname[255] = ""; + + struct _nbc_packet *nbc_pkt = (struct _nbc_packet *)pkt; + nbcsource = getenv ("nbcsource"); + + /* check packet validity */ + if (nbc_pkt->id != 0xD3) + goto fail; + if (strncmp (nbc_pkt->head, "NBC", 3)) + goto fail; + if (nbc_pkt->size != len) + goto fail; + + sprintf (src_ip, "%lu.%lu.%lu.%lu", ((NetSrcIP >> 0) & 0xFF), + ((NetSrcIP >> 8) & 0xFF), ((NetSrcIP >> 16) & 0xFF), + ((NetSrcIP >> 24) & 0xFF)); + + if (nbcsource && strcmp (nbcsource, src_ip)) + goto fail; + + for (cnt = 0; cnt < (nbc_pkt->size - NBC_HEADER_SIZE);) { + struct _nbc_chunk *chk = + (struct _nbc_chunk *)(pkt + NBC_HEADER_SIZE + cnt); + if (strncmp (chk->name, "IP\0\0", 4) == 0) { + if (chk->size != NBC_CHK_IP_SIZE) + goto fail; + unsigned char *pkt_ip = (unsigned char *)chk->data; + sprintf (ip, "%d.%d.%d.%d", pkt_ip[0], pkt_ip[1], + pkt_ip[2], pkt_ip[3]); + } else if (strncmp (chk->name, "MAC\0", 4) == 0) { + if (chk->size != NBC_CHK_MAC_SIZE) + goto fail; + unsigned char *pkt_mac = (unsigned char *)chk->data; + sprintf (mac, "%02X:%02X:%02X:%02X:%02X:%02X", + pkt_mac[0], pkt_mac[1], pkt_mac[2], pkt_mac[3], + pkt_mac[4], pkt_mac[5]); + } else if (strncmp (chk->name, "HOST", 4) == 0) { + unsigned char *pkt_hostname = + (unsigned char *)chk->data; + if (chk->size >= NBC_CHK_HOSTNAME_SIZE) + goto fail; + strncpy (hostname, pkt_hostname, chk->size); + hostname[chk->size] = '\0'; + } + cnt += NBC_CHK_HEADER_SIZE + chk->size; + } + + /* test if we are targeted by the magic packet */ + if (strlen (mac)) { + char *our_mac = getenv ("ethaddr"); + debug ("mac filter: cmp(%s,%s)\n", our_mac, mac); + if (strcmp (mac, our_mac)) + goto fail; + } + + if (strlen (hostname)) { + char *our_hostname = getenv ("hostname"); + debug ("hostname filter: cmp(%s,%s)\n", our_hostname, hostname); + if (strcmp (hostname, our_hostname)) + goto fail; + } + + /* set server ip */ + setenv ("serverip", src_ip); + + /* set gateway ip */ + setenv ("gatewayip", src_ip); + + /* set addrip */ + setenv ("ipaddr", ip); + + printf ("activated nc from [%s] to [%s]\n", ip, src_ip); + + /* activate the netconsole */ + setenv ("ncip", src_ip); + setenv ("stdin", "nc"); + setenv ("stdout", "nc"); + setenv ("stderr", "nc"); + console_assign (stdin, "nc"); + console_assign (stdout, "nc"); + console_assign (stderr, "nc"); + + NBC_Mode_On = 1; + + NetState = NETLOOP_SUCCESS; + + return; +fail: + debug ("not a valid nbc magic packet\n"); +} + +static void NBCTimeout (void) +{ + NetState = NETLOOP_FAIL; + debug ("NBC Timeout!\n"); +} + +int NBCWait (void) +{ + char *nbcinhibit = getenv ("nbcinhibit"); + if (nbcinhibit) + return 0; + + NetLoop (NBC); + + if (NBC_Mode_On) { + return 1; + } + return 0; +} + +void NBCStart (void) +{ + NetSetTimeout (1000, NBCTimeout); + NetSetHandler (NBCHandler); +} diff --git a/net/nbc.h b/net/nbc.h new file mode 100644 index 0000000..40371a5 --- /dev/null +++ b/net/nbc.h @@ -0,0 +1,39 @@ +/* + * (C) Tristan Lelong 2010 + * Copyright 2010, Tristan Lelong + * + * 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 __NBC_H__ +#define __NBC_H__ + +#define NBC_SERVICE_PORT 4446 +#define NBC_TIMEOUT 2000 + +#define NBC_CHK_HEADER_SIZE 5 +#define NBC_HEADER_SIZE 5 +#define NBC_CHK_IP_SIZE 4 +#define NBC_CHK_MAC_SIZE 6 +#define NBC_CHK_HOSTNAME_SIZE 255 + +struct _nbc_packet { + unsigned char id; + unsigned char head[3]; + unsigned char size; + unsigned char data[255]; +}; + +struct _nbc_chunk { + unsigned char name[4]; + unsigned char size; + unsigned char data[255]; +}; + +extern void NBCStart (void); +extern int NBCWait (void); + +#endif diff --git a/net/net.c b/net/net.c index d5a5429..b722048 100644 --- a/net/net.c +++ b/net/net.c @@ -97,6 +97,9 @@ #if defined(CONFIG_CMD_DNS) #include "dns.h" #endif +#if defined(CONFIG_CMD_NBC) +#include "nbc.h" +#endif DECLARE_GLOBAL_DATA_PTR; @@ -180,6 +183,10 @@ IPaddr_t NetNtpServerIP; /* NTP server IP address */ int NetTimeOffset=0; /* offset time from UTC */ #endif +#if defined(CONFIG_CMD_NBC) +IPaddr_t NetSrcIP; /* Src IP addr (0 = unknown) */ +#endif + #ifdef CONFIG_NETCONSOLE void NcStart(void); int nc_input_packet(uchar *pkt, unsigned dest, unsigned src, unsigned len); @@ -384,6 +391,11 @@ restart: NetDevExists = 1; #endif switch (protocol) { +#if defined(CONFIG_CMD_NBC) + case NBC: + NBCStart (); + break; +#endif case TFTP: /* always use ARP to get server ethernet address */ TftpStart(); @@ -1631,6 +1643,7 @@ NetReceive(volatile uchar * inpkt, int len) ushort *sumptr; ushort sumlen; + xsum = ip->ip_p; xsum += (ntohs(ip->udp_len)); xsum += (ntohl(ip->ip_src) >> 16) & 0x0000ffff; @@ -1673,6 +1686,10 @@ NetReceive(volatile uchar * inpkt, int len) ntohs(ip->udp_src), ntohs(ip->udp_len) - 8); #endif + +#ifdef CONFIG_CMD_NBC + NetSrcIP = NetReadIP ((void *)&ip->ip_src); +#endif /* * IP header OK. Pass the packet to the current handler. */