Welcome to MicroMonitor!
+
This is the top-level of the MicroMonitor CVS.
There are three main directories:
for any target supported by MicroMonitor.
To get started, refer to umon_main/README.
+
+
+######################
+#
+# SVN User Notes:
+#
+As of release 1.17 the uMon tree is under SVN (instead of CVS).
+To diff a file ignoring whitespace...
+ svn diff --diff-cmd diff -x -uw filename
+
+To diff a file relative to the HEAD, run...
+ svn diff -r HEAD filename
+
+To create a new uMon release...
+ 1 Retrieve a "fresh" tree from SVN so that we don't miss a file
+ that may be in the local directory, but not committed.
+ 2 Run 'make rebuild 2>&1 | tee make.out' under umon_ports and
+ verify that the build was clean.
+ 3 Update common/version.h
+ 4 When committing the verion.h file, note the SVN release and
+ make a note of it at the bottom of this file. Then commit this
+ file.
+ 5 Copy the umon tree to umon-X.YY, then remove all .svn and
+ .subversion directories. Run 'make clobber' under umon_ports
+ and umon_main/host.
+ 6 Create new tarball.
+If these instructions are followed, then in theory, this file will be
+the last committed file in the release; hence the Revision of this file
+(keyword below) can be used as the release point of reference...
+
+Revision: $Revision: 1928 $
+
+######################
+#
+# SVN Revision-to-uMon release...
+#
+uMon1.17: Committed revision 1924 (Mar 13, 2009).
*/
ab = mon_getenv("APPRAMBASE");
if (ab) {
- char *addr = (char *)strtol(ab,0,0);
+ char *addr = (char *)strtoul(ab,0,0);
mon_printf("Dumping memory at 0x%lx...\n",addr);
mon_printmem(addr,128,1);
ifeq ($(ARCH),ARM)
TOOL_PREFIX := arm-elf
-CFLAGS := -fno-builtin -mcpu=arm9tdmi \
+CFLAGS := -fno-builtin -mcpu=arm1136j-s -fno-omit-frame-pointer \
-c -Wall -O -g -I.
CRT0 := crt0_arm.o
CPU := -D CPU_IS_ARM=1
static int (*_flashwrite)(char *,char *,int);
static int (*_flasherase)(int);
static int (*_flashinfo)(int,int *,char **);
+static int (*_flashoverride)(void *,int,int);
static int (*_sendenet)(char *,int);
static int (*_recvenet)(char *,int);
static int (*_printpkt)(char *,int,int);
rc += _moncom(GETMONFUNC_PORTCMD,&_portcmd,0,0);
rc += _moncom(GETMONFUNC_TIMEOFDAY,&_timeofday,0,0);
rc += _moncom(GETMONFUNC_TIMER,&_montimer,0,0);
+ rc += _moncom(GETMONFUNC_FLASHOVRRD,&_flashoverride,0,0);
}
return(rc);
}
GENERIC_MONUNLOCK();
}
+int
+mon_flashoverride(void *flashinfo,int get,int bank)
+{
+ int ret;
+
+ TFS_MONLOCK();
+ ret = _flashoverride(flashinfo,get,bank);
+ TFS_MONUNLOCK();
+ return(ret);
+}
+
int
mon_flashwrite(char *dest,char *src,int bytecnt)
{
int len);
extern int mon_sendenetpkt(char *pkt, int len);
extern int mon_recvenetpkt(char *pkt, int len);
+extern int mon_flashoverride(void *flashinfo, int get, int bank);
extern int mon_flasherase(int snum);
extern int mon_flashwrite(char *dest,char *src, int bytecnt);
extern int mon_flashinfo(int snum,int *size, char **base);
#define GETMONFUNC_PORTCMD 70
#define GETMONFUNC_TIMEOFDAY 71
#define GETMONFUNC_TIMER 72
+#define GETMONFUNC_FLASHOVRRD 73
#define CACHEFTYPE_DFLUSH 200
#define CACHEFTYPE_IINVALIDATE 201
* Lines 11-16 : show the output of strace giving the user the exact
* call-stack that caused the exception.
- * Note that the strace facility (INCLUDE_STRACE in config.h) in the
+ * Note1:
+ * The strace facility (INCLUDE_STRACE in config.h) in the
* monitor requires that the symbol table facility (INCLUDE_SYMTBL in
* the config.h file) also be enabled.
+ * Note2:
+ * Depending on the version of GCC you're using, you may have to specify
+ * -fno-omit-frame-pointer on the command line; otherwise the stack trace
+ * function will not work properly.
*/
#include "monlib.h"
--- /dev/null
+#ifndef _TIMER_H_
+#define _TIMER_H_
+
+struct elapsed_tmr {
+ unsigned long start; // Start value of elapsed timeout.
+ unsigned long tmrval; // Running timer value
+ // (used by elapsed timeout)
+ unsigned long currenttmrval; // Current timer value
+ // (not used by elapsed timeout)
+ unsigned long tpm; // Ticks per millisecond
+
+ unsigned long elapsed_low;
+ unsigned long elapsed_high;
+
+ unsigned long timeout_low;
+ unsigned long timeout_high;
+
+ unsigned long tmrflags;
+};
+
+/* Timer flags:
+ */
+#define HWTMR_ENABLED (1 << 0)
+#define TIMEOUT_OCCURRED (1 << 1)
+
+/* Timer macros:
+ */
+#define HWRTMR_IS_ENABLED(tmr) \
+ ((tmr)->tmrflags & HWTMR_ENABLED)
+
+#define ELAPSED_TIMEOUT(tmr) \
+ ((tmr)->tmrflags & TIMEOUT_OCCURRED)
+
+/* uMon API timer commands:
+ */
+#define TIMER_START 1
+#define TIMER_ELAPSED 2
+#define TIMER_QUERY 3
+
+extern unsigned long target_timer(void);
+extern void startElapsedTimer(struct elapsed_tmr *tmr,long timeout);
+extern int msecElapsed(struct elapsed_tmr *tmr);
+extern unsigned long msecRemaining(struct elapsed_tmr *tmr);
+extern int monTimer(int cmd, void *arg);
+
+#endif
#define LWIP_PLATFORM_DIAG(x) do {mon_printf x;} while(0)
#define LWIP_PLATFORM_ASSERT(x) do {mon_printf("Assertion \"%s\" failed at line %d in %s\n", \
- x, __LINE__, __FILE__); fflush(NULL); abort();} while(0)
+ x, __LINE__, __FILE__);} while(0)
#endif /* __ARCH_CC_H__ */
#include "cfg.h"
+#if USE_APPSTACK
.extern AppStack
.extern Cstart
.global start
jump_to_c:
bl Cstart
+#endif
.global _clock_time
.text
-
+#if USE_APPSTACK
start:
sp.h = _AppStack+(APPSTACKSIZE-32)
sp.l = _AppStack+(APPSTACKSIZE-32)
jump _Cstart
+#endif
_clock_time:
R0 = CYCLES;
.text
+#if USE_APPSTACK
start:
move.l #AppStack+(APPSTACKSIZE-32),%sp
jsr Cstart
+#endif
/* Set stack pointer to end of AppStack and jump to Cstart:
*/
+#if USE_APPSTACK
start:
addi r1, r0, AppStack
addi r1, r1, (APPSTACKSIZE-16)
jump_to_c:
brai Cstart
+#endif
.text
.set noreorder
+#if USE_APPSTACK
start:
la sp, AppStack
addiu sp, APPSTACKSIZE
la k0,Cstart
j k0
nop
+#endif
.extern Cstart
.globl start
+#if USE_APPSTACK
start:
lis sp, (AppStack+(APPSTACKSIZE-4))@h
addi sp, sp, (AppStack+(APPSTACKSIZE-4))@l
addi r7, r0, -8
- and sp, sp, r7 /* 8-byte aligned (EABI spec) */
+ and sp, sp, r7
ba Cstart
nop
+#endif
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">\r
<html>\r
<body bgcolor="#60e040" text="black"></body>\r
+</html>\r
<title>${PLATFORM}</title>\r
</head>\r
<frameset rows="50%,50%">\r
-<frame src="/top.html" name="topFrame">\r
-<frame src="/cmdresptop.html" name="botFrame">\r
+<frame src="top.html" name="topFrame">\r
+<frame src="bot.html" name="botFrame">\r
</frameset>\r
<noframes>\r
Apparently your browser is not frames-ready!\r
-<A HREF="/top.html">Click here for non-frame version</A>\r
+<A HREF="top.html">Click here for non-frame version</A>\r
</noframes>\r
</html>\r
-for file in *
+for file in *.html *.jpg
do
-ttftp $1 put $file /$file
+ttftp $1 put $file web/$file
done
</head>\r
<body bgcolor="#60e040" text="black">\r
<center>\r
-<a href="http://www.microcross.com/html/micromonitor.html">\r
+<a href="http://www.umonfw.com">\r
<img border="3" alt="Go to uMon homepage" src="umonheader.jpg"></a>\r
<br>\r
<font face="Arial">\r
-for file in *
+for file in *.html *.jpg
do
-ttftp $1 put $file /$file
+ttftp $1 put $file http/$file
done
/** This is a helper struct which holds the starting
* offset and the ending offset of this fragment to
* easily chain the fragments.
+ * It has to be packed since it has to fit inside the IP header.
*/
+#ifdef PACK_STRUCT_USE_INCLUDES
+# include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
struct ip_reass_helper {
- struct pbuf *next_pbuf;
- u16_t start;
- u16_t end;
-};
+ PACK_STRUCT_FIELD(struct pbuf *next_pbuf);
+ PACK_STRUCT_FIELD(u16_t start);
+ PACK_STRUCT_FIELD(u16_t end);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+# include "arch/epstruct.h"
+#endif
#define IP_ADDRESSES_AND_ID_MATCH(iphdrA, iphdrB) \
(ip_addr_cmp(&(iphdrA)->src, &(iphdrB)->src) && \
u32_t
tcp_next_iss(void)
{
+#if 0
static u32_t iss = 6510;
-
+
iss += tcp_ticks; /* XXX */
return iss;
+#else
+ extern u32_t uMonRand(void);
+ return(uMonRand());
+#endif
}
#if TCP_CALCULATE_EFF_SEND_MSS
-#define LWIP_NETCONN 0
-#define LWIP_SOCKET 0
-#define LWIP_SNMP 0
-//#define LWIP_STATS 0
-#define NO_SYS 1
-//#define MEM_SIZE 0x80000
-#define TCP_MSS (1024)
-#define TCP_SND_BUF (TCP_MSS * 32) /* can't exceed 64K */
+#define LWIP_NETCONN 0
+#define LWIP_SOCKET 0
+#define LWIP_SNMP 0
+#define LWIP_STATS 0
+#define NO_SYS 1
+#define TCP_MSS (1460)
+#define TCP_SND_BUF (TCP_MSS * 42) /* can't exceed 64K */
+#define TCP_SND_QUEUELEN (8 * (TCP_SND_BUF/TCP_MSS))
+#define TCP_WND (24*1024)
#define MEM_ALIGNMENT 4
#include "lwip/netif.h"
#include "lwip/stats.h"
#include "httpd.h"
+#include "telnet.h"
#include "monsrvr.h"
#include "umonlwip.h"
+#if USE_APPSTACK
unsigned long AppStack[APPSTACKSIZE/4];
+#endif
+
+void
+usage(char *arg0)
+{
+ mon_printf("Usage: %s {command} [command-specific-args]\n",arg0);
+ mon_printf(" Commands:\n");
+ mon_printf(" * srvrs\n");
+ mon_printf(" run HTTP & MONCMD servers\n");
+ mon_printf(" * telnetc {srvrip} [port]\n");
+ mon_printf(" run TELNET client to specified server ip\n");
+ mon_printf(" * httpget {srvrip} {filename} {dest_addr}\n");
+ mon_printf(" run HTTP-GET requet to specified server ip and file;\n");
+ mon_printf(" place data at 'dest_addr'\n");
+ mon_printf(" load HTTPGET shellvar with size of transfer\n");
+ mon_printf("\n\n");
+}
int
main(int argc,char *argv[])
{
- lwip_umon_startup();
-
- httpd_init();
- monsrvr_init();
-
- mon_printf("System running (hit any char to terminate)...\n");
-
- while(!mon_gotachar())
- {
- lwip_poll();
+ short port;
+ char *srvr, *fname, *addr;
- /* PUT OTHER APPLICATION CODE HERE */
+ if (argc < 2) {
+ usage(argv[0]);
+ return(-1);
}
+ if (strcmp(argv[1],"httpget") == 0) {
+ if (argc != 5) {
+ usage(argv[0]);
+ return(-1);
+ }
+
+ srvr = argv[2];
+ fname = argv[3];
+ addr = (char *)strtoul(argv[4],0,0);
+
+ mon_printf("Http get: %s %s 0x%lx\n",srvr,fname,addr);
+ lwip_umon_startup();
+ httpget_init(srvr,fname,addr);
+
+ while(1) {
+ if (mon_gotachar()) {
+ mon_printf("HttpGet terminted by user\n");
+ httpget_close();
+ break;
+ }
+ if (!httpget_isactive()) {
+ mon_printf("HttpGet completed\n");
+ break;
+ }
+ lwip_poll();
+ }
+ lwip_umon_shutdown();
+ }
+ else if (strcmp(argv[1],"telnetc") == 0) {
+ if (argc == 3) {
+ port = 23;
+ srvr = argv[2];
+ }
+ else if (argc == 4) {
+ srvr = argv[2];
+ port = atoi(argv[3]);
+ }
+ else {
+ usage(argv[0]);
+ return(-1);
+ }
+
+ lwip_umon_startup();
+ telnetc_init(srvr,port);
+ while(1) {
+ if (mon_gotachar())
+ telnetc_putchar((char)mon_getchar());
+ if (!telnetc_isactive()) {
+ mon_printf("Telnetc completed\n");
+ break;
+ }
+ lwip_poll();
+ }
+ lwip_umon_shutdown();
+ }
+ else if (strcmp(argv[1],"srvrs") == 0) {
+ mon_printf("Running HTTP & MONCMD servers (hitakey to terminate)...\n");
+ lwip_umon_startup();
+ httpd_init();
+ monsrvr_init();
+ while(!mon_gotachar())
+ lwip_poll();
+ lwip_umon_shutdown();
+ }
+ else {
+ usage(argv[0]);
+ }
+
return(0);
}
}
int
+#if USE_APPSTACK
Cstart(void)
+#else
+start(void)
+#endif
{
char **argv;
int argc;
mon_getargv(&argc,&argv);
/* Call main, then exit to monitor.
+ * Wrap the call with the Lwip startup/shutdown calls...
*/
+#if USE_APPSTACK
+ mon_appexit(main(argc,argv));
+#else
main(argc,argv);
+#endif
- mon_appexit(0);
-
- /* Won't get here. */
- return(0);
-}
-
-/* CstartAlt():
- * Demonstrates the use of the "call -a" command in uMon.
- * For example, if for some reason you wanted to do this...
- * Load the application then load the symtbl file using
- * "make TARGET_IP=1.2.3.4 sym", then issue these commands:
- *
- * tfs -v ld app
- * call -a %CstartAlt one two three
- *
- * The "call -a" command in uMon correctly sets up the function
- * call parameters so that the following function would see 4
- * arguments (including arg0), with argv[1] thru argv[3] being
- * pointers to each of the number strings (i.e. "one", "two", "three")
- * and argv[0] being the ascii-coded-hex address of the function
- * CstartAlt.
- */
-int
-CstartAlt(int argc, char *argv[])
-{
- monConnect((int(*)())(*(unsigned long *)MONCOMPTR),(void *)0,(void *)0);
- main(argc,argv);
- mon_appexit(0);
+ /* We won't get here if USE_APPSTACK is set.
+ */
return(0);
}
return((clock_time_t)tbl);
}
#elif CPU_IS_MIPS
+#if CLOCK_MS
#error: Gotta write clock_time for MIPS.
+#endif
#elif CPU_IS_ARM
+#if CLOCK_MS
#error: Gotta write clock_time for ARM.
+#endif
#elif CPU_IS_BFIN
+#if CLOCK_MS
/* clock_time is in assembler */
+#endif
#elif CPU_IS_MICROBLAZE
+#if CLOCK_MS
#error: Gotta write clock_time for MICROBLAZE.
+#endif
#elif CPU_IS_68K
+#if CLOCK_MS
+#error: Gotta write clock_time for 68K.
+#endif
#else
#error: Invalid CPU specification.
#endif
# BLACKFIN) that returns the content of a hardware timer.
#
+PORT =
ARCH =
MONCOMPTR =
APPRAMBASE =
TARGET_IP =
CLOCK_MS =
+ENDIANNESS =
+
+USEAPPSTACK = 1
+
+# For convenience, some of the ports are preconfigured if you add
+# "PORT=NNNN" to the command line...
+#
+ifeq ($(PORT),CSB472)
+ARCH = PPC
+MONCOMPTR = 0xfffffff0
+APPRAMBASE = 0x20000
+TARGET_IP = 135.222.138.20
+CLOCK_MS = 200000
+ENDIANNESS = -D BYTE_ORDER=BIG_ENDIAN
+endif
+
+ifeq ($(PORT),BF537)
+ARCH = BLACKFIN
+MONCOMPTR = 0x03f00004
+APPRAMBASE = 0x100000
+TARGET_IP = 135.222.138.21
+CLOCK_MS = 0
+ENDIANNESS = -D BYTE_ORDER=LITTLE_ENDIAN
+endif
+
+ifeq ($(PORT),CSB740)
+ARCH = ARM
+MONCOMPTR = 0x08000038
+APPRAMBASE = 0x80400000
+TARGET_IP = 135.222.138.21
+CLOCK_MS = 0
+ENDIANNESS = -D BYTE_ORDER=LITTLE_ENDIAN
+endif
+
+ifeq ($(PORT),CSB726)
+ARCH = ARM
+MONCOMPTR = 0x20
+APPRAMBASE = 0xa008d000
+TARGET_IP = 135.222.138.21
+CLOCK_MS = 0
+ENDIANNESS = -D BYTE_ORDER=LITTLE_ENDIAN
+endif
+
+
-# For example...
-#ARCH = BLACKFIN
-#MONCOMPTR = 0x03f00004
-#APPRAMBASE = 0x100000
-#TARGET_IP = 135.222.138.21
-#CLOCK_MS = 0
#########################################################################
#
# This uMon/LWIP application requires only that the
# CLOCK_MS value be set based on the target-specific
# function 'clock_time()'. It should be set to the
-# number of ticks that represents 1millisecond.
+# number of ticks that represents 1 millisecond.
#
-APPNAME = app
+APPNAME = lwipapp
NM = $(TOOL_PREFIX)-nm
AR = $(TOOL_PREFIX)-ar
LD = $(TOOL_PREFIX)-ld
ifeq ($(ARCH),MIPS)
TOOL_PREFIX := mips-elf
CFLAGS := -fno-builtin -G 0 -march=r4600 -mips3 -mno-abicalls \
- -fno-pic -c -g -O2 -Wall -EB $(INCPATHS)
+ -fno-pic -c -g -O2 -Wall -EB $(INCPATHS) $(ENDIANNESS)
CRT0 := crt0_mips.o
CPU := -D CPU_IS_MIPS=1
endif
ifeq ($(ARCH),PPC)
TOOL_PREFIX := ppc-elf
CFLAGS := -fno-builtin -mno-sdata -msoft-float \
- -c -Wall -O -g $(INCPATHS)
+ -c -Wall -O -g $(INCPATHS) $(ENDIANNESS)
CRT0 := crt0_ppc.o
CPU := -D CPU_IS_PPC=1
LIBGCC = `$(CC) --print-file-name=nof/libgcc.a`
ifeq ($(ARCH),ARM)
TOOL_PREFIX := arm-elf
CFLAGS := -fno-builtin -mcpu=arm9tdmi \
- -c -Wall -O -g $(INCPATHS)
+ -c -Wall -O2 -g $(INCPATHS) $(ENDIANNESS)
CRT0 := crt0_arm.o
CPU := -D CPU_IS_ARM=1
endif
ifeq ($(ARCH),BLACKFIN)
TOOL_PREFIX := bfin-elf
-CFLAGS := -fno-builtin -mcsync-anomaly -c -O -Wall -g $(INCPATHS)
+CFLAGS := -fno-builtin -mcsync-anomaly -c -O -Wall -g \
+ $(INCPATHS) $(ENDIANNESS)
CRT0 := crt0_bfin.o
CPU := -D CPU_IS_BFIN=1
endif
ifeq ($(ARCH),MICROBLAZE)
TOOL_PREFIX := C:/EDK/gnu/microblaze/nt/bin/mb
LIBPATH := -L C:/xilinx/els_stuff/projects/avnet_spartan3_devkit/microblaze_0/lib
-CFLAGS := -fno-builtin -mno-xl-soft-mul -c -Wall -O -g $(INCPATHS)
+CFLAGS := -fno-builtin -mno-xl-soft-mul -c -Wall -O -g \
+ $(INCPATHS) $(ENDIANNESS)
CRT0 := crt0_mb.o
CPU := -D CPU_IS_MICROBLAZE=1
endif
ifeq ($(ARCH),COLDFIRE)
TOOL_PREFIX := m68k-elf
-CFLAGS := -Wall -fno-builtin -msoft-float -m5200 -g -c $(INCPATHS)
+CFLAGS := -Wall -fno-builtin -msoft-float -m5200 -g -c \
+ $(INCPATHS) $(ENDIANNESS)
CRT0 := crt0_cf.o
CPU := -D CPU_IS_68K=1
#LIBGCC = `$(CC) -m5200 --print-libgcc-file-name`
#
#########################################################################
#
-NET_OBJS = fs.o httpd.o monsrvr.o umonlwip.o
+NET_OBJS = fs.o httpd.o httpget.o monsrvr.o telnetc.o umonlwip.o
API_OBJS = api_lib.o api_msg.o err.o netbuf.o netdb.o netifapi.o
# Objects:
#
crt0_68k.o: crt0_68k.S
- $(CC) $(CFLAGS) -o $@ crt0_68k.S
+ $(CC) $(CFLAGS) -D USE_APPSTACK=$(APPSTACK) -o $@ crt0_68k.S
crt0_arm.o: crt0_arm.S
- $(CC) $(CFLAGS) -o $@ crt0_arm.S
+ $(CC) $(CFLAGS) -D USE_APPSTACK=$(USEAPPSTACK) -o $@ crt0_arm.S
crt0_bfin.o: crt0_bfin.S
- $(CC) $(CFLAGS) -o $@ crt0_bfin.S
+ $(CC) $(CFLAGS) -D USE_APPSTACK=$(USEAPPSTACK) -o $@ crt0_bfin.S
crt0_mips.o: crt0_mips.S
- $(CC) $(CFLAGS) -o $@ crt0_mips.S
+ $(CC) $(CFLAGS) -D USE_APPSTACK=$(USEAPPSTACK) -o $@ crt0_mips.S
crt0_mb.o: crt0_mb.S
- $(CC) $(CFLAGS) -o $@ crt0_mb.S
+ $(CC) $(CFLAGS) -D USE_APPSTACK=$(USEAPPSTACK) -o $@ crt0_mb.S
crt0_ppc.o: crt0_ppc.S
- $(CC) $(CFLAGS) -o $@ crt0_ppc.S
+ $(CC) $(CFLAGS) -D USE_APPSTACK=$(USEAPPSTACK) -o $@ crt0_ppc.S
crt0_sh2.o: crt0_sh2.S
- $(CC) $(CFLAGS) -o $@ crt0_sh2.S
+ $(CC) $(CFLAGS) -D USE_APPSTACK=$(USEAPPSTACK) -o $@ crt0_sh2.S
main.o: main.c
- $(CC) $(CFLAGS) $(CPU) -D MONCOMPTR=$(MONCOMPTR) -o $@ main.c
+ $(CC) $(CFLAGS) $(CPU) -o $@ \
+ -D USE_APPSTACK=$(USEAPPSTACK) -D MONCOMPTR=$(MONCOMPTR) \
+ main.c
+
+misc.o: misc.c
+ $(CC) $(CFLAGS) $(CPU) -o $@ misc.c
monlib.o: monlib.c
$(CC) $(CFLAGS) -o $@ monlib.c
httpd.o: ./net/httpd.c
$(CC) $(CFLAGS) ./net/httpd.c
+httpget.o: ./net/httpget.c
+ $(CC) $(CFLAGS) ./net/httpget.c
+
+telnetc.o: ./net/telnetc.c
+ $(CC) $(CFLAGS) ./net/telnetc.c
+
umonlwip.o: ./net/umonlwip.c
$(CC) $(CFLAGS) -D CLOCK_MS=$(CLOCK_MS) ./net/umonlwip.c
@if ! test -f $(APPNAME); then echo Must build $(APPNAME) first; exit 1; fi
moncmd -q -w2 $(TARGET_IP) reset
ttftp $(TARGET_IP) put $(APPNAME) $(APPNAME),E
- moncmd -w0 $(TARGET_IP) @app
#####
#
*/
#include "lwip/def.h"
#include "fs.h"
+#include "httpd.h"
#include "monlib.h"
#include "tfs.h"
fs_open(char *name, struct fs_file *file)
{
TFILE *tfp;
+ char *prefix, namebuf[TFSNAMESIZE+1];
/* Look for the specified file in TFS. If found, then
* return it; else return the nofile string above.
*/
+ prefix = mon_getenv(HTTP_PREFIX_VARNAME);
+ if (prefix) {
+ if ((strlen(name) + strlen(prefix) + 1) < sizeof(namebuf)) {
+ sprintf(namebuf,"%s%s",prefix,name);
+ name = namebuf;
+ }
+ }
tfp = mon_tfsstat(name);
if (!tfp) {
file->data = (char *)nofile;
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
- *
+ * Modified significantly to run as a uMon application:
+ * Ed Sutter <esutter@alcatel-lucent.com>
*/
#include "lwip/debug.h"
-
#include "lwip/stats.h"
-
#include "httpd.h"
-
#include "lwip/tcp.h"
-
#include "fs.h"
-
#include "monlib.h"
struct http_state {
*/
if (http_respptr == 0) {
TFILE *tfp;
- if ((tfp = mon_tfsstat("/cmdresptop.html")) != 0) {
+ char *name, *prefix;
+ static char namebuf[TFSNAMESIZE+1];
+
+ name = "cmdresptop.html";
+ prefix = mon_getenv(HTTP_PREFIX_VARNAME);
+ if (prefix) {
+ if ((strlen(name) + strlen(prefix) + 1) < sizeof(namebuf)) {
+ sprintf(namebuf,"%s%s",prefix,name);
+ name = namebuf;
+ }
+ }
+ if ((tfp = mon_tfsstat(name)) != 0) {
http_respsiz = TFS_SIZE(tfp) + 1024;
}
else
http_respptr = 0;
mon_com(CHARFUNC_PUTCHAR,http_putchar,0,0);
mon_docommand(val,0);
+ if (http_respptr == 0) // Just in case the message is empty
+ http_putchar('\n'); // generate one character of response.
mon_com(CHARFUNC_PUTCHAR,0,0,0);
}
return(0);
}
}
- if (*(char *)(data + 4) == '/' &&
- *(char *)(data + 5) == 0) {
- fs_open("/index.html", &file);
- } else if (!fs_open((char *)data + 4, &file)) {
- fs_open("/404.html", &file);
+ if (*(char *)(data + 4) == '/' && *(char *)(data + 5) == 0) {
+ fs_open("index.html", &file);
+ } else if (!fs_open((char *)data + 5, &file)) { // skip leading slash
+ fs_open("404.html", &file);
}
hs->file = file.data;
LWIP_UNUSED_ARG(arg);
LWIP_UNUSED_ARG(err);
- tcp_setprio(pcb, TCP_PRIO_MIN);
+// tcp_setprio(pcb, TCP_PRIO_MIN);
/* Allocate memory for the structure that holds the state of the
connection. */
#ifndef __HTTPD_H__
#define __HTTPD_H__
-void httpd_init(void);
+extern void httpd_init(void);
+extern void httpget_close(void);
+extern int httpget_isactive(void);
+extern int httpget_init(char *srvr, char *file, char *addr);
+
+#define HTTP_PREFIX_VARNAME "HTTP_PREFIX"
#endif /* __HTTPD_H__ */
--- /dev/null
+#include "lwip/debug.h"
+#include "lwip/stats.h"
+#include "httpd.h"
+#include "lwip/tcp.h"
+#include "monlib.h"
+
+static int rcvlen, get_state;
+static struct tcp_pcb *get_pcb;
+static char *get_dest, get_line[128];
+static int debug;
+
+/* This code is based on a few different lwip snippets I found...
+ * 1. contrib/ports/unix/proj/minimal/echo.c
+ * 2. http://www.mail-archive.com/lwip-users@nongnu.org/msg04160.html
+ * 3. http://www.mail-archive.com/lwip-users@nongnu.org/msg04689.html
+ */
+
+int
+httpget_isactive(void)
+{
+ return(get_state);
+}
+
+void
+httpget_close(void)
+{
+ tcp_arg(get_pcb, NULL);
+ tcp_sent(get_pcb, NULL);
+ tcp_recv(get_pcb, NULL);
+ tcp_err(get_pcb, NULL);
+ tcp_poll(get_pcb, NULL, 0);
+ tcp_close(get_pcb);
+ get_state = 0;
+}
+
+err_t
+httpget_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
+{
+ struct pbuf *q;
+ extern void ticktock(void);
+
+ if (err != ERR_OK) {
+ mon_printf("\nHTTPGET: recv failed (err=%d)\n",err);
+ httpget_close();
+ return(err);
+ }
+ if (p == NULL) {
+ char buf[16];
+
+ /* If we're here, the remote host closed the connection.
+ */
+ httpget_close();
+ mon_printf("\nServer closed connection, total bytes rcvd: %d\n",
+ rcvlen);
+ mon_sprintf(buf,"%d",rcvlen);
+ mon_setenv("HTTPGET",buf);
+ return(ERR_OK);
+ }
+ for(q = p; q != NULL; q = q->next) {
+ memcpy((char *)get_dest,(char *)q->payload,(int)q->len);
+ rcvlen += q->len;
+ get_dest += q->len;
+ }
+ tcp_recved(tpcb,p->tot_len);
+ pbuf_free(p);
+ if (debug)
+ mon_printf("HTTPGET: recv tot: %d\n",rcvlen);
+ else
+ mon_printf("%08d\b\b\b\b\b\b\b\b",rcvlen);
+ return(ERR_OK);
+}
+
+
+err_t
+httpget_sent(void *arg, struct tcp_pcb *tpcb, u16_t len)
+{
+ if (debug)
+ mon_printf("HTTPGET: msg sent (size=%d)\n",len);
+ return(ERR_OK);
+}
+
+err_t
+httpget_connected(void *arg, struct tcp_pcb *tpcb, err_t err)
+{
+ if (err != ERR_OK) {
+ mon_printf("HTTPGET: connect failed (err=%d)\n",err);
+ httpget_close();
+ }
+ else {
+ int size, maxsize;
+
+ if (debug)
+ mon_printf("HTTPGET: connected\n");
+
+ maxsize = tcp_sndbuf(tpcb);
+ size = strlen(get_line);
+ if (debug)
+ mon_printf("MSG(%d): %s \n",size,get_line);
+ if (size > maxsize) {
+ mon_printf("HTTPGET: msg too big\n");
+ return(ERR_BUF);
+ }
+ else {
+ err = tcp_write(tpcb, get_line, size, 0);
+ if (err != ERR_OK)
+ mon_printf("HTTPGET: tcp_write failed\n");
+ else
+ tcp_output(tpcb);
+ }
+ }
+ return(err);
+}
+
+void
+httpget_err(void *arg, err_t err)
+{
+ mon_printf("\nHTTPGET: error %d\n",err);
+ httpget_close();
+}
+
+/* Regarding a proxy...
+ * When a proxy is involved, all outgoing client requests must pass
+ * through that proxy. So, the connection request must be made to
+ * the proxy, and the path of the file to be retrieved must be
+ * preceded by the full network path of the server containing
+ * the file. For example...
+ *
+ * GET http://www.yada.com/fullpath.html HTTP/1.0
+ *
+ */
+int
+httpget_init(char *srvrip, char *file, char *addr)
+{
+ struct ip_addr ipaddr;
+
+ mon_setenv("HTTPGET",0);
+
+ if ((strlen(file) + 32) >= sizeof(get_line)) {
+ mon_printf("get_line[] overflow\n");
+ return(-1);
+ }
+
+ rcvlen = 0;
+ get_state = 1;
+ get_dest = addr;
+ mon_sprintf(get_line,"GET %s HTTP/1.0\n\n",file);
+ inet_aton((const char *)srvrip,(struct in_addr *)&ipaddr);
+
+ if ((get_pcb = tcp_new()) == 0) {
+ mon_printf("tcp_new() returned NULL\n");
+ return(-1);
+ }
+
+ if (mon_getenv("HTTPGET_DEBUG"))
+ debug = 1;
+ else
+ debug = 0;
+
+ tcp_arg(get_pcb,NULL);
+ tcp_err(get_pcb, httpget_err);
+ tcp_sent(get_pcb, httpget_sent);
+ tcp_recv(get_pcb, httpget_recv);
+ tcp_connect(get_pcb, &ipaddr, 80, httpget_connected);
+ return(0);
+}
+
--- /dev/null
+#ifndef __TELNETC_H__
+#define __TELNETC_H__
+
+extern void telnetc_close(void);
+extern int telnetc_isactive(void);
+extern int telnetc_putchar(char);
+extern int telnetc_init(char *srvr, short port);
+
+/* Telnet command encoding...
+ * These codes only have meaning if preceded by the TELNET_IAC.
+ * See Comer TCP/IP pg 413.
+ */
+#define TELNET_IAC ((char)255) /* interpret as command */
+#define TELNET_DONT ((char)254)
+#define TELNET_DO ((char)253)
+#define TELNET_WONT ((char)252)
+#define TELNET_WILL ((char)251)
+#define TELNET_SB ((char)250) /* start of option sub-negotiation */
+#define TELNET_GA ((char)249) /* the "go ahead" signal */
+#define TELNET_EL ((char)248) /* the "erase line" signal */
+#define TELNET_EC ((char)247) /* the "erase character" signal */
+#define TELNET_AYT ((char)246) /* the "are you there?" signal */
+#define TELNET_AO ((char)245) /* the "abort output" signal */
+#define TELNET_IP ((char)244) /* the "interrupt process" signal */
+#define TELNET_BRK ((char)243) /* the "break" signal */
+#define TELNET_DMARK ((char)242) /* data-stream portion of a synch */
+#define TELNET_NOP ((char)241) /* no operation */
+#define TELNET_SE ((char)240) /* end of option sub-negotiation */
+#define TELNET_EOR ((char)239) /* end of record */
+
+/* Description of DO/DONT/WILL/WONT (taken from Comer)...
+ * In TELNET terminology, the request is WILL X, meaning "will you agree to
+ * let me use option X?"; and the response is either DO X or DONT X,
+ * meaning "I do (or don't) agree to let you use option X".
+ * The commands can be used in the opposite direction also...
+ * The DO X command requests that the receiving party begin using option X,
+ * and WILL X or WONT X is the response.
+ */
+
+
+/* Telnet options. For more details refer to:
+ * "Internet Official Protocol Standards" (STD 1).
+ 0 Binary Transmission [RFC856]
+ 1 Echo [RFC857]
+ 2 Reconnection [NIC50005]
+ 3 Suppress Go Ahead [RFC858]
+ 4 Approx Message Size Negotiation [ETHERNET]
+ 5 Status [RFC859]
+ 6 Timing Mark [RFC860]
+ 7 Remote Controlled Trans and Echo [RFC726]
+ 8 Output Line Width [NIC50005]
+ 9 Output Page Size [NIC50005]
+ 10 Output Carriage-Return Disposition [RFC652]
+ 11 Output Horizontal Tab Stops [RFC653]
+ 12 Output Horizontal Tab Disposition [RFC654]
+ 13 Output Formfeed Disposition [RFC655]
+ 14 Output Vertical Tabstops [RFC656]
+ 15 Output Vertical Tab Disposition [RFC657]
+ 16 Output Linefeed Disposition [RFC658]
+ 17 Extended ASCII [RFC698]
+ 18 Logout [RFC727]
+ 19 Byte Macro [RFC735]
+ 20 Data Entry Terminal [RFC1043,RFC732]
+ 21 SUPDUP [RFC736,RFC734]
+ 22 SUPDUP Output [RFC749]
+ 23 Send Location [RFC779]
+ 24 Terminal Type [RFC1091]
+ 25 End of Record [RFC885]
+ 26 TACACS User Identification [RFC927]
+ 27 Output Marking [RFC933]
+ 28 Terminal Location Number [RFC946]
+ 29 Telnet 3270 Regime [RFC1041]
+ 30 X.3 PAD [RFC1053]
+ 31 Negotiate About Window Size [RFC1073]
+ 32 Terminal Speed [RFC1079]
+ 33 Remote Flow Control [RFC1372]
+ 34 Linemode [RFC1184]
+ 35 X Display Location [RFC1096]
+ 36 Environment Option [RFC1408]
+ 37 Authentication Option [RFC2941]
+ 38 Encryption Option [RFC2946]
+ 39 New Environment Option [RFC1572]
+ 40 TN3270E [RFC1647]
+ 41 XAUTH [Earhart]
+ 42 CHARSET [RFC2066]
+ 43 Telnet Remote Serial Port (RSP) [Barnes]
+ 44 Com Port Control Option [RFC2217]
+ 45 Telnet Suppress Local Echo [Atmar]
+ 46 Telnet Start TLS [Boe]
+ 47 KERMIT [RFC2840]
+ 48 SEND-URL [Croft]
+ 49 FORWARD_X [Altman]
+ 50-137 Unassigned [IANA]
+ 138 TELOPT PRAGMA LOGON [McGregory]
+ 139 TELOPT SSPI LOGON [McGregory]
+ 140 TELOPT PRAGMA HEARTBEAT [McGregory]
+ 255 Extended-Options-List [RFC861]
+ */
+
+#define TELNET_OPTION_ECHO ((char)1)
+#define TELNET_OPTION_SUPPGOAHEAD ((char)03)
+#define TELNET_OPTION_TERMTYPE ((char)24)
+#define TELNET_OPTION_LINEMODE ((char)34)
+
+#endif /* __TELNETC_H__ */
--- /dev/null
+#include "lwip/debug.h"
+#include "lwip/stats.h"
+#include "telnet.h"
+#include "lwip/tcp.h"
+#include "monlib.h"
+
+typedef unsigned char uchar;
+
+static struct tcp_pcb *tnetc_pcb;
+static int tnetc_state, tnetc_debug, tnetc_connected;
+static int tnetc_le;
+
+//#define DBGPRINT(a) mon_printf a
+#define DBGPRINT(a)
+
+int
+telnetc_isactive(void)
+{
+ return(tnetc_state);
+}
+
+void
+telnetc_close(void)
+{
+ tcp_arg(tnetc_pcb, NULL);
+ tcp_sent(tnetc_pcb, NULL);
+ tcp_recv(tnetc_pcb, NULL);
+ tcp_err(tnetc_pcb, NULL);
+ tcp_poll(tnetc_pcb, NULL, 0);
+ tcp_close(tnetc_pcb);
+ tnetc_state = 0;
+}
+
+err_t
+telnetc_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
+{
+ struct pbuf *q;
+
+ if (err != ERR_OK) {
+ mon_printf("\nTELNETC: recv failed (err=%d)\n",err);
+ telnetc_close();
+ return(err);
+ }
+ if (p == NULL) {
+ /* If we're here, the remote host closed the connection.
+ */
+ telnetc_close();
+ mon_printf("\nTELNETC: Server closed connection\n");
+ return(ERR_OK);
+ }
+ for(q = p; q != NULL; q = q->next) {
+ int i;
+ char *cp = (char *)q->payload;
+
+ for(i=0;i<q->len;i++) {
+ if (*cp == TELNET_IAC) {
+ int tstate;
+ char resp[32], c;
+
+ tstate = TELNET_IAC;
+ while(tstate != TELNET_BRK) {
+ if (i >= q->len)
+ mon_printf("TELNETC: OOPS\n");
+ cp++; i++;
+ c = *cp;
+ DBGPRINT(("recv %d (%02x)",(uchar)c,(uchar)c));
+
+ if (tstate == TELNET_IAC) {
+ switch(c) {
+ case TELNET_IAC:
+ tstate = TELNET_BRK;
+ break;
+ case TELNET_DO:
+ cp++; i++;
+ c = *cp;
+ resp[0] = TELNET_IAC;
+ if (c == TELNET_OPTION_TERMTYPE) {
+ DBGPRINT(("TELNET_DO TERMTYPE"));
+ resp[1] = TELNET_WILL;
+ }
+ else if (c == TELNET_OPTION_ECHO) {
+ DBGPRINT(("TELNET_DO ECHO"));
+ resp[1] = TELNET_WILL;
+ tnetc_le= 1;
+ }
+ else {
+ DBGPRINT(("TELNET_DO %d",(uchar)c));
+ resp[1] = TELNET_WONT;
+ }
+ resp[2] = c;
+ tcp_write(tnetc_pcb,resp,3,TCP_WRITE_FLAG_COPY);
+ tstate = TELNET_BRK;
+ break;
+ case TELNET_DONT:
+ cp++; i++;
+ c = *cp;
+ DBGPRINT(("TELNET_DONT %d",(uchar)c));
+ tstate = TELNET_BRK;
+ break;
+ case TELNET_WILL:
+ cp++; i++;
+ c = *cp;
+ resp[0] = TELNET_IAC;
+ if (c == TELNET_OPTION_ECHO) {
+ DBGPRINT(("TELNET_WILL ECHO"));
+ resp[1] = TELNET_DO;
+ tnetc_le= 0;
+ }
+ else if (c == TELNET_OPTION_TERMTYPE) {
+ DBGPRINT(("TELNET_WILL TERMTYPE"));
+ resp[1] = TELNET_DO;
+ }
+ else if (c == TELNET_OPTION_SUPPGOAHEAD) {
+ DBGPRINT(("TELNET_WILL SUPPGOAHEAD"));
+ resp[1] = TELNET_DO;
+ }
+ else {
+ DBGPRINT(("TELNET_WILL %d",c));
+ resp[1] = TELNET_DONT;
+ }
+ resp[2] = c;
+ tcp_write(tnetc_pcb,resp,3,TCP_WRITE_FLAG_COPY);
+ tstate = TELNET_BRK;
+ break;
+ case TELNET_WONT:
+ cp++; i++;
+ c = *cp;
+ DBGPRINT(("TELNET_WONT %d",(uchar)c));
+ tstate = TELNET_BRK;
+ break;
+ case TELNET_SB:
+ tstate = TELNET_SB;
+ DBGPRINT(("TELNET_SB"));
+ break;
+ default:
+ tstate = TELNET_BRK;
+ break;
+ }
+ }
+ else if (tstate == TELNET_SB) {
+ if (c == TELNET_IAC) {
+ cp++; i++;
+ c = *cp;
+ if (c == TELNET_SE) {
+ tstate = TELNET_BRK;
+ DBGPRINT(("TELNET_SE"));
+ }
+ else {
+ DBGPRINT(("TELNET_SB %d",(uchar)c));
+ }
+ }
+ else if (c == TELNET_OPTION_TERMTYPE) {
+ cp++; i++;
+ c = *cp;
+ DBGPRINT(("TELNET_SB TERMTYPE"));
+ resp[0] = TELNET_IAC;
+ resp[1] = TELNET_SB;
+ resp[2] = TELNET_OPTION_TERMTYPE;
+ resp[3] = 'v';
+ resp[4] = 't';
+ resp[5] = '1';
+ resp[6] = '0';
+ resp[7] = '0';
+ resp[8] = TELNET_IAC;
+ resp[9] = TELNET_SE;
+ DBGPRINT(("TERMTYPE = VT100"));
+ tcp_write(tnetc_pcb,resp,10,TCP_WRITE_FLAG_COPY);
+ }
+ }
+ }
+ DBGPRINT(("done\n"));
+ }
+ else
+ mon_putchar(*cp);
+ cp++;
+ }
+ }
+ tcp_recved(tpcb,p->tot_len);
+ pbuf_free(p);
+ return(ERR_OK);
+}
+
+
+err_t
+telnetc_sent(void *arg, struct tcp_pcb *tpcb, u16_t len)
+{
+ if (tnetc_debug)
+ mon_printf("TELNETC: msg sent (size=%d)\n",len);
+ return(ERR_OK);
+}
+
+int
+telnetc_putchar(char c)
+{
+ err_t err;
+
+ if (!tnetc_connected)
+ return((int)ERR_CONN);
+
+ if (c == 0x1d) { /* ctrl-] */
+ telnetc_close();
+ tnetc_connected = 1;
+ return(-1);
+ }
+
+ err = tcp_write(tnetc_pcb, &c, 1, TCP_WRITE_FLAG_COPY);
+ if (err != ERR_OK) {
+ mon_printf("TELNETC: tcp_write failed\n");
+ telnetc_close();
+ }
+ else
+ tcp_output(tnetc_pcb);
+
+ return((int)err);
+}
+
+err_t
+telnetc_connected(void *arg, struct tcp_pcb *tpcb, err_t err)
+{
+ if (err != ERR_OK) {
+ mon_printf("TELNETC: connect failed (err=%d)\n",err);
+ telnetc_close();
+ }
+ else {
+ if (tnetc_debug)
+ mon_printf("TELNETC: connected\n");
+ tnetc_connected = 1;
+ }
+ return(err);
+}
+
+void
+telnetc_err(void *arg, err_t err)
+{
+ mon_printf("\nTELNETC: error %d\n",err);
+ telnetc_close();
+}
+
+int
+telnetc_init(char *srvrip, short port)
+{
+ struct ip_addr ipaddr;
+
+ tnetc_state = 1;
+ tnetc_le = 0;
+ tnetc_connected = 0;
+ inet_aton((const char *)srvrip,(struct in_addr *)&ipaddr);
+
+ if ((tnetc_pcb = tcp_new()) == 0) {
+ mon_printf("TELNETC: tcp_new() returned NULL\n");
+ return(-1);
+ }
+
+ if (mon_getenv("TELNETC_DEBUG"))
+ tnetc_debug = 1;
+ else
+ tnetc_debug = 0;
+
+ tcp_arg(tnetc_pcb,NULL);
+ tcp_err(tnetc_pcb, telnetc_err);
+ tcp_sent(tnetc_pcb, telnetc_sent);
+ tcp_recv(tnetc_pcb, telnetc_recv);
+ tcp_connect(tnetc_pcb, &ipaddr, port, telnetc_connected);
+ return(0);
+}
+
return(0);
}
+int
+uMonRand(void)
+{
+#if CLOCK_MS
+ return((int)clock_time());
+#else
+ struct elapsed_tmr tmr;
+ mon_timer(TIMER_QUERY,&tmr);
+ return((int)tmr.currenttmrval);
+#endif
+}
+
+/* lwip_umon_shutdown():
+ * When this app started using uMon's underlying ethernet interface,
+ * it had to start off by disabling uMon's underlying mechanism to poll
+ * the ethernet interface (so that this application can do it).
+ *
+ * This function must be called prior to exiting the the application (back
+ * to the monitor) so that ethernet polling intrinsically done by the monitor
+ * is turned back on.
+ */
+void
+lwip_umon_shutdown(void)
+{
+ mon_sendenetpkt(0,-1);
+}
+
/* lwip_poll():
* The recommended "OS-less" code, based on text in the LWIP wiki page...
* http://lwip.scribblewiki.com/LwIP_with_or_without_an_operating_system
struct pbuf *p, *q;
static unsigned long last_time = 0;
#if !CLOCK_MS
- struct elapsed_tmr tmr;
+ struct elapsed_tmr tmr, tmr1;
#endif
ipkt = (char *)ipacket;
count = 0;
}
tcp_tmr();
+#if CLOCK_MS
last_time = clock_time();
+#else
+ mon_timer(TIMER_QUERY,&tmr1);
+ last_time = tmr1.currenttmrval;
+#endif
}
}
-extern int lwip_umon_startup(void);
extern void lwip_poll(void);
+extern int lwip_umon_startup(void);
+extern void lwip_umon_shutdown(void);
be built with GNU tools or Visual C++ (VCC).
These tools have been successfully built on CYGWIN (using both GNU and VCC),
-plus SOLARIS (SunOS 5.7) and LINUX (RedHat-9 & others).
+plus SOLARIS (SunOS 5.7) LINUX (RedHat-9 & others), and MacOS (using BASH
+and GCC).
To do a complete build and cleanup using native GNU gcc run:
"make OSTYPE=linux rebuild"
or
"make OSTYPE=solaris rebuild"
+or
+ "make OSTYPE=macos rebuild"
depending on your host system. To do a complete build and cleanup
for Cygwin using Visual C++ first make sure your environment is set
oscheck:
@if ! test -d $(BIN) ; then mkdir $(BIN); fi
ifeq ($(OSTYPE),)
- @printf "Set OSTYPE variable to cygwin, linux or solaris\n"
+ @printf "Set OSTYPE variable to cygwin, linux, macos or solaris\n"
@printf "(depending on your environment).\n"
exit 1
endif
--- /dev/null
+
+ fprintf(stderr," Built with: ");
+#ifdef BUILD_WITH_VCC
+ fprintf(stderr,"VCC\n");
+#else
+ fprintf(stderr,"GCC\n");
+#endif
AR = ar ruv $(TOOL)$(L_EXT)
CONLIBS =
THREADLIBS = -lpthread
-CFLAGS = -fno-builtin -c -I $(COMSRC) -I .
+CFLAGS = -fno-builtin -Wall -c -I $(COMSRC) -I .
O_EXT = .o
ifneq ($(findstring Win,$(OS)),)
endif
ifneq ($(findstring Win,$(OS)),)
+SOCKLIBS =
+else
+ifeq ($(OSTYPE),linux)
+SOCKLIBS = -lnsl
+else
+ifeq ($(OSTYPE),macos)
SOCKLIBS =
else
-ifeq ($(findstring linux,$(OSTYPE)),)
-SOCKLIBS = -lsocket -lnsl
+ifeq ($(OSTYPE),cygwin)
+SOCKLIBS =
else
SOCKLIBS = -lnsl
endif
endif
+endif
+endif
int
ofcrc32(char *filename, unsigned long *crc, int verbose)
{
+ int ifd;
char *buf;
- int ifd, opt;
unsigned long tmpcrc;
struct stat mstat;
}
close(ifd);
- tmpcrc = crc32(buf,mstat.st_size);
+ tmpcrc = crc32((unsigned char *)buf,mstat.st_size);
if (verbose)
printf("CRC of file %s: 0x%x\n",filename,tmpcrc);
int
fcrc32(char *filename, unsigned long *crc, int verbose)
{
+ int ifd, size;
char buf[0x10000];
unsigned long tmpcrc;
struct stat mstat;
- int ifd, opt, size;
/* Open input file: */
ifd = open(filename,O_RDONLY | O_BINARY);
perror("read1");
return(-1);
}
- tmpcrc = partial_crc32(tmpcrc,buf,sizeof(buf));
+ tmpcrc = partial_crc32(tmpcrc,(unsigned char *)buf,sizeof(buf));
size -= sizeof(buf);
}
else {
perror("read1");
return(-1);
}
- tmpcrc = partial_crc32(tmpcrc,buf,size);
+ tmpcrc = partial_crc32(tmpcrc,(unsigned char *)buf,size);
size = 0;
}
}
void
showVersion(void)
{
- printf(" Built: %s @ %s\n",__DATE__,__TIME__);
+ printf(" Built: %s @ %s with ",__DATE__,__TIME__);
+#ifdef BUILD_WITH_VCC
+ fprintf(stderr,"VCC\n");
+#else
+ fprintf(stderr,"GCC\n");
+#endif
exit(1);
}
#define STATIC static
#endif
-STATIC init_des(), init_perm(), permute();
+STATIC int init_des(), init_perm(), permute();
int des_setkey(), des_cipher();
#ifdef DEBUG
#define PERM3264(d,d0,d1,cpp,p) \
{ C_block tblk; permute(cpp,&tblk,p,4); LOAD (d,d0,d1,tblk); }
-STATIC
+STATIC int
permute(cp, out, p, chars_in)
unsigned char *cp;
C_block *out;
static unsigned char S[8][64] = { /* 48->32 bit substitution tables */
/* S[1] */
+ {
14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
- 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,
+ 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13
+ },
/* S[2] */
+ {
15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
- 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,
+ 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9
+ },
/* S[3] */
+ {
10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
- 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,
+ 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12
+ },
/* S[4] */
+ {
7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
- 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,
+ 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14
+ },
/* S[5] */
+ {
2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
- 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,
+ 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3
+ },
/* S[6] */
+ {
12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
- 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,
+ 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13
+ },
/* S[7] */
+ {
4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
- 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,
+ 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12
+ },
/* S[8] */
+ {
13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
- 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11,
+ 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
+ }
};
static unsigned char P32Tr[] = { /* 32-bit permutation function */
* followed by an encryption produced by the "key" and "setting".
*/
char *
-crypt(key, setting)
+orig_crypt(key, setting)
register const char *key;
register const char *setting;
{
/*
* Set up the key schedule from the key.
*/
+int
des_setkey(key)
register const char *key;
{
* NOTE: the performance of this routine is critically dependent on your
* compiler and machine architecture.
*/
+int
des_cipher(in, out, salt, num_iter)
const char *in;
char *out;
* Initialize various tables. This need only be done once. It could even be
* done at compile time, if the compiler were capable of that sort of thing.
*/
-STATIC
+STATIC int
init_des()
{
register int i, j;
*
* "perm" must be all-zeroes on entry to this routine.
*/
-STATIC
+STATIC int
init_perm(perm, p, chars_in, chars_out)
C_block perm[64/CHUNKBITS][1<<CHUNKBITS];
unsigned char p[64];
/*
* "setkey" routine (for backwards compatibility)
*/
+int
setkey(key)
register const char *key;
{
/*
* "encrypt" routine (for backwards compatibility)
*/
+int
encrypt(block, flag)
register char *block;
int flag;
#ifdef UNIQUE_DATATBL
#include "unique_data_file.c"
#else
-unsigned char *umon_crypt_datatbl = "5gfHHJ^RVGJF#@FNM_NJE#W)(UJH(&T*%Ec54evX6t-098yun-9um9u8yv785rc5e43w3xw543wx43wx54ex7%R*^&RC*&TV_*(U_)(UN_)U*B76rc764ex643wx34ec6t098yn=9ui=n09im[pim[pimo(UB*)&GVB*&^FC$EX^$&*Y_(U*N(_*UN)9h8b087gv87f6cuytfghfvu654dx#SX53q2ax74f0p8u-[0in=-i-9ub098v087gv987g";
+unsigned char *umon_crypt_datatbl = (unsigned char *)"5gfHHJ^RVGJF#@FNM_NJE#W)(UJH(&T*%Ec54evX6t-098yun-9um9u8yv785rc5e43w3xw543wx43wx54ex7%R*^&RC*&TV_*(U_)(UN_)U*B76rc764ex643wx34ec6t098yn=9ui=n09im[pim[pimo(UB*)&GVB*&^FC$EX^$&*Y_(U*N(_*UN)9h8b087gv87f6cuytfghfvu654dx#SX53q2ax74f0p8u-[0in=-i-9ub098v087gv987g";
#endif
#define UNIX_CRYPT 'u'
char *rslt, *string, *cryptfile;
unsigned char salt[3], buffer[64], etherbin[16];
struct stat mstat;
- extern char *crypt();
+ extern char *orig_crypt(char *,char *);
cryptfile = (char *)0;
crypttype = CHEAP_CRYPT;
switch(crypttype) {
case UNIX_CRYPT:
- rslt = crypt(etherbin,salt);
+ rslt = orig_crypt((char *)etherbin,(char *)salt);
break;
case CHEAP_CRYPT:
- rslt = cheap_crypt(etherbin,salt,buffer);
+ rslt = cheap_crypt((char *)etherbin,(char *)salt,(char *)buffer);
break;
default:
fprintf(stderr,"Invalid encryption type\n");
#define WIN32_LEAN_AND_MEAN
#include <winsock.h>
#else
+#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
fprintf(stderr,"ERROR: %s\n",error);
for(i=0;errmsg[i];i++)
fprintf(stderr,"%s\n",errmsg[i]);
+#include "builtwith.c"
exit(EXIT_ERROR);
}
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <stdint.h>
#include <netdb.h>
#include <sys/socket.h>
+#include <sys/select.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#endif
int
do_moncmd(char *hostname, char *command_to_monitor, short portnum)
{
- int i, lasterr;
- int msglen;
+ int i;
+ unsigned msglen;
uint32_t inaddr;
struct hostent *hp, host_info;
char rcvmsg[4096*4], cmdline[128];
#include "ttftp.h"
#include "moncmd.h"
+#include "version.h"
+#include "crc32.h"
char *errmsg[] = {
fprintf(stderr,"ERROR: %s\n",error);
for(i=0;errmsg[i];i++)
fprintf(stderr,"%s\n",errmsg[i]);
+#include "builtwith.c"
exit(EXIT_ERROR);
}
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
" Where...",
" OPCODE is RRQ, WRQ, DAT, ACK or ERR;",
" OPCODE_NUM specifies the 'nth' repetition of that opcode",
- " TESTTYPE is SLEEP, QUIT, CORRUPT",
- " ARG1 is SLEEPTIME, NA, or CORRUPTBYTE",
+ " TESTTYPE is SLEEP, QUIT, BBNO or CORRUPT",
+ " ARG1 is SLEEPTIME, NA or CORRUPTBYTE",
" ARG2 is NA for now",
" Examples...",
" -T ACK,3,SLEEP,5",
fprintf(stderr,"ERROR: %s\n",error);
for(i=0;errmsg[i];i++)
fprintf(stderr,"%s\n",errmsg[i]);
+#include "builtwith.c"
exit(EXIT_ERROR);
}
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#define SOCKADDR_IN struct sockaddr_in
#define PSOCKADDR struct sockaddr *
#define SetConsoleTitle(n)
+#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/utsname.h>
int
showMyIp(void)
{
- int nsfd, sfd, clilen, cpid, portnum;
struct in_addr *ipr;
- struct sockaddr_in serv_addr, cli_addr;
struct hostent *hostptr;
struct utsname uts;
SOCKET listener;
SOCKADDR_IN localAddr;
char RRQmode[32];
+ unsigned localAddr_len;
char *WRQmode, *errmsg;
ushort opcode, blockno, errcode;
char rcvmsg[1024], sndmsg[1024], title[256];
- INT err, localAddr_len, datlen, rcvlen, len, rcvtot;
+ INT err, datlen, rcvlen, len, rcvtot;
#ifdef BUILD_WITH_VCC
err = WSAStartup (0x0101, &WsaData);
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
typedef unsigned short ushort;
#define sleep(n) Sleep(n*1000)
#else
+#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
fprintf(stderr,"TEST: corruption...");
msg[test_CorruptByte] = 0;
}
+ else if (test_Type == TFTPTEST_BBNO) {
+ fprintf(stderr,"TEST: blockno err...");
+ msg[3] += 3;
+ }
}
/* testSetup():
return(-1);
}
}
+ else if (!strncmp(commas[1]+1,"BBNO",4)) {
+ test_Type = TFTPTEST_BBNO;
+ }
else if (!strncmp(commas[1]+1,"QUIT",4)) {
test_Type = TFTPTEST_QUIT;
}
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <winsock2.h>
#define uint32_t unsigned long
#else
+#define Sleep(a) sleep(a/1000)
+#include <unistd.h>
#include <stdint.h>
#ifndef O_BINARY
#define O_BINARY 0
#include <arpa/inet.h>
#endif
+#ifndef IPPORT_TFTP
+#define IPPORT_TFTP 69
+#endif
+
#ifdef BUILD_WITH_VCC
typedef unsigned short ushort;
#else
{
unsigned sfd;
ushort opcode;
- int msglen;
+ unsigned msglen;
struct stat mstat;
uint32_t inaddr;
ushort blockno, lastblockno;
*(ushort *)sndmsg = htons(TFTP_ACK);
sndmsg[2] = rcvmsg[2];
sndmsg[3] = rcvmsg[3];
-#ifdef BUILD_WITH_VCC
+//#ifdef BUILD_WITH_VCC
testTftp(TFTP_DAT,sndmsg,4);
-#endif
+//#endif
SendTo(sfd,sndmsg,4,0,(struct sockaddr *)&resp,
sizeof(server),"ACK",0);
if (rcvsz < TFTP_DATAMAX)
if (tftpVerbose)
printf("Rcvd TFTP_OACK\n");
}
-#ifdef BUILD_WITH_VCC
+//#ifdef BUILD_WITH_VCC
if (tftpPpd)
Sleep(tftpPpd);
-#endif
+//#endif
if (xferlen == -1) {
done = 1;
blockno);
}
}
-#ifdef BUILD_WITH_VCC
+//#ifdef BUILD_WITH_VCC
testTftp(TFTP_ACK,sndmsg,len+4);
-#endif
+//#endif
SendTo(sfd,sndmsg,len+4,0,(struct sockaddr *)&resp,
sizeof(server),"DAT",0);
lastblockno = blockno;
#define TFTPTEST_SLEEP 1
#define TFTPTEST_CORRUPT 2
#define TFTPTEST_QUIT 3
+#define TFTPTEST_BBNO 4
#define RETRY_MAX 10000 /* Give up after RETRY_MAX xmit retries */
extern int ttftp(char *,char *,char *,char *,char *);
extern void ttftp_init(void);
-#ifdef BUILD_WITH_VCC
extern int tftpsrvr();
extern int testSetup(char *msg);
extern void testTftp(int,char *,int);
-#endif
extern int getopt(), optind;
extern char *optarg;
#ifdef BUILD_WITH_VCC
#include <io.h>
+#else
+#include <unistd.h>
#endif
#ifndef O_BINARY
aoutFname,binto);
Lseek(aoutFD,0,SEEK_SET);
stat(aoutFname,&buf);
- cp = (unsigned char *)Malloc(buf.st_size+32);
+ cp = Malloc(buf.st_size+32);
Read(aoutFD,cp,buf.st_size);
ep = (struct exec *)cp;
- tfrom = (unsigned char *)(ep+1);
- dfrom = (unsigned char *)(tfrom + Ahdr.a_text);
+ tfrom = (char *)(ep+1);
+ dfrom = (char *)(tfrom + Ahdr.a_text);
if (write(fd,tfrom,Ahdr.a_text) != (int)Ahdr.a_text) {
perror(binto);
exit(1);
close(fd);
}
-ShowAppend()
+void
+ShowAppend(void)
{
char c;
}
}
-ShowAoutHdr()
+void
+ShowAoutHdr(void)
{
printf("\n\t\tA.OUT FILE HEADER\n");
printf("Magic: 0x%x\n",Ahdr.a_magic);
Ahdr.a_drsize,Ahdr.a_drsize);
}
-ShowAoutMap()
+void
+ShowAoutMap(void)
{
unsigned long tstart, dstart, bstart;
bstart,bstart+Ahdr.a_bss-1,Ahdr.a_bss,Ahdr.a_bss);
}
-ShowAoutOffsets()
+void
+ShowAoutOffsets(void)
{
unsigned long tstart, dstart, bstart;
bstart,bstart+Ahdr.a_bss-1,Ahdr.a_bss);
}
-ShowAoutAppendedDate()
+void
+ShowAoutAppendedDate(void)
{
unsigned long tstart, dstart, bstart;
char c;
0,
};
-main(argc,argv)
-int argc;
-char *argv[];
+int
+main(int argc,char *argv[])
{
char fname[128], *append, *stripto, *binto;
int opt, showstuff;
ShowAoutOffsets();
}
close(aoutFD);
- exit(0);
+ return(0);
}
*/
#include <stdio.h>
+#include <stdlib.h>
#include <ctype.h>
#include <sys/stat.h>
#include <string.h>
+#ifdef BUILD_WITH_VCC
+#else
+#include <unistd.h>
+#endif
+#include "version.h"
#include "utils.h"
#define LINESIZE 256
0,
};
+int
main(int argc,char *argv[])
{
int opt, i;
while(1)
{
- int lsize;
- char *symbol, *data, outline[LINESIZE];
-
if (fgets(line,LINESIZE,symfp) == NULL)
break;
rewind(symfp);
}
fclose(symfp);
- exit(0);
+ return(0);
}
#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#ifndef BUILD_WITH_VCC
#include <unistd.h>
#endif
#include "utils.h"
+#include "version.h"
#ifndef O_BINARY
#define O_BINARY 0
FILE *ofp;
int ofd, ifd, i, j, total, cnt, tenth, percent, width, opt, len;
int swap, begin, end, Size, AssemblerFormat, definetot, nullTerminate;
- char buf[100], arrayname[64], outputfilename[64], *filename;
+ char arrayname[64], outputfilename[64], *filename;
char oline[128];
unsigned char ibuf[BLKSIZ+100];
char defines[16][80];
j = 1;
while(1) {
if ((total + BLKSIZ) > Size)
- cnt = Read(ifd,ibuf,Size-total);
+ cnt = Read(ifd,(char *)ibuf,Size-total);
else
- cnt = Read(ifd,ibuf,BLKSIZ);
+ cnt = Read(ifd,(char *)ibuf,BLKSIZ);
if (cnt <= 0)
break;
if (width == 1) {
#include <stdio.h>
+#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "utils.h"
+#include "version.h"
#ifndef BUILD_WITH_VCC
#include <unistd.h>
#endif
/* converts a file to a Motorola S3 record */
-main(argc,argv)
-int argc;
-char **argv;
+int
+main(int argc,char *argv[])
{
- FILE *ofp;
int ifd, i, total, cnt, csum, opt;
unsigned long address, offset, base;
unsigned char ibuf[100], *cp;
}
printf("S705000019E001\n");
close(ifd);
- exit(0);
+ return(0);
}
char *usage_txt[] = {
* Just take a file and swap the bytes (either by 2 or by 4).
*/
#include <stdio.h>
+#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#ifndef BUILD_WITH_VCC
#include <unistd.h>
#endif
#include "utils.h"
+#include "version.h"
#ifndef O_BINARY
#define O_BINARY 0
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#ifdef BUILD_WITH_VCC
#include <io.h>
extern int optind;
#include <unistd.h>
#endif
+#include "utils.h"
+#include "version.h"
+
int debug;
char *usage_txt[] = {
phone: 908-582-2351
*/
#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/stat.h>
#ifdef BUILD_WITH_VCC
#include <io.h>
+#else
+#include <unistd.h>
#endif
+#include "packdata.h"
#include "coff.h"
#include "../zlib/zlib.h"
#include "utils.h"
return(&CoffFhdr);
}
+int
GetCoffSectionHdrs(void)
{
int i;
printf("Total savings of %d bytes\n",savings);
}
+int
zipdata(src,dest,srcsize,mode,verbose)
char *src, *dest, *mode;
int srcsize, verbose;
0,
};
-main(argc,argv)
-int argc;
-char *argv[];
+int
+main(int argc,char *argv[])
{
extern int optind;
extern char *optarg;
if (showstuff & SHOWSECTIONS)
ShowCoffSections();
}
- exit(0);
+ return(0);
}
* Simply scans through the file removing all instances of 0x0d.
*/
#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
int
main(int argc,char *argv[])
{
- struct stat mstat;
- int ifd, ofd, opt, i, arg;
+ int ifd, ofd, opt, arg;
char c, tmpfile[16], *infile, cmd[128];
while((opt=getopt(argc,argv,"V")) != EOF) {
#include <stdio.h>
#include <stdlib.h>
+#ifdef BUILD_WITH_VCC
+#else
+#include <unistd.h>
+#endif
#include <time.h>
#include "utils.h"
* phone: 908-582-2351
*/
#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "elf.h"
+#include "version.h"
#include "utils.h"
#include "../zlib/zlib.h"
+#ifdef BUILD_WITH_VCC
+#else
+#include <unistd.h>
+#endif
#ifndef O_BINARY
#define O_BINARY 0
void
ShowElfHdr(void)
{
- int i, j;
+ int i;
printf("\t\tELF FILE HEADER\n");
printf("E_IDENT (hex): ");
void
ShowProgramHdrTbl(int verbose)
{
- int i, j;
+ int i;
printf("\t\tProgram Header Table:\n");
for(i=0;i<Ehdr.e_phnum;i++) {
{
int i;
unsigned long size;
- char buf[32];
struct elf_shdr *eshdr;
if (debug >= 2)
}
Lseek(elfFD,0,SEEK_SET);
- cp = Malloc(lowest_section_offset);
- Read(elfFD,cp,lowest_section_offset);
- Write(zipfd,cp,lowest_section_offset);
+ cp = (uchar *)Malloc(lowest_section_offset);
+ Read(elfFD,(char *)cp,lowest_section_offset);
+ Write(zipfd,(char *)cp,lowest_section_offset);
free(cp);
offset_delta = 0;
fprintf(stderr,"Couldn't open %s\n",zoutfile);
exit(1);
}
- cp = Malloc(zstat.st_size);
- Read(secfd,cp,zstat.st_size);
- Write(zipfd,cp,zstat.st_size);
- free(cp);
+ cp = (uchar *)Malloc(zstat.st_size);
+ Read(secfd,(char *)cp,zstat.st_size);
+ Write(zipfd,(char *)cp,zstat.st_size);
+ free((char *)cp);
close(secfd);
if (remove_zouts)
unlink(zoutfile);
fprintf(stderr,"Read %s offset=%d size=%d\n",
name,sptr->sh_offset,sptr->sh_size);
Lseek(elfFD,sptr->sh_offset,SEEK_SET);
- cp = Malloc(sptr->sh_size);
- Read(elfFD,cp,sptr->sh_size);
+ cp = (uchar *)Malloc(sptr->sh_size);
+ Read(elfFD,(char *)cp,sptr->sh_size);
#if USE_OFFSET_DELTA
sptr_z->sh_offset -= offset_delta;
#else
sptr_z->sh_offset = tell(zipfd);
#endif
- Write(zipfd,cp,sptr->sh_size);
+ Write(zipfd,(char *)cp,sptr->sh_size);
free(cp);
}
}
void
ElfToBinary(char *binto)
{
+ uchar *cp;
int fd, sidx, firstone;
- struct stat buf;
- uchar *tfrom, *dfrom, *cp;
- unsigned long paddr;
struct elf_shdr *sptr;
unlink(binto);
name,sptr->sh_addr,sptr->sh_size);
cp = (uchar *)Malloc(sptr->sh_size);
Lseek(elfFD,sptr->sh_offset,SEEK_SET);
- read(elfFD,cp,sptr->sh_size);
- Write(fd,cp,sptr->sh_size);
+ read(elfFD,(char *)cp,sptr->sh_size);
+ Write(fd,(char *)cp,sptr->sh_size);
free(cp);
nextpaddr = sptr->sh_addr + sptr->sh_size;
firstone = 0;
Read(fd,branch,4);
Lseek(fd,-4,SEEK_CUR);
for(i=0;i<insertPAD;i++)
- Write(fd,&PadByte,1);
+ Write(fd,(char *)&PadByte,1);
Write(fd,branch,4);
}
close(fd);
StripElfFile(char *stripto,char *append)
{
uchar *cp;
- FILE *zout;
unsigned long shoffs, offset_delta;
int stripfd, sidx, newsectot;
struct elf_shdr *sptr, *scntbl_s, *sptr_s;
- struct stat zstat;
fprintf(stderr,"Stripping %s into %s \n",elfFname,stripto);
fprintf(stderr,"Not working yet\n");
if (debug)
fprintf(stderr,"Copying first %ld bytes\n",ScnTbl[1].sh_offset);
Lseek(elfFD,0,SEEK_SET);
- cp = Malloc(ScnTbl[1].sh_offset);
- Read(elfFD,cp,ScnTbl[1].sh_offset);
- Write(stripfd,cp,ScnTbl[1].sh_offset);
+ cp = (uchar *)Malloc(ScnTbl[1].sh_offset);
+ Read(elfFD,(char *)cp,ScnTbl[1].sh_offset);
+ Write(stripfd,(char *)cp,ScnTbl[1].sh_offset);
free(cp);
scntbl_s[0] = ScnTbl[0];
fprintf(stderr,"Copying %s (%d bytes)\n",
name,sptr->sh_size);
Lseek(elfFD,sptr->sh_offset,SEEK_SET);
- cp = Malloc(sptr->sh_size);
- Read(elfFD,cp,sptr->sh_size);
- Write(stripfd,cp,sptr->sh_size);
+ cp = (uchar *)Malloc(sptr->sh_size);
+ Read(elfFD,(char *)cp,sptr->sh_size);
+ Write(stripfd,(char *)cp,sptr->sh_size);
sptr_s->sh_offset -= offset_delta;
free(cp);
}
GetElfSectionName(unsigned long index)
{
static char buf[64];
- char *strings, *bp, *end, *name;
+ char *strings, *name;
struct elf_shdr *eshdr;
if (debug >= 2)
0,
};
-main(argc,argv)
-int argc;
-char *argv[];
+int
+main(int argc,char *argv[])
{
extern int optind;
extern char *optarg;
char fname[128], buf[16], *append, *binto, *stripto;
- int i, opt, showstuff, zlevel;
+ int opt, showstuff, zlevel;
elfFD = 0;
zlevel = 0;
if (showstuff & SHOWPRGMHDR)
ShowProgramHdrTbl(verbose);
}
- exit(0);
+ return(0);
}
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
+#ifdef BUILD_WITH_VCC
+#else
+#include <unistd.h>
+#endif
+#include "version.h"
#include "utils.h"
#ifdef BUILD_WITH_VCC
};
struct tfsflg tfsflgtbl[] = {
- TFS_BRUN, 'b',
- TFS_QRYBRUN, 'B',
- TFS_EXEC, 'e',
- TFS_AOUT, 'A',
- TFS_COFF, 'C',
- TFS_ELF, 'E',
- TFS_IPMOD, 'i',
- TFS_UNREAD, 'u',
- TFS_ULVL0, '0',
- TFS_ULVL1, '1',
- TFS_ULVL2, '2',
- TFS_ULVL3, '3',
- TFS_CPRS, 'c',
- 0, 0,
+ { TFS_BRUN, 'b' },
+ { TFS_QRYBRUN, 'B' },
+ { TFS_EXEC, 'e' },
+ { TFS_AOUT, 'A' },
+ { TFS_COFF, 'C' },
+ { TFS_ELF, 'E' },
+ { TFS_IPMOD, 'i' },
+ { TFS_UNREAD, 'u' },
+ { TFS_ULVL0, '0' },
+ { TFS_ULVL1, '1' },
+ { TFS_ULVL2, '2' },
+ { TFS_ULVL3, '3' },
+ { TFS_CPRS, 'c' },
+ { 0, 0 }
};
char *usage_txt[] = {
int
buildTfsHeader(unsigned long address, struct finfo *fip, struct tfshdr *tfp)
{
- int sizeofheader, modnext, alignadjust, rsvd;
+ int modnext, alignadjust, rsvd;
memset((char *)tfp,0,TFSHDRSIZ);
strncpy(tfp->name,fip->name,TFSNAMESIZE);
tfp->flags = 0;
tfp->flags |= (TFS_ACTIVE | TFS_AIPNOT);
if (!(tfp->flags & TFS_IPMOD))
- tfp->filcrc = otherEnd32(endianSwap,crc32(fip->filecontent,fip->size));
+ tfp->filcrc = otherEnd32(endianSwap,
+ crc32((uchar *)fip->filecontent,fip->size));
else
tfp->filcrc = 0xffffffff;
fclose(fp);
}
+int
main(int argc,char *argv[])
{
unsigned long tfsoffset, flashbase, padto;
struct stat statbuf;
struct finfo *fip;
int ftot, totalmem;
- int i, opt, ifd, size, swapmonitor, swapall;
+ int i, opt, ifd, swapmonitor, swapall;
uchar fillbyte;
struct tfshdr hdrbuf;
char *membase, *memptr, outtype;
close(ifd);
fip++;
}
- totalmem;
memptr = membase = malloc(totalmem+1024);
if (!memptr)
if (outtype == 's') {
if (!Outfile)
Outfile = "mem.srec";
- buf2srec(membase,totalmem);
+ buf2srec((uchar *)membase,totalmem);
}
else {
if (!Outfile)
Outfile = "mem.bin";
- buf2bin(membase,totalmem);
+ buf2bin((uchar *)membase,totalmem);
}
if (verbose)
free(FileTable[i].filecontent);
free(membase);
- exit(0);
+ return(0);
}
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include "version.h"
#include "utils.h"
#include "crc32.h"
#ifndef BUILD_WITH_VCC
int
main(int argc,char *argv[])
{
- char *buf;
- int ifd, opt;
+ int opt;
unsigned long crc;
- struct stat mstat;
while((opt=getopt(argc,argv,"V")) != EOF) {
switch(opt) {
#include <sys/stat.h>
#include <sys/types.h>
#include "utils.h"
+#include "version.h"
#include "crc32.h"
#ifndef BUILD_WITH_VCC
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#ifdef BUILD_WITH_VCC
+#else
+#include <unistd.h>
+#endif
+#include "version.h"
#include "utils.h"
int debug;
coff$(O_EXT) d2u$(O_EXT) \
defdate$(O_EXT) elf$(O_EXT) f2mem$(O_EXT) fcrc$(O_EXT) \
make2flist$(O_EXT) monsym$(O_EXT) mkupdate$(O_EXT) \
- mkbmp$(O_EXT) mktfsimg$(O_EXT) fsize$(O_EXT) \
+ mkbin$(O_EXT) mkbmp$(O_EXT) mktfsimg$(O_EXT) fsize$(O_EXT) \
title$(O_EXT) tfs$(O_EXT) what$(O_EXT) vsub$(O_EXT) u2d$(O_EXT)
TOOLS = $(OBJS:$(O_EXT)=$(E_EXT))
$(CC) $(CFLAGS) -o version$(O_EXT) ../comsrc/version.c
$(LN) make2flist$(O_EXT) utils$(O_EXT) version$(O_EXT)
+mkbin$(E_EXT): mkbin$(O_EXT) utils$(O_EXT)
+ $(CC) $(CFLAGS) -o version$(O_EXT) ../comsrc/version.c
+ $(LN) mkbin$(O_EXT) utils$(O_EXT) version$(O_EXT)
+
mkbmp$(E_EXT): mkbmp$(O_EXT) utils$(O_EXT)
$(CC) $(CFLAGS) -o version$(O_EXT) ../comsrc/version.c
$(LN) mkbmp$(O_EXT) utils$(O_EXT) version$(O_EXT)
--- /dev/null
+/* mkbin.c:
+ * This tool is used as part of a test for the TFS defragger.
+ * It builds a file of a specified size, and optionally (-t option)
+ * tests a file that already exists to verify that its content is
+ * what would have been created.
+ * This allows a file of any size to be created, downloaded to TFS,
+ * put through defragmentation, uploaded and then verified.
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef BUILD_WITH_VCC
+#else
+#include <unistd.h>
+#endif
+#include "version.h"
+#include "utils.h"
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+int debug, optind;
+
+char *usage_txt[] = {
+ "Usage: mkbin [options] {filename} {size}",
+ " Options:",
+ " -d debug mode",
+ " -t test file",
+ " -V display version of tool",
+ 0
+};
+/* Data array used to create the file...
+ * All of the data is readable just to make things easier to debug.
+ */
+char *data = "012345678901234567890123456789\nabcdefghijklmnopqrstuvwxyz\nABCDEFGHIJKLMNOPQRSTUVWXYZ\n!@#$%^&*()_+!@#$%^&*()_+!@#$%^&*()_+\n";
+
+
+int
+main(int argc,char *argv[])
+{
+ char *fname;
+ long opt, fd, tot, dlen, size, test;
+
+ test = 0;
+ while ((opt=getopt(argc,argv,"dtV")) != EOF) {
+ switch(opt) {
+ case 'd':
+ debug = 1;
+ break;
+ case 't':
+ test = 1;
+ break;
+ case 'V':
+ showVersion();
+ break;
+ default:
+ usage(0);
+ }
+ }
+
+ if (argc != optind+2)
+ usage(0);
+
+ dlen = strlen(data);
+ fname = argv[optind];
+ size = strtol(argv[optind+1],0,0);
+
+ if (debug) {
+ fprintf(stderr,"dlen=%d, fname=%s, size=%d\n",dlen,fname,size);
+ }
+
+ if (test) {
+ int pkt;
+ char *buf, *bp;
+ struct stat fstat;
+
+ if (stat(fname,&fstat) < 0) {
+ fprintf(stderr,"mkbin: File '%s' doesn't exist.\n",fname);
+ exit(1);
+ }
+ if (fstat.st_size != size) {
+ fprintf(stderr,"mkbin: Invalid file size (%d != %d)\n",
+ fstat.st_size,size);
+ exit(1);
+ }
+ buf = Malloc(size);
+ if ((fd = open(fname,O_RDONLY | O_BINARY))==-1) {
+ fprintf(stderr,"mkbin: Can't open file '%s'\n",fname);
+ exit(1);
+ }
+ Read(fd,buf,size);
+ close(fd);
+ tot = 0;
+ bp = buf;
+ pkt = 0;
+ while(1) {
+ if (tot < (size-dlen)) {
+ if (memcmp(bp,data,dlen) != 0) {
+ fprintf(stderr,"mkbin: Mismatch in packet %d\n",pkt);
+ fprintf(stderr,
+ "mkbin: Packet %d starts at offset %d (0x%x)\n",
+ pkt,tot,tot);
+ exit(1);
+ }
+ tot += dlen;
+ bp += dlen;
+ pkt++;
+ }
+ else {
+ if (memcmp(bp,data,size-tot) != 0) {
+ fprintf(stderr,"mkbin: Mismatch in last packet (%d)\n",pkt);
+ fprintf(stderr,
+ "mkbin: Packet %d starts at offset %d (0x%x)\n",
+ pkt,tot,tot);
+ exit(1);
+ }
+ break;
+ }
+ }
+ free(buf);
+ fprintf(stderr,"mkbin: %s test passed\n",fname);
+ }
+ else {
+ if ((fd = open(fname,O_WRONLY|O_BINARY|O_CREAT|O_TRUNC,0777))==-1) {
+ fprintf(stderr,"mkbin: Can't open file %s\n",fname);
+ exit(1);
+ }
+
+ tot = 0;
+ while(1) {
+ if (tot < (size-dlen)) {
+ write(fd,data,dlen);
+ tot += dlen;
+ }
+ else {
+ write(fd,data,size-tot);
+ break;
+ }
+ }
+ close(fd);
+ }
+ exit(0);
+}
* to a .bmp file format.
*/
#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#endif
+#include "utils.h"
+#include "version.h"
+
#ifndef O_BINARY
#define O_BINARY 0
{
short sval;
struct stat mstat;
- int ifd, ofd, opt, i, readmode;
- char lastc, c, tmpfile[16], *infile;
+ int ifd, ofd, opt, readmode;
+ char tmpfile[16], *infile;
unsigned char ibytes[2], obytes[3];
readmode = 0;
#include <unistd.h>
#endif
+#include "version.h"
+
/* Note that these two files (tfs.h and tfsprivate.h) are included in the
* host tools directory only for convenience (so that the host directory can
* be isolated from the target directory). The files tfs.h and tfsprivate.h
{
FILE* in;
char line[256];
- size_t len = 0;
- size_t read;
int lnum = 0;
long reloc;
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include "version.h"
#include "utils.h"
#include "crc32.h"
#ifndef BUILD_WITH_VCC
void
mkupdate(void)
{
- int ifd;
unsigned long crc;
- char *buf, *comma;
flist = fbase;
printf("\n#\n#\n");
printf("tftp -F %s%s%s $TFTPSRVR get %s\n",
flist->tfs_fname,fbuf,ibuf,flist->host_fname);
+ printf("tfs base %s BASE\n",flist->tfs_fname);
printf("set -i FTOT\nreturn\n");
flist = flist->next;
}
#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
#include <ctype.h>
#include <sys/stat.h>
#include <string.h>
+#ifdef BUILD_WITH_VCC
+#else
+#include <unistd.h>
+#endif
+#include "version.h"
#include "utils.h"
#define LINESIZE 256
0,
};
+int
main(int argc,char *argv[])
{
char *dataPrefix, *symbolPrefix, *fmt, line[LINESIZE];
}
if (sortbase) {
- int lsize, line_cnt;
- char *symbol, *data, outline[LINESIZE];
+ int line_cnt;
+ char *symbol, *data;
line_cnt = 0;
while(1) {
fprintf(stderr,"%d symbols truncated\n",truncTot);
if (symfp)
fclose(symfp);
- exit(0);
+ return(0);
}
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include "packdata.h"
//extern char *malloc();
/* encode the current file */
/* return 1 if successful, 0 otherwise */
-static
-output ()
+static int
+output (void)
{
extern long lseek();
int c, i, inleft;
}
/* makes a heap out of heap[i],...,heap[n] */
-static
-heapify (i)
+static void
+heapify (int i)
{
register int k;
int lastparent;
/* return 1 after successful packing, 0 otherwise */
static int
-packbuffer()
+packbuffer(void)
{
register int c, i, p;
long bitsout;
char *sourceBase;
char *destBase;
-getdata(buffer,size)
-char *buffer;
-int size;
+int
+getdata(char *buffer,int size)
{
int i, tot;
return(tot);
}
-putdata(buffer,size)
-char *buffer;
-int size;
+int
+putdata(char *buffer,int size)
{
int i;
return(size);
}
-packdata(src,dest,srcsize,verbose)
-char *src, *dest;
-int srcsize, verbose;
+int
+packdata(char *src,char *dest,int srcsize,int verbose)
{
int i;
--- /dev/null
+extern int getdata(char *buffer,int size);
+extern int putdata(char *buffer,int size);
+extern int packdata(char *src,char *dest,int srcsize,int verbose);
#include <sys/stat.h>
#ifdef BUILD_WITH_VCC
#include <io.h>
+#else
+#include <unistd.h>
#endif
+#include "version.h"
#include "utils.h"
/* Note that these two files are included in the host tools directory
/* Allocate space for local storage of the file, but make sure that
* the base address of the data is 16-byte aligned...
*/
- flash = Malloc(mstat.st_size+64);
+ flash = (uchar *)Malloc(mstat.st_size+64);
end = flash + mstat.st_size+64;
flash += 32;
#if 0
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <ctype.h>
+#include <string.h>
#ifdef BUILD_WITH_VCC
#define WIN32_LEAN_AND_MEAN
#include <sys/types.h>
int
main(int argc,char *argv[])
{
- char string[256];
char *title;
if (argc == 1) {
* Simply scans through the file and replaces all 0x0a's with 0x0d 0x0a.
*/
#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
int
main(int argc,char *argv[])
{
- struct stat mstat;
- int ifd, ofd, opt, i, arg;
+ int ifd, ofd, opt, arg;
char lastc, c, cr, tmpfile[16], *infile, cmd[128];
cr = 0x0d;
/* fileexists():
Return1 if name is a valid file; else 0.
*/
+int
fileexists(char *name)
{
struct stat buf;
return(cp);
}
+int
Write(int fd,char *buf,int size)
{
int ret;
for(i=0;usage_txt[i];i++)
fprintf(stderr,"%s\n",usage_txt[i]);
-
+
+#include "builtwith.c"
+
exit(1);
}
* with VALUE.
*/
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/stat.h>
+#ifdef BUILD_WITH_VCC
+#else
+#include <unistd.h>
+#endif
#include "utils.h"
#include "version.h"
0,
};
+int
main(int argc,char *argv[])
{
FILE *ifp, *ofp;
int opt, i, pairtot, vsubtot, lno;
- char iline[LINESIZE], oline[LINESIZE*2], *eq, *cp;
+ char iline[LINESIZE], *eq, *cp;
while((opt=getopt(argc,argv,"vV")) != EOF) {
switch(opt) {
fclose(ofp);
if (verbose)
fprintf(stderr,"%d substitutions\n",vsubtot);
- exit(0);
+ return(0);
}
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "utils.h"
+#include "version.h"
#ifndef BUILD_WITH_VCC
#include <unistd.h>
#endif
/* converts a file to a Motorola S3 record */
+int
main(int argc,char **argv)
{
int ifd, opt, state;
}
free(buf);
- exit(0);
+ return(0);
}
* alt_tfsdevtbl_base = ALTTFSDEVTBLBASE;
*/
- .globl alt_tfsdevtbl_base
+ .global alt_tfsdevtbl_base
.balign 0x10
static void ArpFlush(void);
static void ArpShow(char *);
+static void llas(char *);
static int ArpStore(uchar *,uchar *);
static int IpIsOnThisNet(uchar *);
+static unsigned long probeIP;
+static char probeAbort;
+
+/* Constants used by Dynamic IPV4 Local-Link Address setup...
+ * (see RFC 3927)
+ */
+#define PROBE_WAIT 1000 /* (msec) */
+#define PROBE_NUM 3
+#define PROBE_MIN 1000 /* (msec) */
+#define PROBE_MAX 2000 /* (msec) */
+#define ANNOUNCE_WAIT 2000 /* (msec) */
+#define ANNOUNCE_NUM 2
+#define ANNOUNCE_INTERVAL 2000 /* (msec) */
+#define MAX_CONFLICTS 10
+#define RATE_LIMIT_INTERVAL 60000 /* (msec) */
+#define DEFEND_INTERVAL 10000 /* (msec) */
+
/* arpcache[]:
* Used to store the most recent set of IP-to-MAC address correlations.
*/
}
/* SendArpRequest():
+ * If 'probe' is non-zero, then the request is an arp-probe.
+ * Refer to RFC3927 for more on that.
*/
-int
-SendArpRequest(uchar *ip)
+static int
+SendArpRequest(uchar *ip, int probe)
{
struct ether_header *te;
struct arphdr *ta;
ta->plen = 4; /* Length of protocol (ip) address */
ta->operation = ecs(ARP_REQUEST);
memcpy((char *)ta->senderha, (char *)BinEnetAddr,6);
- memcpy((char *)ta->senderia, (char *)BinIpAddr,4);
- memcpy((char *)ta->targetha, (char *)BroadcastAddr,6);
+ if (probe) {
+ memset((char *)ta->senderia,0,4);
+ memset((char *)ta->targetha,0,6);
+ }
+ else {
+ memcpy((char *)ta->senderia, (char *)BinIpAddr,4);
+ memcpy((char *)ta->targetha, (char *)BroadcastAddr,6);
+ }
memcpy((char *)ta->targetia, (char *)ip,4);
sendBuffer(ARPSIZE);
return(0);
char *ArpHelp[] = {
"Address resolution protocol",
- "-[fps:v] [IP]",
+ "-[flps:v] [IP]",
#if INCLUDE_VERBOSEHELP
" -f flush cache",
+ " -l dynamic config using link-local arp probe",
" -p proxy arp",
" -s{eadr} store eadr/IP into cache",
#if INCLUDE_ETHERVERBOSE
int
Arp(int argc,char *argv[])
{
- int opt, proxyarp;
+ int opt, proxyarp, llad;
char binip[8], binether[8], *storeether;
- proxyarp = 0;
+ llad = proxyarp = 0;
storeether = (char *)0;
- while ((opt=getopt(argc,argv,"fps:v")) != -1) {
+ while ((opt=getopt(argc,argv,"flps:v")) != -1) {
switch(opt) {
case 'f': /* Flush current arp cache */
ArpFlush();
break;
+ case 'l': /* Dynamic ip-config using link-local addressing */
+ llad = 1; /* (refer to RFC 3927) */
+ break;
case 's': /* Store specified IP/MAC combination in arp cache. */
storeether = optarg;
break;
}
}
- if (argc == (optind+1)) {
+ /* If llad flag is set, then we do a dynamic configuration using the
+ * link-local protocol as described in RFC 3927...
+ */
+ if (llad) {
+ char buf[32];
+ struct elapsed_tmr tmr;
+ int i, retry, conflicts, psval;
+
+ dhcpDisable();
+ probeAbort = retry = conflicts = 0;
+
+ /* Use MAC address to establish a uniformly selected pseudo random
+ * value between 0 and 1000...
+ */
+ psval = (BinEnetAddr[5] * 4);
+
+ monDelay(psval);
+
+ if (argc == (optind+1))
+ IpToBin((char *)argv[optind],(unsigned char *)&probeIP);
+ else
+ llas((char *)&probeIP);
+
+nextllas:
+ SendArpRequest((uchar *)&probeIP,1);
+ startElapsedTimer(&tmr,ANNOUNCE_WAIT);
+ while(!msecElapsed(&tmr)) {
+ if (probeAbort) {
+ llas((char *)&probeIP);
+ probeAbort = retry = 0;
+ monDelay(psval + PROBE_MIN);
+ goto nextllas;
+ }
+ if (EtherFromCache((uchar *)&probeIP)) {
+ if (++conflicts > MAX_CONFLICTS)
+ monDelay(RATE_LIMIT_INTERVAL);
+ else
+ monDelay(psval + PROBE_MIN);
+ if (++retry == PROBE_NUM) {
+ llas((char *)&probeIP);
+ retry = 0;
+ }
+ goto nextllas;
+ }
+ pollethernet();
+ }
+ /* If we're here, then we found an IP address that is not being
+ * used on the local subnet...
+ */
+ setenv("IPADD",IpToString(probeIP,buf));
+ setenv("NETMASK","255.255.0.0");
+ setenv("GIPADD",0);
+ EthernetStartup(EtherVerbose,0);
+ for(i=0;i<ANNOUNCE_NUM;i++) {
+ SendArpRequest(BinIpAddr,0);
+ monDelay(ANNOUNCE_INTERVAL);
+ }
+ }
+ else if (argc == (optind+1)) {
IpToBin((char *)argv[optind],(unsigned char *)binip);
if (storeether) {
EtherToBin((char *)storeether, (unsigned char *)binether);
retry = 0;
RetransmitDelay(DELAY_INIT_ARP);
while(1) {
- /* If IP is not on this net, the get the GATEWAY IP address. */
+ /* If IP is not on this net, then get the GATEWAY IP address. */
if (!proxyarp && !IpIsOnThisNet(binip)) {
gip = getenv("GIPADD");
if (gip) {
}
return(ep);
}
- SendArpRequest(gbinip);
+ SendArpRequest(gbinip,0);
Ip = gbinip;
}
else {
- SendArpRequest(binip);
+ SendArpRequest(binip,0);
Ip = binip;
}
}
else {
- SendArpRequest(binip);
+ SendArpRequest(binip,0);
Ip = binip;
}
if (retry) {
self_ecs(arpp->protocol);
self_ecs(arpp->operation);
+ /* If the sender IP address is all zeroes, then assume this is
+ * an arp probe. If we are currently doing a probe, and the
+ * address we are probing matches the target IP address of this
+ * probe, then set a flag that will abort the current probe.
+ */
+ if ((arpp->senderia[0] == 0) && (arpp->senderia[1] == 0) &&
+ (arpp->senderia[2] == 0) && (arpp->senderia[3] == 0)) {
+ if (memcmp((char *)arpp->targetia,(char *)&probeIP,4) == 0)
+ probeAbort = 1;
+ }
+
switch(arpp->operation) {
case ARP_REQUEST:
if (!memcmp((char *)arpp->targetia, (char *)BinIpAddr,4)) {
break;
case ARP_RESPONSE:
if (!memcmp((char *)arpp->targetia, (char *)BinIpAddr,4)) {
+ if (!memcmp((char *)arpp->targetia,(char *)arpp->senderia,4))
+ printf("WARNING: IP %s may be in use on network\n",IPadd);
+
ArpStore(arpp->senderia,arpp->senderha);
}
break;
return((char *)(arpp + 1));
}
+/* sendGratuitousARP():
+ * As defined in RFC 3220...
+ *
+ * An ARP packet sent by a node in order to spontaneously
+ * cause other nodes to update an entry in their ARP cache.
+ *
+ * Issue a "gratuitous ARP" (RFC 3220) for two reasons...
+ * - make sure no other host is already using this IP address.
+ * - cause other devices on cable to update their arp cache.
+ */
+void
+sendGratuitousArp(void)
+{
+ SendArpRequest(BinIpAddr,0);
+}
+
+/* llas():
+ * Link local address selection.
+ * Referring to sec 2.1 of RFC3927, select an address using a pseudo-random
+ * number generator to assign a number in the range from
+ * 169.254.1.0 (0xa9fe0100) thru 169.254.254.255 (0xa9fefeff).
+ * To do this, we run a 32-bit CRC on the 6-byte MAC address, then add the
+ * least significant 8 bits of that value to the base of the address
+ * range. Each successive time this function is called, then increment
+ * by the least significant 4 bits of the LSB of the MAC.
+ */
+#define LLAD_BEGIN 0xa9fe0100
+#define LLAD_END 0xa9fefeff
+
+static void
+llas(char *ipptr)
+{
+ static char beenhere;
+ static unsigned long llad;
+ unsigned long pseudorandval, tmp;
+
+ if (beenhere == 0) {
+ pseudorandval = crc32(BinEnetAddr,6);
+ llad = LLAD_BEGIN + (pseudorandval & 0xff);
+ }
+ else {
+ pseudorandval = (unsigned long)(BinEnetAddr[5] & 0xf);
+ llad += pseudorandval;
+ if (llad >= LLAD_END)
+ llad = LLAD_BEGIN + pseudorandval + beenhere;
+ }
+ beenhere++;
+
+ printf("LLAD: %d.%d.%d.%d\n",
+ (llad & 0xff000000) >> 24, (llad & 0xff0000) >> 16,
+ (llad & 0xff00) >> 8, (llad & 0xff));
+
+ tmp = ecl(llad);
+
+ if (ipptr)
+ memcpy(ipptr,(char *)&tmp,4);
+}
+
#endif
#include "stddefs.h"
#include "timer.h"
#include "ether.h"
+#include "fbi.h"
#define CTLC 0x03 /* control-c */
int rawmode, ConsoleBaudRate;
+/* extWatchDog():
+ * This function pointer is used by the application to override the
+ * monitor's configured watchdog functionality. Refer to config.h
+ * in umon_ports/template for more information on the WATCHDOG macro.
+ */
+#ifdef WATCHDOG_ENABLED
+int (*remoteWatchDog)(void);
+#endif
+
+/* remotexxxx() function pointers:
+ * These function pointers provide the application with the ability to
+ * override the monitor's default putchar/getchar/gotachar functions.
+ * See comments above InitRemoteIO() function below for more info.
+ */
int (*remoterawon)(void);
int (*remoterawoff)(void);
int (*remoteputchar)(int);
if (rawmode) {
target_putchar(c);
+ fbi_putchar(c);
return((int)c);
}
*/
if (c == '\n') {
SendIPMonChar('\r',0);
+ fbi_putchar('\r');
target_putchar('\r');
}
SendIPMonChar(c,0);
target_putchar(c);
+ fbi_putchar(c);
WATCHDOG_MACRO;
return((int)c);
}
if (remotegetchar)
return(remotegetchar());
- while(!target_gotachar()) {
+ while(!gotachar()) {
/* While waiting for an incoming character, call pollethernet()
* to process any incoming packets. Note that if INCLUDE_ETHERNET
* is 0 in config.h, then this function is NULL (see ether.h).
if (remotegotachar)
return(remotegotachar());
+ fbi_cursor();
WATCHDOG_MACRO;
return(target_gotachar());
}
extern int Dis(int, char **);
extern int Dm(int, char **);
extern int Dhcp(int, char **);
+extern int DnsCmd(int, char **);
extern int Echo(int, char **);
extern int Edit(int, char **);
extern int Ether(int, char **);
extern int Exit(int, char **);
extern int FatfsCmd(int, char **);
+extern int FbiCmd(int, char **);
extern int FlashCmd(int, char **);
extern int Fm(int, char **);
extern int Gdb(int, char **);
extern int History(int, char **);
extern int Icmp(int, char **);
extern int Ide(int, char **);
+extern int I2cCmd(int, char **);
extern int If(int, char **);
extern int Igmp(int, char **);
extern int Item(int, char **);
extern int SyslogCmd(int, char **);
extern int Tfs(int, char **);
extern int Tftp(int, char **);
+extern int TsiCmd(int, char **);
extern int Ulvl(int, char **);
extern int Unzip(int, char **);
extern int Version(int, char **);
extern char *DisHelp[];
extern char *DhcpHelp[];
extern char *DmHelp[];
+extern char *DnsHelp[];
extern char *EchoHelp[];
extern char *EditHelp[];
extern char *EtherHelp[];
extern char *ExitHelp[];
extern char *FatfsHelp[];
+extern char *FbiHelp[];
extern char *FlashHelp[];
extern char *FmHelp[];
extern char *GdbHelp[];
extern char *HistoryHelp[];
extern char *IcmpHelp[];
extern char *IdeHelp[];
+extern char *I2cHelp[];
extern char *IfHelp[];
extern char *IgmpHelp[];
extern char *ItemHelp[];
extern char *SyslogHelp[];
extern char *TfsHelp[];
extern char *TftpHelp[];
+extern char *TsiHelp[];
extern char *UlvlHelp[];
extern char *UnzipHelp[];
extern char *VersionHelp[];
#if INCLUDE_DM
{ "dm", Dm, DmHelp, 0 },
#endif
+#if INCLUDE_DNS
+ { "dns", DnsCmd, DnsHelp, 0 },
+#endif
#if INCLUDE_TFSSCRIPT
{ "echo", Echo, EchoHelp, 0 },
#endif
#if INCLUDE_FATFS
{ "fatfs", FatfsCmd, FatfsHelp, 0 },
#endif
+#if INCLUDE_FBI
+ { "fbi", FbiCmd, FbiHelp, 0 },
+#endif
#if INCLUDE_FLASH
{ "flash", FlashCmd, FlashHelp, 0 },
#endif
{ "history", History, HistoryHelp, 0 },
#endif
+#if INCLUDE_I2C
+ { "i2c", I2cCmd, I2cHelp, 0 },
+#endif
+
#if INCLUDE_ICMP
{ "icmp", Icmp, IcmpHelp, CMDFLAG_NOMONRC },
#endif
{ "tfs", Tfs, TfsHelp, 0 },
#endif
+#if INCLUDE_TSI
+ { "tsi", TsiCmd, TsiHelp, 0 },
+#endif
+
#if INCLUDE_UNZIP
{ "unzip", Unzip, UnzipHelp, 0 },
#endif
}
else if ((DHCPState == DHCPSTATE_REQUEST) && (msgtype == DHCPACK)) {
ulong cookie;
+ char ipsrc[4];
/* Target issued the REQUEST, the incoming packet is the server's
* ACK reply. We're done so load the environment now.
*/
+ memcpy(ipsrc,(char *)&ihdr->ip_src,4);
+ shell_sprintf("DHCPOFFERFROM","%d.%d.%d.%d",
+ ipsrc[0],ipsrc[1],ipsrc[2],ipsrc[3]);
/* If bootfile is nonzero, store it into BOOTFILE shell var: */
if (dhdr->bootfile[0])
}
char *
-DHCPopt(op)
-int op;
+DHCPmsgtype(int msg)
{
- switch(op) {
+ char *type;
+
+ switch(msg) {
case DHCPDISCOVER:
- return("DISCOVER");
+ type = "DISCOVER";
+ break;
case DHCPOFFER:
- return("OFFER");
+ type = "OFFER";
+ break;
case DHCPREQUEST:
- return("REQUEST");
+ type = "REQUEST";
+ break;
case DHCPDECLINE:
- return("DECLINE");
+ type = "DECLINE";
+ break;
case DHCPACK:
- return("ACK");
+ type = "ACK";
+ break;
case DHCPNACK:
- return("NACK");
+ type = "NACK";
+ break;
case DHCPRELEASE:
- return("RELEASE");
+ type = "RELEASE";
+ break;
+ case DHCPINFORM:
+ type = "INFORM";
+ break;
+ case DHCPFORCERENEW:
+ type = "FORCERENEW";
+ break;
+ case DHCPLEASEQUERY:
+ type = "LEASEQUERY";
+ break;
+ case DHCPLEASEUNASSIGNED:
+ type = "LEASEUNASSIGNED";
+ break;
+ case DHCPLEASEUNKNOWN:
+ type = "LEASEUNKNOWN";
+ break;
+ case DHCPLEASEACTIVE:
+ type = "LEASEACTIVE";
+ break;
default:
- return("???");
-
+ type = "???";
+ break;
}
+ return(type);
}
/* printDhcpOptions():
printf(" option %3d: ",opt);
optlen = (int)*options++;
if (opt==DHCPOPT_MESSAGETYPE) {
- printf("DHCP%s",DHCPopt(*options++));
- }
- /* Vendor specific information:
- * Note that the data within this option is vendor specific.
- * The RFC2132 says that the encapsulated data with this option
- * SHOULD follow the same format as the outer-layer options, but
- * is not mandatory.
- */
- else if (opt==DHCPOPT_VENDORSPECIFICINFO) {
- int vsopt, vsoptlen;
-
- printf("\n");
- while(*options != 0xff) {
- vsopt = (int)*options++;
- vsoptlen = (int)*options++;
- printf(" vso %3d: ",vsopt);
- if (!printDhcpVSopt(vsopt,vsoptlen,(char *)options)) {
- printf("0x");
- for(i=0;i<vsoptlen;i++)
- printf("%02x",*options++);
- }
- if (*options != 0xff)
- printf("\n");
- }
- options++; /* Skip over the 0xff within this option sub-set */
+ printf("DHCP_%s",DHCPmsgtype(*options++));
}
else if ((opt < DHCPOPT_HOSTNAME) ||
(opt == DHCPOPT_BROADCASTADDRESS) ||
--- /dev/null
+/* dns.c:
+ * This file implements a basic DNS client and some form of a multicast-DNS
+ * reponder. The functionality provides the basic ability to retrieve an IP
+ * address from a domain name.
+ *
+ * Refer to RFC 1035 section 4.1 for the packet format.
+ *
+ * General notice:
+ * This code is part of a boot-monitor package developed as a generic base
+ * platform for embedded system designs. As such, it is likely to be
+ * distributed to various projects beyond the control of the original
+ * author. Please notify the author of any enhancements made or bugs found
+ * so that all may benefit from the changes. In addition, notification back
+ * to the author will allow the new user to pick up changes that may have
+ * been made by other users after this version of the code was distributed.
+ *
+ * Note1: the majority of this code was edited with 4-space tabs.
+ * Note2: as more and more contributions are accepted, the term "author"
+ * is becoming a mis-representation of credit.
+ *
+ * Original author: Ed Sutter
+ * Email: esutter@lucent.com
+ * Phone: 908-582-2351
+ */
+#include "config.h"
+#if INCLUDE_DNS
+#include "endian.h"
+#include "genlib.h"
+#include "stddefs.h"
+#include "ether.h"
+#include "cli.h"
+#include "timer.h"
+
+const char mDNSIp[] = { 224, 0, 0, 251 };
+const char mDNSMac[] = { 0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb };
+
+char * dnsErrStr(int errno);
+
+short DnsPort;
+static unsigned short dnsId;
+static unsigned long dnsIP;
+static char dnsErrno, dnsWaiting, dnsCacheInitialized;
+static struct dnscache hostnames[MAX_CACHED_HOSTNAMES];
+
+/* ip_to_bin...
+ * Essentially identical to IpToBin() in ethernet.c, but without
+ * the error message.
+ */
+int
+ip_to_bin(char *ascii,uchar *binary)
+{
+ int i, digit;
+ char *acpy;
+
+ acpy = ascii;
+ for(i=0;i<4;i++) {
+ digit = (int)strtol(acpy,&acpy,10);
+ if (((i != 3) && (*acpy++ != '.')) ||
+ ((i == 3) && (*acpy != 0)) ||
+ (digit < 0) || (digit > 255)) {
+ return(-1);
+ }
+ binary[i] = (uchar)digit;
+ }
+ return(0);
+}
+
+
+/* getHostAddr():
+ * This function is a simplified version of gethostbyname().
+ * Given a domain name, this function will first query a
+ * locally maintained cache then, if not found there, it will
+ * issue a DNS query to retrieve the hosts IP address.
+ */
+unsigned long
+getHostAddr(char *hostname)
+{
+ short port;
+ struct ip *ipp;
+ struct Udphdr *udpp;
+ struct dnshdr *dnsp;
+ struct elapsed_tmr tmr;
+ struct ether_header *enetp;
+ uchar binenet[8], *enetaddr;
+ unsigned long srvrip, binip;
+ char *pp, *np, *srvrname, *dot;
+ int i, namelen, pktsize, retrytot, ip_len;
+
+ /* First check to see if the incoming host name is simply a
+ * decimal-dot-formatted IP address. If it is, then just
+ * convert it to a 32-bit long and return here...
+ */
+ if (ip_to_bin(hostname,(uchar *)&binip) == 0)
+ return(binip);
+
+ if (!dnsCacheInitialized)
+ dnsCacheInit();
+
+ retrytot = 0;
+ dnsErrno = DNSERR_NULL;
+
+ /* First try to find the hostname in our local cache...
+ */
+ for(i=0;i<MAX_CACHED_HOSTNAMES;i++) {
+ if (strcmp(hostnames[i].name,hostname) == 0)
+ return(hostnames[i].addr);
+ }
+
+ /* If not in the cache, we query the network. First look
+ * for a DNSSRVR defined in the environment. If found, use
+ * it; else, use IP broadcast.
+ */
+
+ /* See if this is a mDNS request...
+ */
+ if (strstr(hostname,".local")) {
+ DnsPort = port = DNSMCAST_PORT;
+ srvrip = htonl(DNSMCAST_IP);
+ memcpy((char *)binenet,(char *)mDNSMac,sizeof(mDNSMac));
+ enetaddr = binenet;
+ }
+ else {
+ port = IPPORT_DNS;
+ DnsPort = port+1;
+ srvrname = getenv("DNSSRVR");
+ if (srvrname == (char *)0)
+ srvrip = 0xffffffff;
+ else {
+ if (IpToBin(srvrname,(uchar *)&srvrip) < 0)
+ return(0);
+ }
+
+ /* Get the ethernet address for the IP:
+ */
+ enetaddr = ArpEther((uchar *)&srvrip,binenet,0);
+ if (!enetaddr) {
+ printf("ARP failed for 0x%x\n",srvrip);
+ return(0);
+ }
+ }
+
+ /* Retrieve an ethernet buffer from the driver and populate the
+ * ethernet level of packet:
+ */
+ enetp = (struct ether_header *) getXmitBuffer();
+ memcpy((char *)&enetp->ether_shost,(char *)BinEnetAddr,6);
+ memcpy((char *)&enetp->ether_dhost,(char *)binenet,6);
+ enetp->ether_type = htons(ETHERTYPE_IP);
+
+ /* Move to the IP portion of the packet and populate it
+ * appropriately:
+ */
+ ipp = (struct ip *) (enetp + 1);
+ ipp->ip_vhl = IP_HDR_VER_LEN;
+ ipp->ip_tos = 0;
+ ipp->ip_id = ipId();
+ ipp->ip_off = 0;
+ ipp->ip_ttl = UDP_TTL;
+ ipp->ip_p = IP_UDP;
+ memcpy((char *)&ipp->ip_src.s_addr,(char *)BinIpAddr,4);
+ memcpy((char *)&ipp->ip_dst.s_addr,(char *)&srvrip,4);
+
+ /* Now UDP...
+ */
+ udpp = (struct Udphdr *) (ipp + 1);
+ udpp->uh_sport = htons(DnsPort);
+ udpp->uh_dport = htons(port);
+
+ /* Finally, the DNS data ...
+ */
+ dnsp = (struct dnshdr *)(udpp+1);
+
+ /* Build the message. This query supports a single internet
+ * host-address question.
+ *
+ * Fixed header...
+ */
+ dnsId = ipId();
+ dnsp->id = htons(dnsId); /* Unique id */
+ dnsp->param = 0; /* Parameter field */
+ dnsp->num_questions = htons(1); /* # of questions */
+ dnsp->num_answers = 0; /* # of answers */
+ dnsp->num_authority = 0; /* # of authority */
+ dnsp->num_additional = 0; /* # of additional */
+
+ /* The formatted name list..
+ * Each name is preceded by a single-byte length, so for our
+ * query, the list is "LNNNLNNNLNNN0", where...
+ * 'L' is the single-byte length of the name.
+ * 'NN..N' is variable-lenght domain.
+ * '0' is the length of the next name in the list; hence,
+ * indicating the end of the list.
+ *
+ * For each '.' (dot) in the hostname, there is a
+ * LNNN pair.
+ */
+ pp = (char *)dnsp->question;
+ np = (char *)hostname;
+ namelen = strlen(hostname);
+ do {
+ dot = strchr(np,'.');
+ if (dot) {
+ *pp++ = dot-np;
+ memcpy(pp,np,dot-np);
+ pp += (dot-np);
+ np = dot + 1;
+ }
+ else {
+ *pp++ = strlen(np);
+ strcpy(pp,np);
+ }
+ } while(dot);
+
+
+ /* Since the size of the name can be arbitrary (not aligned),
+ * we must populate the TYPE and CLASS fields one byte at
+ * a time...
+ */
+ pp += (strlen(np) + 1);
+ *pp++ = 0;
+ *pp++ = 1; /* type = 'A' (host address) */
+ *pp++ = 0;
+ *pp = 1; /* class = 'IN' (the internet) */
+
+ /* Send the DNS query:
+ * Total message size is...
+ * FIXED_HDR_SIZE + NAME_SIZE + TYPE_SIZE + CLASS_SIZE + (NAMELEN_SIZE*2)
+ * where...
+ * FIXED_HDR_SIZE = 12
+ * NAME_SIZE = strlen(hostname) = namelen
+ * TYPE_SIZE = sizeof(short) = 2
+ * CLASS_SIZE = sizeof(short) = 2
+ * NAMELEN_SIZE = sizeof(char) = 1
+ *
+ * There are 2 name lengths. The first one is the size of the host
+ * name we are querying for and the second one is zero (indicating no
+ * more names in the list).
+ * So, the total length of the packet is <namelen + 18>.
+ */
+
+ pktsize = namelen+18;
+ ip_len = sizeof(struct ip) + sizeof(struct Udphdr) + pktsize;
+ ipp->ip_len = htons(ip_len);
+ udpp->uh_ulen = htons((ushort)(ip_len - sizeof(struct ip)));
+
+ ipChksum(ipp); /* Compute csum of ip hdr */
+ udpChksum(ipp); /* Compute UDP checksum */
+
+// printf("Sending DNS rqst id=%04x (%d %d)\n",dnsId,pktsize,ip_len);
+
+ dnsWaiting = 1;
+ sendBuffer(ETHERSIZE + IPSIZE + UDPSIZE + pktsize);
+
+ /* Wait for 3 seconds for a response...
+ */
+ startElapsedTimer(&tmr,3000);
+ while(!msecElapsed(&tmr)) {
+ if (dnsErrno != DNSERR_NULL)
+ break;
+ pollethernet();
+ }
+ if (dnsErrno == DNSERR_COMPLETE) {
+ dnsCacheAdd(hostname,dnsIP);
+ shell_sprintf("DNSIP","%d.%d.%d.%d",
+ IP1(dnsIP),IP2(dnsIP),IP3(dnsIP), IP4(dnsIP));
+ return(dnsIP);
+ }
+ else {
+ if (dnsErrno == DNSERR_NULL)
+ printf("DNS attempt timeout\n");
+ else
+ printf("DNSErr: %s\n",dnsErrStr((int)dnsErrno));
+ setenv("DNSIP",0);
+ }
+ return(0);
+}
+
+/* Note two different processDNS/processMCASTDNS functions...
+ * processDNS() provides the necessary code to deal with responses
+ * that we should expect to get as a result of issuing a dns request.
+ * processMCASTDNS() provides the necessary code to deal with requests
+ * from other machines querying for our hostname/ip info.
+ */
+
+/* processDNS():
+ * This function provides the recieving half of the DNS query above.
+ */
+int
+processDNS(struct ether_header *ehdr,ushort size)
+{
+ int i;
+ char *pp;
+ struct ip *ihdr;
+ struct Udphdr *uhdr;
+ struct dnshdr *dhdr;
+ unsigned short rtype, qtot, atot;
+
+ if (dnsWaiting == 0)
+ return(0);
+
+ dnsWaiting = 0;
+ ihdr = (struct ip *)(ehdr + 1);
+ uhdr = (struct Udphdr *)((char *)ihdr + IP_HLEN(ihdr));
+ dhdr = (struct dnshdr *)(uhdr + 1);
+
+// printf("DNS: (%d)\n",size);
+// printf(" dnsid: %04x\n",htons(dhdr->id));
+// printf(" param: %04x\n",htons(dhdr->param));
+// printf(" quest: %04x\n",htons(dhdr->num_questions));
+// printf(" answe: %04x\n",htons(dhdr->num_answers));
+// printf(" autho: %04x\n",htons(dhdr->num_authority));
+// printf(" addit: %04x\n",htons(dhdr->num_additional));
+// printMem(dhdr->question, size - UDPSIZE - IPSIZE - ETHERSIZE - 12,1);
+
+ /* Verify the DNS response...
+ */
+ if ((htons(dhdr->param) & 0x8000) == 0) { /* response? */
+ dnsErrno = DNSERR_NOTARESPONSE;
+ return(0);
+ }
+ if (htons(dhdr->id) != dnsId) { /* correct id? */
+ dnsErrno = DNSERR_BADRESPID;
+ return(0);
+ }
+ if ((rtype = (htons(dhdr->param) & 0xf)) != 0) { /* response normal? */
+ switch(rtype) {
+ case 1:
+ dnsErrno = DNSERR_FORMATERR;
+ break;
+ case 2:
+ dnsErrno = DNSERR_SRVRFAILURE;
+ break;
+ case 3:
+ dnsErrno = DNSERR_NAMENOEXIST;
+ break;
+ default:
+ dnsErrno = DNSERR_BADRESPTYPE;
+ break;
+ }
+ return(0);
+ }
+ qtot = htons(dhdr->num_questions);
+ if ((atot = htons(dhdr->num_answers)) < 1) { /* answer count >= 1? */
+ dnsErrno = DNSERR_BADANSWRCOUNT;
+ return(0);
+ }
+
+ /* At this point we can assume that the received packet format
+ * is ok. Now we need to parse the packet for the "answer" to
+ * our query...
+ */
+
+ /* Set 'pp' to point to the start of the question list.
+ * There should only be one question in the response.
+ */
+ pp = (char *)&dhdr->question;
+
+ /* Skip over the questions:
+ */
+ for(i=0;i<qtot;i++) {
+ while(*pp) /* while 'L' is nonzero */
+ pp += (*pp + 1);
+ pp += 5; /* Account for last 'L' plus TYPE/CLASS */
+ }
+
+ /* The 'pp' pointer is now pointing a list of resource records that
+ * correspond to the answer list. It is from this list that we
+ * must retrieve the information we are looking for...
+ */
+
+ for(i=0;i<atot;i++) {
+ unsigned short type, len;
+
+ /* The first portion of the record is the resource domain name
+ * and it may be literal string (a 1-octet count followed by
+ * characters that make up the name) or a pointer to a literal
+ * string.
+ */
+ if ((*pp & 0xc0) == 0xc0) { /* compressed? (section 4.1.4 RFC1035) */
+ pp += 2;
+ }
+ else {
+ while(*pp) /* while 'L' is nonzero */
+ pp += (*pp + 1);
+ pp += 1;
+ }
+ memcpy((char *)&type,pp,2);
+ type = htons(type);
+ pp += 8;
+ memcpy((char *)&len,pp,2);
+ len = htons(len);
+ if ((type == TYPE_A) && (len == 4)) {
+ pp += 2;
+ memcpy((char *)&dnsIP,pp,4);
+ dnsIP = htonl(dnsIP);
+ }
+ else
+ pp += (len+2);
+ }
+ dnsErrno = DNSERR_COMPLETE;
+ return(0);
+}
+
+/* processMCASTDNS():
+ * If we're here, then we've received a request over the Multi-cast
+ * DNS address for some host name. If the hostname in this request
+ * matches this board's hostname, then return this board's IP address.
+ * If the shell variable HOSTNAME isn't set, then just return immediately.
+ */
+int
+processMCASTDNS(struct ether_header *ehdr,ushort size)
+{
+ int l1, ql = 0;
+ struct ip *ihdr;
+ char *pp, *myname;
+ struct Udphdr *uhdr;
+ struct dnshdr *dhdr;
+
+ ihdr = (struct ip *)(ehdr + 1);
+ uhdr = (struct Udphdr *)(ihdr + 1);
+ dhdr = (struct dnshdr *)(uhdr + 1);
+
+ // If this message is DNS response, branch to processDNS()...
+ if ((htons(dhdr->param) & 0x8000) == 0x8000) {
+ processDNS(ehdr,size);
+ return(0);
+ }
+
+ if ((myname = getenv("HOSTNAME")) == 0)
+ return(0);
+
+ // If this isn't a normal query type, return...
+ if ((htons(dhdr->param) & 0xf) != 0)
+ return(0);
+
+ // If there isn't exactly 1 question, return...
+ if (htons(dhdr->num_questions) != 1)
+ return(0);
+
+ /* At this point we can assume that the received packet format
+ * is ok. Now we need to parse the packet for the "question"...
+ */
+
+ /* Set 'pp' to point to the start of the question list.
+ */
+ pp = (char *)dhdr->question;
+ l1 = *pp;
+ while(*pp) {
+ ql += *pp;
+ ql++;
+ pp += (*pp + 1);
+ }
+
+ /* If the name in the question matches our hostname, then send a
+ * reply...
+ *
+ * Referring to top of pg 20 of the document
+ * http://files.multicastdns.org/draft-cheshire-dnsext-multicastdns.txt...
+ *
+ * Multicast DNS responses MUST be sent to UDP port 5353 on the
+ * 224.0.0.251 multicast address.
+ */
+ if ((l1 == strlen(myname)) &&
+ (memcmp(myname,(char *)&dhdr->question[1],l1) == 0)) {
+ struct ip *ti, *ri;
+ struct Udphdr *tu, *ru;
+ struct ether_header *te;
+ struct dnshdr *td;
+ short type, class;
+ long ttl;
+ struct elapsed_tmr tmr;
+
+ te = EtherCopy(ehdr);
+ ti = (struct ip *) (te + 1);
+ ri = (struct ip *) (ehdr + 1);
+ ti->ip_vhl = ri->ip_vhl;
+ ti->ip_tos = ri->ip_tos;
+ ti->ip_id = ri->ip_id;
+ ti->ip_off = ri->ip_off;
+ ti->ip_ttl = UDP_TTL;
+ ti->ip_p = IP_UDP;
+ memcpy((char *)&(ti->ip_src.s_addr),(char *)BinIpAddr,
+ sizeof(struct in_addr));
+ memcpy((char *)&(ti->ip_dst.s_addr),(char *)mDNSIp,
+ sizeof(struct in_addr));
+
+ tu = (struct Udphdr *) (ti + 1);
+ ru = (struct Udphdr *) (ri + 1);
+ tu->uh_sport = ru->uh_dport;
+ tu->uh_dport = htons(DNSMCAST_PORT);
+
+ td = (struct dnshdr *)(tu+1);
+
+ /* Flags: */
+ td->id = dhdr->id;
+ td->param = htons(0x8400);
+ td->num_questions = 0;
+ td->num_answers = htons(1);
+ td->num_authority = 0;
+ td->num_additional = 0;
+
+ /* Answers: */
+ pp = (char *)td->question;
+ memcpy(pp,(char *)dhdr->question,ql+1);
+ pp += (ql+1);
+
+ type = htons(TYPE_A);
+ memcpy(pp,(char *)&type,2);
+ pp += 2;
+
+ class = htons(CLASS_IN);
+ memcpy(pp,(char *)&class,2);
+ pp += 2;
+
+ ttl = htonl(900);
+ memcpy(pp,(char *)&ttl,4);
+ pp += 4;
+
+ *pp++ = 0; /* 2-byte length of address */
+ *pp++ = 4;
+ memcpy(pp,(char *)BinIpAddr,4);
+
+ tu->uh_ulen = ecs((UDPSIZE + 27 + ql));
+ ti->ip_len = ecs((UDPSIZE + 27 + ql + sizeof(struct ip)));
+
+ ipChksum(ti); /* Compute checksum of ip hdr */
+ udpChksum(ti); /* Compute UDP checksum */
+
+ /* Delay for some random time between 20-120msec...
+ */
+ startElapsedTimer(&tmr,20 + (BinEnetAddr[5] & 0x3f));
+ while(!msecElapsed(&tmr));
+
+ sendBuffer(ETHERSIZE + IPSIZE + UDPSIZE + 27 + ql);
+ }
+ return(0);
+}
+
+/* DNS Cache utilities:
+ */
+void
+dnsCacheInit(void)
+{
+ int i;
+
+ for(i=0;i<MAX_CACHED_HOSTNAMES;i++) {
+ hostnames[i].idx = 0;
+ hostnames[i].addr = 0;
+ hostnames[i].name[0] = 0;
+ }
+ dnsCacheInitialized = 1;
+}
+
+int
+dnsCacheDump(void)
+{
+ int i, tot;
+ struct dnscache *hnp;
+
+ tot = 0;
+ hnp = hostnames;
+ for(i=0;i<MAX_CACHED_HOSTNAMES;i++,hnp++) {
+ if (hnp->addr) {
+ printf("%3d %30s: %d.%d.%d.%d\n",hnp->idx,hnp->name, IP1(hnp->addr),
+ IP2(hnp->addr), IP3(hnp->addr), IP4(hnp->addr));
+ tot++;
+ }
+ }
+ return(tot);
+}
+
+int
+dnsCacheAdd(char *name, unsigned long inaddr)
+{
+ int i, li, lowest;
+ struct dnscache *hnp;
+ static int idx = 0;
+
+ if (!dnsCacheInitialized)
+ dnsCacheInit();
+
+ /* Validate incoming name size:
+ */
+ if ((strlen(name) >= MAX_HOSTNAME_SIZE) || (inaddr == 0))
+ return(-1);
+
+ lowest = 0x70000000;
+
+ /* First look for an empty slot...
+ */
+ hnp = hostnames;
+ li = MAX_CACHED_HOSTNAMES;
+ for(i=0;i<MAX_CACHED_HOSTNAMES;i++,hnp++) {
+ if (hnp->addr == 0) {
+ strcpy(hnp->name,name);
+ hnp->addr = inaddr;
+ hnp->idx = idx++;
+ return(1);
+ }
+ else {
+ if (hnp->idx < lowest) {
+ lowest = hnp->idx;
+ li = i;
+ }
+ }
+ }
+
+ if (i == MAX_CACHED_HOSTNAMES)
+ return(-1);
+
+ /* If all slots are filled, use the slot that had the
+ * the lowest idx value (this would be the oldest entry)...
+ */
+ hnp = &hostnames[li];
+ strcpy(hnp->name,name);
+ hnp->addr = inaddr;
+ hnp->idx = idx++;
+ return(1);
+}
+
+int
+dnsCacheDelAddr(unsigned long addr)
+{
+ int i;
+
+ if (!dnsCacheInitialized) {
+ dnsCacheInit();
+ return(0);
+ }
+
+ for(i=0;i<MAX_CACHED_HOSTNAMES;i++) {
+ if (hostnames[i].addr == addr) {
+ hostnames[i].name[0] = 0;
+ hostnames[i].addr = 0;
+ return(1);
+ }
+ }
+ return(0);
+}
+
+int
+dnsCacheDelName(char *name)
+{
+ int i;
+
+ if (!dnsCacheInitialized) {
+ dnsCacheInit();
+ return(0);
+ }
+
+ for(i=0;i<MAX_CACHED_HOSTNAMES;i++) {
+ if (strcmp(hostnames[i].name,name) == 0) {
+ hostnames[i].name[0] = 0;
+ hostnames[i].addr = 0;
+ return(1);
+ }
+ }
+ return(0);
+}
+
+struct dnserr dnsErrTbl[] = {
+ { DNSERR_NOSRVR, "no dns server" },
+ { DNSERR_SOCKETFAIL, "socket fail" },
+ { DNSERR_FORMATERR, "format error" },
+ { DNSERR_SRVRFAILURE, "server error" },
+ { DNSERR_NAMENOEXIST, "no name exists" },
+ { DNSERR_BADRESPTYPE, "bad dns server response" },
+ { DNSERR_BADQSTNCOUNT, "bad question count" },
+ { DNSERR_BADANSWRCOUNT, "bad answer count" },
+ { DNSERR_NOTARESPONSE, "replay not a dns response" },
+ { DNSERR_BADRESPID, "bad dns response id" },
+
+ /* Must be last entry in table: */
+ { DNSERR_NULL, "no error" }
+};
+
+char *
+dnsErrStr(int errno)
+{
+ struct dnserr *dep;
+
+ dep = dnsErrTbl;
+ while(dep->errno != DNSERR_NULL) {
+ if (dep->errno == errno)
+ return(dep->errstr);
+ dep++;
+ }
+ return("invalid dns errno");
+}
+
+char *DnsHelp[] = {
+ "DNS Client",
+ "{hostname} | {cmd args}",
+ " Valid cmd values:",
+ " add {name} {ip}",
+ " cache {dump | init}",
+ " mdns {on | off}",
+ " del {name}",
+ 0,
+};
+
+int
+DnsCmd(int argc, char *argv[])
+{
+ unsigned long addr;
+
+ if (argc == 2) {
+ if ((addr = getHostAddr(argv[1])) != 0) {
+ printf("%s: %d.%d.%d.%d\n",argv[1],
+ IP1(dnsIP),IP2(dnsIP),IP3(dnsIP), IP4(dnsIP));
+ }
+ }
+ else if (argc == 3) {
+ if (strcmp(argv[1],"cache") == 0) {
+ if (strcmp(argv[2],"dump") == 0)
+ dnsCacheDump();
+ else if (strcmp(argv[2],"init") == 0)
+ dnsCacheInit();
+ else
+ return(CMD_PARAM_ERROR);
+ }
+ else if (strcmp(argv[1],"mdns") == 0) {
+ extern void enableMulticastReception(void);
+ extern void disableMulticastReception(void);
+
+ if (strcmp(argv[2],"on") == 0)
+ enableMulticastReception();
+ else if (strcmp(argv[2],"off") == 0)
+ disableMulticastReception();
+ else
+ return(CMD_PARAM_ERROR);
+ }
+ else if (strcmp(argv[1],"del") == 0) {
+ dnsCacheDelName(argv[2]);
+ }
+ else
+ return(CMD_PARAM_ERROR);
+ }
+ else if (argc == 4) {
+ if (strcmp(argv[1],"add") == 0) {
+ if (IpToBin(argv[3],(uchar *)&addr) < 0)
+ return(CMD_FAILURE);
+ dnsCacheAdd(argv[2],addr);
+ }
+ else
+ return(CMD_PARAM_ERROR);
+ }
+ else
+ return(CMD_PARAM_ERROR);
+
+ return(CMD_SUCCESS);
+}
+
+#endif
#include "version.h"
#include "boardinfo.h"
#include "ee.h"
+#include "timer.h"
#if INCLUDE_SHELLVARS
setenv("PLATFORM",PLATFORM_NAME);
setenv("MONITORBUILT",monBuilt());
shell_sprintf("MONCOMPTR","0x%lx",(ulong)&moncomptr);
+#if INCLUDE_HWTMR
+ shell_sprintf("TARGETTIMER","0x%x",target_timer);
+ shell_sprintf("TICKSPERMSEC","0x%x",TIMER_TICKS_PER_MSEC);
+#endif
/* Support the ability to have additional target-specific
* shell variables initialized at startup...
"TFS_DEVTOT", "FLASH_DEVTOT", "PROMPT",
"VERSION_MAJ", "VERSION_MIN", "VERSION_TGT",
"MONCMD_SRCIP", "MONCMD_SRCPORT",
+#if INCLUDE_HWTMR
+ "TARGETTIMER", "TICKSPERMSEC",
+#endif
0
};
/* envToExec():
Create a file of "set" commands that can be run to recreate the
current environment.
+ Changed Oct 2008 to eliminate use of getAppRamStart().
*/
int
envToExec(char *filename)
{
- int err, vartot;
+ int err, vartot, size, rc;
char *buf, *bp, *cp;
register struct s_shell *sp;
- buf = bp = (char *)getAppRamStart();
sp = shell_vars;
- vartot = 0;
+ vartot = size = rc = 0;
+ /* First go through the list to see how much space we need
+ * to allocate...
+ */
while(1) {
+ if (validEnvToExecVar(sp->name)) {
+ size += strlen(sp->name) + 6;
+ cp = sp->val;
+ while(*cp) {
+ if (*cp == '$')
+ size++;
+ size++;
+ cp++;
+ }
+ size += 3;
+ vartot++;
+ }
+ if (sp->next != (struct s_shell *)0)
+ sp = sp->next;
+ else
+ break;
+ }
+ if (size == 0)
+ return(0);
+
+ /* Now that we know the space needed (stored in 'size' variable),
+ * allocate it and build the new file in that space, then use tfsadd()
+ * to create the file...
+ */
+ vartot = 0;
+ sp = shell_vars;
+ buf = bp = (char *)env_alloc(size);
+ while(1) {
+ /* Note: if this code changes, then the code above that is used to
+ * allocate the buffer size may also need to change...
+ */
if (validEnvToExecVar(sp->name)) {
bp += sprintf(bp,"set %s \"",sp->name);
cp = sp->val;
err = tfsadd(filename,"envsetup","e",(unsigned char *)buf,strlen(buf));
if (err != TFS_OKAY) {
printf("%s: %s\n",filename,(char *)tfsctrl(TFS_ERRMSG,err,0));
- return(-1);
+ rc = -1;
}
}
- return(0);
+ env_free(buf);
+ return(rc);
}
#endif
#define IP_PUP 12
#define IP_UDP 17
+#define IP1(a) ((a & 0xff000000) >> 24)
+#define IP2(a) ((a & 0xff0000) >> 16)
+#define IP3(a) ((a & 0xff00) >> 8)
+#define IP4(a) (a & 0xff)
+
+#define IP2LONG(a,b,c,d) ((a << 24) | (b << 16) | (c << 8) | d)
+
/************************************************************************
*
* ICMP stuff...
/* DHCP Message types:
*/
-#define DHCPDISCOVER 1
-#define DHCPOFFER 2
-#define DHCPREQUEST 3
-#define DHCPDECLINE 4
-#define DHCPACK 5
-#define DHCPNACK 6
-#define DHCPRELEASE 7
+#define DHCPDISCOVER 1
+#define DHCPOFFER 2
+#define DHCPREQUEST 3
+#define DHCPDECLINE 4
+#define DHCPACK 5
+#define DHCPNACK 6
+#define DHCPRELEASE 7
+#define DHCPINFORM 8
+#define DHCPFORCERENEW 9
+#define DHCPLEASEQUERY 10
+#define DHCPLEASEUNASSIGNED 11
+#define DHCPLEASEUNKNOWN 12
+#define DHCPLEASEACTIVE 13
#define DHCPUNKNOWN 99
/* DHCPState (short) values: (upper bit set = bootp)
* 64 byte question section and assume that no single domain name request
* will exceed that length.
* Note: first byte of domain name is the size.
+ *
+ * For MulticastDNS information I used...
+ * http://files.multicastdns.org/draft-cheshire-dnsext-multicastdns.txt
*/
#define MAX_DOMAIN_NAME_SIZE 63
unsigned char question[MAX_DOMAIN_NAME_SIZE+1];
} __PACKED__ ;
+#define IPPORT_DNS 53
+#define TYPE_A 1
+#define TYPE_CNAME 5
+#define CLASS_IN 1
+
+/* DNS Error codes:
+ */
+#define DNSERR_NULL 0
+#define DNSERR_COMPLETE 1
+#define DNSERR_NOSRVR 2
+#define DNSERR_SOCKETFAIL 3
+#define DNSERR_FORMATERR 4
+#define DNSERR_SRVRFAILURE 5
+#define DNSERR_NAMENOEXIST 6
+#define DNSERR_BADRESPTYPE 7
+#define DNSERR_BADQSTNCOUNT 8
+#define DNSERR_BADANSWRCOUNT 9
+#define DNSERR_NOTARESPONSE 10
+#define DNSERR_BADRESPID 11
+
+#define DNSMCAST_IP IP2LONG(224,0,0,251)
+#define DNSMCAST_PORT 5353
+
+/* DNS Buffer sizes:
+ */
+#define MAX_CACHED_HOSTNAMES 32
+#define MAX_HOSTNAME_SIZE 255
+
+#define DNS_RETRY_MAX 5
+#define DNS_PKTBUF_SIZE 512
+
+struct dnserr {
+ int errno;
+ char *errstr;
+};
+
+struct dnscache {
+ int idx;
+ unsigned long addr;
+ char name[MAX_HOSTNAME_SIZE+1];
+};
+
+extern const char mDNSIp[];
/************************************************************************
*
extern int processDHCP(struct ether_header *,unsigned short);
extern int processRARP(struct ether_header *,unsigned short);
extern int processGDB(struct ether_header *,unsigned short);
+extern int processDNS(struct ether_header *,unsigned short);
+extern int processMCASTDNS(struct ether_header *,unsigned short);
extern int SendICMPUnreachable(struct ether_header *,unsigned char);
extern void enresetmmu(void), enreset(void);
extern void ShowEtherdevStats(void), ShowTftpStats(void), ShowDhcpStats(void);
extern void tftpInit(void);
extern void disableBroadcastReception(void);
extern void enableBroadcastReception(void);
+extern void sendGratuitousArp(void);
+
+extern unsigned long getHostAddr(char *);
+extern int dnsCacheDelName(char *);
+extern void dnsCacheInit(void);
+extern int dnsCacheAdd(char *, unsigned long);
+extern int dnsCacheDelAddr(unsigned long);
+extern short DnsPort;
+
#if INCLUDE_ETHERNET
extern int pollethernet(void);
extern int EthernetStartup(int,int);
#include "ether.h"
#include "monflags.h"
#include "cli.h"
+#include "timer.h"
void ShowEthernetStats(void);
disablePromiscuousReception();
return(CMD_SUCCESS);
case 't':
+ if (EtherIsActive == 0) {
+ printf("Selftest requires active driver to run\n");
+ return(CMD_FAILURE);
+ }
enselftest(1);
return(CMD_SUCCESS);
#if INCLUDE_ETHERVERBOSE
return(eia);
}
+/* EthernetWaitforLinkup():
+ * If the ENET_LINK_IS_UP() macro is defined, then use