diff options
author | RajithaY <rajithax.yerrumsetty@intel.com> | 2017-04-25 03:31:15 -0700 |
---|---|---|
committer | Rajitha Yerrumchetty <rajithax.yerrumsetty@intel.com> | 2017-05-22 06:48:08 +0000 |
commit | bb756eebdac6fd24e8919e2c43f7d2c8c4091f59 (patch) | |
tree | ca11e03542edf2d8f631efeca5e1626d211107e3 /qemu/roms/SLOF/clients/net-snk/app | |
parent | a14b48d18a9ed03ec191cf16b162206998a895ce (diff) |
Adding qemu as a submodule of KVMFORNFV
This Patch includes the changes to add qemu as a submodule to
kvmfornfv repo and make use of the updated latest qemu for the
execution of all testcase
Change-Id: I1280af507a857675c7f81d30c95255635667bdd7
Signed-off-by:RajithaY<rajithax.yerrumsetty@intel.com>
Diffstat (limited to 'qemu/roms/SLOF/clients/net-snk/app')
47 files changed, 0 insertions, 10831 deletions
diff --git a/qemu/roms/SLOF/clients/net-snk/app/Makefile b/qemu/roms/SLOF/clients/net-snk/app/Makefile deleted file mode 100644 index 8b0c08f19..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/Makefile +++ /dev/null @@ -1,51 +0,0 @@ -# ***************************************************************************** -# * Copyright (c) 2004, 2011 IBM Corporation -# * All rights reserved. -# * This program and the accompanying materials -# * are made available under the terms of the BSD License -# * which accompanies this distribution, and is available at -# * http://www.opensource.org/licenses/bsd-license.php -# * -# * Contributors: -# * IBM Corporation - initial implementation -# ****************************************************************************/ - -ifndef TOP -TOP = $(shell while ! test -e make.rules; do cd .. ; done; pwd) -export TOP -endif -include $(TOP)/make.rules - -CFLAGS +=$(ADDCFLAGS) - -OBJS = main.o -OBJDIRS = netlib/netlib.o netapps/netboot.o -OBJDIRS += netapps/ping.o -OBJDIRS += netapps/args.o - -ifeq ($(SNK_BIOSEMU_APPS), 1) -OBJDIRS += biosemu/biosemu_app.o -CFLAGS += -DSNK_BIOSEMU_APPS -endif - -SUBDIRS = $(dir $(OBJDIRS)) - -all: subdirs - $(MAKE) app.o - -subdirs: - for dir in $(SUBDIRS); do \ - $(MAKE) -C $$dir DIRECTORY=$(DIRECTORY)$$dir || exit 1; \ - done - -app.o: $(OBJS) $(OBJDIRS) - $(LD) $(LDFLAGS) $(OBJDIRS) $(OBJS) -o $@ -r - -clean : - $(RM) -f *.o *.a *.i - for dir in $(SUBDIRS); do \ - $(CLEAN) ; \ - $(MAKE) -C $$dir DIRECTORY=$(DIRECTORY)$$dir clean; \ - done - -include $(TOP)/make.depend diff --git a/qemu/roms/SLOF/clients/net-snk/app/biosemu/Makefile b/qemu/roms/SLOF/clients/net-snk/app/biosemu/Makefile deleted file mode 100644 index 3a07ada31..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/biosemu/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -# ***************************************************************************** -# * Copyright (c) 2004, 2008 IBM Corporation -# * All rights reserved. -# * This program and the accompanying materials -# * are made available under the terms of the BSD License -# * which accompanies this distribution, and is available at -# * http://www.opensource.org/licenses/bsd-license.php -# * -# * Contributors: -# * IBM Corporation - initial implementation -# ****************************************************************************/ - -ifndef TOP - TOP = $(shell while ! test -e make.rules; do cd .. ; done; pwd) - export TOP -endif -include $(TOP)/make.rules - -CFLAGS += -I$(ROOTDIR)/other-licence/x86emu -I$(ROOTDIR)/other-licence/x86emu/include - -OBJS = biosemu.o debug.o device.o mem.o io.o interrupt.o vbe.o -LIBX86EMU = $(ROOTDIR)/other-licence/x86emu/libx86emu.a - -.PHONY: $(LIBX86EMU) - -all: biosemu_app.o - -# special rule for libx86emu.a -$(LIBX86EMU): - $(MAKE) -C $(dir $@) - -biosemu_app.o: $(OBJS) $(LIBX86EMU) - $(LD) $(LDFLAGS) $^ -o $@ -r - -clean: - $(RM) -f *.o *.a *.i *.s - -include $(TOP)/make.depend diff --git a/qemu/roms/SLOF/clients/net-snk/app/biosemu/biosemu.c b/qemu/roms/SLOF/clients/net-snk/app/biosemu/biosemu.c deleted file mode 100644 index 82a763acf..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/biosemu/biosemu.c +++ /dev/null @@ -1,345 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2008 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include <stdint.h> -#include <cpu.h> - -#include "debug.h" - -#include <x86emu/x86emu.h> -#include <x86emu/regs.h> -#include <x86emu/prim_ops.h> // for push_word - -#include "biosemu.h" -#include "io.h" -#include "mem.h" -#include "interrupt.h" -#include "device.h" - -#include <rtas.h> - - -static X86EMU_memFuncs my_mem_funcs = { - my_rdb, my_rdw, my_rdl, - my_wrb, my_wrw, my_wrl -}; - -static X86EMU_pioFuncs my_pio_funcs = { - my_inb, my_inw, my_inl, - my_outb, my_outw, my_outl -}; - -void dump(uint8_t * addr, uint32_t len); - -uint32_t -biosemu(char argc, char **argv) -{ - uint8_t *rom_image; - int i = 0; - uint8_t *biosmem; - uint32_t biosmem_size; -#ifdef DEBUG - //debug_flags = DEBUG_PRINT_INT10 | DEBUG_PNP;// | DEBUG_PMM;// | DEBUG_INTR | DEBUG_CHECK_VMEM_ACCESS | DEBUG_MEM | DEBUG_IO;// | DEBUG_TRACE_X86EMU | DEBUG_JMP; -#endif - if (argc < 4) { - printf("Usage %s <vmem_base> <vmem_size> <device_path> [<debug_flags>]\n", argv[0]); - for (i = 0; i < argc; i++) { - printf("argv[%d]: %s\n", i, argv[i]); - } - return -1; - } - // argv[1] is address of virtual BIOS mem... - // argv[2] is the size - biosmem = (uint8_t *) strtoul(argv[1], 0, 16); - biosmem_size = strtoul(argv[2], 0, 16); - if (biosmem_size < MIN_REQUIRED_VMEM_SIZE) { - printf("Error: Not enough virtual memory: %x, required: %x!\n", - biosmem_size, MIN_REQUIRED_VMEM_SIZE); - return -1; - } - // argv[3] is the device to open and use... - if (dev_init(argv[3]) != 0) { - printf("Error initializing device!\n"); - return -1; - } - if (dev_check_exprom() != 0) { - printf("Error: Device Expansion ROM invalid!\n"); - return -1; - } - // argv[4] if set, is additional debug_flags - if (argc >= 5) { - debug_flags |= strtoul(argv[4], 0, 16); - printf("debug_flags: %x\n", debug_flags); - } - rom_image = (uint8_t *) bios_device.img_addr; - DEBUG_PRINTF("executing rom_image from %p\n", rom_image); - DEBUG_PRINTF("biosmem at %p\n", biosmem); - - DEBUG_PRINTF("Image Size: %d\n", bios_device.img_size); - - // in case we jump somewhere unexpected, or execution is finished, - // fill the biosmem with hlt instructions (0xf4) - memset(biosmem, 0xf4, biosmem_size); - - M.mem_base = (long) biosmem; - M.mem_size = biosmem_size; - DEBUG_PRINTF("membase set: %08x, size: %08x\n", (int) M.mem_base, - (int) M.mem_size); - - // copy expansion ROM image to segment OPTION_ROM_CODE_SEGMENT - // NOTE: this sometimes fails, some bytes are 0x00... so we compare - // after copying and do some retries... - uint8_t *mem_img = biosmem + (OPTION_ROM_CODE_SEGMENT << 4); - uint8_t copy_count = 0; - uint8_t cmp_result = 0; - do { -#if 0 - set_ci(); - memcpy(mem_img, rom_image, len); - clr_ci(); -#else - // memcpy fails... try copy byte-by-byte with set/clr_ci - uint8_t c; - for (i = 0; i < bios_device.img_size; i++) { - set_ci(); - c = *(rom_image + i); - if (c != *(rom_image + i)) { - clr_ci(); - printf("Copy failed at: %x/%x\n", i, - bios_device.img_size); - printf("rom_image(%x): %x, mem_img(%x): %x\n", - i, *(rom_image + i), i, *(mem_img + i)); - break; - } - clr_ci(); - *(mem_img + i) = c; - } -#endif - copy_count++; - set_ci(); - cmp_result = memcmp(mem_img, rom_image, bios_device.img_size); - clr_ci(); - } - while ((copy_count < 5) && (cmp_result != 0)); - if (cmp_result != 0) { - printf - ("\nCopying Expansion ROM Image to Memory failed after %d retries! (%x)\n", - copy_count, cmp_result); - dump(rom_image, 0x20); - dump(mem_img, 0x20); - return 0; - } - // setup default Interrupt Vectors - // some expansion ROMs seem to check for these addresses.. - // each handler is only an IRET (0xCF) instruction - // ROM BIOS Int 10 Handler F000:F065 - my_wrl(0x10 * 4, 0xf000f065); - my_wrb(0x000ff065, 0xcf); - // ROM BIOS Int 11 Handler F000:F84D - my_wrl(0x11 * 4, 0xf000f84d); - my_wrb(0x000ff84d, 0xcf); - // ROM BIOS Int 12 Handler F000:F841 - my_wrl(0x12 * 4, 0xf000f841); - my_wrb(0x000ff841, 0xcf); - // ROM BIOS Int 13 Handler F000:EC59 - my_wrl(0x13 * 4, 0xf000ec59); - my_wrb(0x000fec59, 0xcf); - // ROM BIOS Int 14 Handler F000:E739 - my_wrl(0x14 * 4, 0xf000e739); - my_wrb(0x000fe739, 0xcf); - // ROM BIOS Int 15 Handler F000:F859 - my_wrl(0x15 * 4, 0xf000f859); - my_wrb(0x000ff859, 0xcf); - // ROM BIOS Int 16 Handler F000:E82E - my_wrl(0x16 * 4, 0xf000e82e); - my_wrb(0x000fe82e, 0xcf); - // ROM BIOS Int 17 Handler F000:EFD2 - my_wrl(0x17 * 4, 0xf000efd2); - my_wrb(0x000fefd2, 0xcf); - // ROM BIOS Int 1A Handler F000:FE6E - my_wrl(0x1a * 4, 0xf000fe6e); - my_wrb(0x000ffe6e, 0xcf); - - // setup BIOS Data Area (0000:04xx, or 0040:00xx) - // we currently 0 this area, meaning "we dont have - // any hardware" :-) no serial/parallel ports, floppys, ... - memset(biosmem + 0x400, 0x0, 0x100); - - // at offset 13h in BDA is the memory size in kbytes - my_wrw(0x413, biosmem_size / 1024); - // at offset 0eh in BDA is the segment of the Extended BIOS Data Area - // see setup further down - my_wrw(0x40e, INITIAL_EBDA_SEGMENT); - // TODO: setup BDA Video Data ( offset 49h-66h) - // e.g. to store video mode, cursor position, ... - // in int10 (done) handler and VBE Functions - - // TODO: setup BDA Fixed Disk Data - // 74h: Fixed Disk Last Operation Status - // 75h: Fixed Disk Number of Disk Drives - - // TODO: check BDA for further needed data... - - //setup Extended BIOS Data Area - //we currently 0 this area - memset(biosmem + (INITIAL_EBDA_SEGMENT << 4), 0, INITIAL_EBDA_SIZE); - // at offset 0h in EBDA is the size of the EBDA in KB - my_wrw((INITIAL_EBDA_SEGMENT << 4) + 0x0, INITIAL_EBDA_SIZE / 1024); - //TODO: check for further needed EBDA data... - - // setup original ROM BIOS Area (F000:xxxx) - char *date = "06/11/99"; - for (i = 0; date[i]; i++) - my_wrb(0xffff5 + i, date[i]); - // set up eisa ident string - char *ident = "PCI_ISA"; - for (i = 0; ident[i]; i++) - my_wrb(0xfffd9 + i, ident[i]); - - // write system model id for IBM-AT - // according to "Ralf Browns Interrupt List" Int15 AH=C0 Table 515, - // model FC is the original AT and also used in all DOSEMU Versions. - my_wrb(0xFFFFE, 0xfc); - - //setup interrupt handler - X86EMU_intrFuncs intrFuncs[256]; - for (i = 0; i < 256; i++) - intrFuncs[i] = handleInterrupt; - X86EMU_setupIntrFuncs(intrFuncs); - X86EMU_setupPioFuncs(&my_pio_funcs); - X86EMU_setupMemFuncs(&my_mem_funcs); - - // setup the CPU - M.x86.R_AH = bios_device.bus; - M.x86.R_AL = bios_device.devfn; - M.x86.R_DX = 0x80; - M.x86.R_EIP = 3; - M.x86.R_CS = OPTION_ROM_CODE_SEGMENT; - - // Initialize stack and data segment - M.x86.R_SS = STACK_SEGMENT; - M.x86.R_SP = STACK_START_OFFSET; - M.x86.R_DS = DATA_SEGMENT; - - // push a HLT instruction and a pointer to it onto the stack - // any return will pop the pointer and jump to the HLT, thus - // exiting (more or less) cleanly - push_word(0xf4f4); //F4=HLT - push_word(M.x86.R_SS); - push_word(M.x86.R_SP + 2); - - CHECK_DBG(DEBUG_TRACE_X86EMU) { - X86EMU_trace_on(); - } else { -#ifdef DEBUG - M.x86.debug |= DEBUG_SAVE_IP_CS_F; - M.x86.debug |= DEBUG_DECODE_F; - M.x86.debug |= DEBUG_DECODE_NOPRINT_F; -#endif - } - CHECK_DBG(DEBUG_JMP) { - M.x86.debug |= DEBUG_TRACEJMP_F; - M.x86.debug |= DEBUG_TRACEJMP_REGS_F; - M.x86.debug |= DEBUG_TRACECALL_F; - M.x86.debug |= DEBUG_TRACECALL_REGS_F; - } - - DEBUG_PRINTF("Executing Initialization Vector...\n"); - X86EMU_exec(); - DEBUG_PRINTF("done\n"); - - // according to PNP BIOS Spec, Option ROMs should upon exit, return some boot device status in - // AX (see PNP BIOS Spec Section 3.3 - DEBUG_PRINTF_CS_IP("Option ROM Exit Status: %04x\n", M.x86.R_AX); -#ifdef DEBUG - DEBUG_PRINTF("Exit Status Decode:\n"); - if (M.x86.R_AX & 0x100) { // bit 8 - DEBUG_PRINTF - (" IPL Device supporting INT 13h Block Device Format:\n"); - switch (((M.x86.R_AX >> 4) & 0x3)) { // bits 5:4 - case 0: - DEBUG_PRINTF(" No IPL Device attached\n"); - break; - case 1: - DEBUG_PRINTF(" IPL Device status unknown\n"); - break; - case 2: - DEBUG_PRINTF(" IPL Device attached\n"); - break; - case 3: - DEBUG_PRINTF(" IPL Device status RESERVED!!\n"); - break; - } - } - if (M.x86.R_AX & 0x80) { // bit 7 - DEBUG_PRINTF - (" Output Device supporting INT 10h Character Output:\n"); - switch (((M.x86.R_AX >> 4) & 0x3)) { // bits 5:4 - case 0: - DEBUG_PRINTF(" No Display Device attached\n"); - break; - case 1: - DEBUG_PRINTF(" Display Device status unknown\n"); - break; - case 2: - DEBUG_PRINTF(" Display Device attached\n"); - break; - case 3: - DEBUG_PRINTF(" Display Device status RESERVED!!\n"); - break; - } - } - if (M.x86.R_AX & 0x40) { // bit 6 - DEBUG_PRINTF - (" Input Device supporting INT 9h Character Input:\n"); - switch (((M.x86.R_AX >> 4) & 0x3)) { // bits 5:4 - case 0: - DEBUG_PRINTF(" No Input Device attached\n"); - break; - case 1: - DEBUG_PRINTF(" Input Device status unknown\n"); - break; - case 2: - DEBUG_PRINTF(" Input Device attached\n"); - break; - case 3: - DEBUG_PRINTF(" Input Device status RESERVED!!\n"); - break; - } - } -#endif - // check wether the stack is "clean" i.e. containing the HLT instruction - // we pushed before executing, and pointing to the original stack address... - // indicating that the initialization probably was successful - if ((pop_word() == 0xf4f4) && (M.x86.R_SS == STACK_SEGMENT) - && (M.x86.R_SP == STACK_START_OFFSET)) { - DEBUG_PRINTF("Stack is clean, initialization successful!\n"); - } else { - DEBUG_PRINTF - ("Stack unclean, initialization probably NOT COMPLETE!!!\n"); - DEBUG_PRINTF("SS:SP = %04x:%04x, expected: %04x:%04x\n", - M.x86.R_SS, M.x86.R_SP, STACK_SEGMENT, - STACK_START_OFFSET); - } - - - // TODO: according to the BIOS Boot Spec initializations may be ended using INT18h and setting - // the status. - // We need to implement INT18 accordingly, pseudo code is in specsbbs101.pdf page 30 - // (also for Int19) - return 0; -} diff --git a/qemu/roms/SLOF/clients/net-snk/app/biosemu/biosemu.h b/qemu/roms/SLOF/clients/net-snk/app/biosemu/biosemu.h deleted file mode 100644 index 28b7ab881..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/biosemu/biosemu.h +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2008 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -#ifndef _BIOSEMU_BIOSEMU_H_ -#define _BIOSEMU_BIOSEMU_H_ - -#define MIN_REQUIRED_VMEM_SIZE 0x100000 // 1MB - -//define default segments for different components -#define STACK_SEGMENT 0x1000 //1000:xxxx -#define STACK_START_OFFSET 0xfffe - -#define DATA_SEGMENT 0x2000 -#define VBE_SEGMENT 0x3000 - -#define PMM_CONV_SEGMENT 0x4000 // 4000:xxxx is PMM conventional memory area, extended memory area - // will be anything beyound MIN_REQUIRED_MEMORY_SIZE -#define PNP_DATA_SEGMENT 0x5000 - -#define OPTION_ROM_CODE_SEGMENT 0xc000 - -#define BIOS_DATA_SEGMENT 0xF000 -// both EBDA values are _initial_ values, they may (and will be) changed at runtime by option ROMs!! -#define INITIAL_EBDA_SEGMENT 0xF600 // segment of the Extended BIOS Data Area -#define INITIAL_EBDA_SIZE 0x400 // size of the EBDA (at least 1KB!! since size is stored in KB!) - -#define PMM_INT_NUM 0xFC // we misuse INT FC for PMM functionality, at the PMM Entry Point - // Address, there will only be a call to this INT and a RETF -#define PNP_INT_NUM 0xFD - -uint32_t biosemu(char argc, char **argv); - -#endif diff --git a/qemu/roms/SLOF/clients/net-snk/app/biosemu/debug.c b/qemu/roms/SLOF/clients/net-snk/app/biosemu/debug.c deleted file mode 100644 index 2fce24497..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/biosemu/debug.c +++ /dev/null @@ -1,55 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2008 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -#include <cpu.h> - -#include "debug.h" - -uint32_t debug_flags = 0; - -void -dump(uint8_t * addr, uint32_t len) -{ - printf("\n\r%s(%p, %x):\n", __FUNCTION__, addr, len); - while (len) { - unsigned int tmpCnt = len; - unsigned char x; - if (tmpCnt > 8) - tmpCnt = 8; - printf("\n\r%p: ", addr); - // print hex - while (tmpCnt--) { - set_ci(); - x = *addr++; - clr_ci(); - printf("%02x ", x); - } - tmpCnt = len; - if (tmpCnt > 8) - tmpCnt = 8; - len -= tmpCnt; - //reset addr ptr to print ascii - addr = addr - tmpCnt; - // print ascii - while (tmpCnt--) { - set_ci(); - x = *addr++; - clr_ci(); - if ((x < 32) || (x >= 127)) { - //non-printable char - x = '.'; - } - printf("%c", x); - } - } - printf("\n"); -} diff --git a/qemu/roms/SLOF/clients/net-snk/app/biosemu/debug.h b/qemu/roms/SLOF/clients/net-snk/app/biosemu/debug.h deleted file mode 100644 index 46a026ae6..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/biosemu/debug.h +++ /dev/null @@ -1,74 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2008 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ -#ifndef _BIOSEMU_DEBUG_H_ -#define _BIOSEMU_DEBUG_H_ - -#include <stdio.h> -#include <stdint.h> - -extern uint32_t debug_flags; -// from x86emu...needed for debugging -extern void x86emu_dump_xregs(void); - -#define DEBUG_IO 0x1 -#define DEBUG_MEM 0x2 -// set this to print messages for certain virtual memory accesses (Interrupt Vectors, ...) -#define DEBUG_CHECK_VMEM_ACCESS 0x4 -#define DEBUG_INTR 0x8 -#define DEBUG_PRINT_INT10 0x10 // set to have the INT10 routine print characters -#define DEBUG_VBE 0x20 -#define DEBUG_PMM 0x40 -#define DEBUG_DISK 0x80 -#define DEBUG_PNP 0x100 - -#define DEBUG_TRACE_X86EMU 0x1000 -// set to enable tracing of JMPs in x86emu -#define DEBUG_JMP 0x2000 - -//#define DEBUG -#ifdef DEBUG - -#define CHECK_DBG(_flag) if (debug_flags & _flag) - -#define DEBUG_PRINTF(_x...) printf(_x); -// prints the CS:IP before the printout, NOTE: actually its CS:IP of the _next_ instruction -// to be executed, since the x86emu advances CS:IP _before_ actually executing an instruction -#define DEBUG_PRINTF_CS_IP(_x...) DEBUG_PRINTF("%x:%x ", M.x86.R_CS, M.x86.R_IP); DEBUG_PRINTF(_x); - -#define DEBUG_PRINTF_IO(_x...) CHECK_DBG(DEBUG_IO) { DEBUG_PRINTF_CS_IP(_x) } -#define DEBUG_PRINTF_MEM(_x...) CHECK_DBG(DEBUG_MEM) { DEBUG_PRINTF_CS_IP(_x) } -#define DEBUG_PRINTF_INTR(_x...) CHECK_DBG(DEBUG_INTR) { DEBUG_PRINTF_CS_IP(_x) } -#define DEBUG_PRINTF_VBE(_x...) CHECK_DBG(DEBUG_VBE) { DEBUG_PRINTF_CS_IP(_x) } -#define DEBUG_PRINTF_PMM(_x...) CHECK_DBG(DEBUG_PMM) { DEBUG_PRINTF_CS_IP(_x) } -#define DEBUG_PRINTF_DISK(_x...) CHECK_DBG(DEBUG_DISK) { DEBUG_PRINTF_CS_IP(_x) } -#define DEBUG_PRINTF_PNP(_x...) CHECK_DBG(DEBUG_PNP) { DEBUG_PRINTF_CS_IP(_x) } - -#else - -#define CHECK_DBG(_flag) if (0) - -#define DEBUG_PRINTF(_x...) -#define DEBUG_PRINTF_CS_IP(_x...) - -#define DEBUG_PRINTF_IO(_x...) -#define DEBUG_PRINTF_MEM(_x...) -#define DEBUG_PRINTF_INTR(_x...) -#define DEBUG_PRINTF_VBE(_x...) -#define DEBUG_PRINTF_PMM(_x...) -#define DEBUG_PRINTF_DISK(_x...) -#define DEBUG_PRINTF_PNP(_x...) - -#endif //DEBUG - -void dump(uint8_t * addr, uint32_t len); - -#endif diff --git a/qemu/roms/SLOF/clients/net-snk/app/biosemu/device.c b/qemu/roms/SLOF/clients/net-snk/app/biosemu/device.c deleted file mode 100644 index 514b87e62..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/biosemu/device.c +++ /dev/null @@ -1,324 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2008 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - - -#include "device.h" -#include "rtas.h" -#include <stdio.h> -#include <string.h> -#include <of.h> // use translate_address_dev and get_puid from net-snk -#include "debug.h" - -typedef struct { - uint8_t info; - uint8_t bus; - uint8_t devfn; - uint8_t cfg_space_offset; - uint64_t address; - uint64_t size; -} __attribute__ ((__packed__)) assigned_address_t; - - -// scan all adresses assigned to the device ("assigned-addresses" and "reg") -// store in translate_address_array for faster translation using dev_translate_address -static void -dev_get_addr_info(void) -{ - // get bus/dev/fn from assigned-addresses - int32_t len; - //max. 6 BARs and 1 Exp.ROM plus CfgSpace and 3 legacy ranges - assigned_address_t buf[11]; - len = - of_getprop(bios_device.phandle, "assigned-addresses", buf, - sizeof(buf)); - bios_device.bus = buf[0].bus; - bios_device.devfn = buf[0].devfn; - DEBUG_PRINTF("bus: %x, devfn: %x\n", bios_device.bus, - bios_device.devfn); - //store address translations for all assigned-addresses and regs in - //translate_address_array for faster translation later on... - int i = 0; - // index to insert data into translate_address_array - int taa_index = 0; - uint64_t address_offset; - for (i = 0; i < (len / sizeof(assigned_address_t)); i++, taa_index++) { - //copy all info stored in assigned-addresses - translate_address_array[taa_index].info = buf[i].info; - translate_address_array[taa_index].bus = buf[i].bus; - translate_address_array[taa_index].devfn = buf[i].devfn; - translate_address_array[taa_index].cfg_space_offset = - buf[i].cfg_space_offset; - translate_address_array[taa_index].address = buf[i].address; - translate_address_array[taa_index].size = buf[i].size; - // translate first address and store it as address_offset - address_offset = buf[i].address; - translate_address_dev(&address_offset, bios_device.phandle); - translate_address_array[taa_index].address_offset = - address_offset - buf[i].address; - } - //get "reg" property - len = of_getprop(bios_device.phandle, "reg", buf, sizeof(buf)); - for (i = 0; i < (len / sizeof(assigned_address_t)); i++) { - if ((buf[i].size == 0) || (buf[i].cfg_space_offset != 0)) { - // we dont care for ranges with size 0 and - // BARs and Expansion ROM must be in assigned-addresses... so in reg - // we only look for those without config space offset set... - // i.e. the legacy ranges - continue; - } - //copy all info stored in assigned-addresses - translate_address_array[taa_index].info = buf[i].info; - translate_address_array[taa_index].bus = buf[i].bus; - translate_address_array[taa_index].devfn = buf[i].devfn; - translate_address_array[taa_index].cfg_space_offset = - buf[i].cfg_space_offset; - translate_address_array[taa_index].address = buf[i].address; - translate_address_array[taa_index].size = buf[i].size; - // translate first address and store it as address_offset - address_offset = buf[i].address; - translate_address_dev(&address_offset, bios_device.phandle); - translate_address_array[taa_index].address_offset = - address_offset - buf[i].address; - taa_index++; - } - // store last entry index of translate_address_array - taa_last_entry = taa_index - 1; -#ifdef DEBUG - //dump translate_address_array - printf("translate_address_array: \n"); - translate_address_t ta; - for (i = 0; i <= taa_last_entry; i++) { - ta = translate_address_array[i]; - printf - ("%d: %02x%02x%02x%02x\n\taddr: %016llx\n\toffs: %016llx\n\tsize: %016llx\n", - i, ta.info, ta.bus, ta.devfn, ta.cfg_space_offset, - ta.address, ta.address_offset, ta.size); - } -#endif -} - -// to simulate accesses to legacy VGA Memory (0xA0000-0xBFFFF) -// we look for the first prefetchable memory BAR, if no prefetchable BAR found, -// we use the first memory BAR -// dev_translate_addr will translate accesses to the legacy VGA Memory into the found vmem BAR -static void -dev_find_vmem_addr(void) -{ - int i = 0; - translate_address_t ta; - int8_t tai_np = -1, tai_p = -1; // translate_address_array index for non-prefetchable and prefetchable memory - //search backwards to find first entry - for (i = taa_last_entry; i >= 0; i--) { - ta = translate_address_array[i]; - if ((ta.cfg_space_offset >= 0x10) - && (ta.cfg_space_offset <= 0x24)) { - //only BARs - if ((ta.info & 0x03) >= 0x02) { - //32/64bit memory - tai_np = i; - if ((ta.info & 0x40) != 0) { - // prefetchable - tai_p = i; - } - } - } - } - if (tai_p != -1) { - ta = translate_address_array[tai_p]; - bios_device.vmem_addr = ta.address; - bios_device.vmem_size = ta.size; - DEBUG_PRINTF - ("%s: Found prefetchable Virtual Legacy Memory BAR: %llx, size: %llx\n", - __FUNCTION__, bios_device.vmem_addr, - bios_device.vmem_size); - } else if (tai_np != -1) { - ta = translate_address_array[tai_np]; - bios_device.vmem_addr = ta.address; - bios_device.vmem_size = ta.size; - DEBUG_PRINTF - ("%s: Found non-prefetchable Virtual Legacy Memory BAR: %llx, size: %llx", - __FUNCTION__, bios_device.vmem_addr, - bios_device.vmem_size); - } - // disable vmem - //bios_device.vmem_size = 0; -} - -static void -dev_get_puid(void) -{ - // get puid - bios_device.puid = get_puid(bios_device.phandle); - DEBUG_PRINTF("puid: 0x%llx\n", bios_device.puid); -} - -static void -dev_get_device_vendor_id(void) -{ - uint32_t pci_config_0 = - rtas_pci_config_read(bios_device.puid, 4, bios_device.bus, - bios_device.devfn, 0x0); - bios_device.pci_device_id = - (uint16_t) ((pci_config_0 & 0xFFFF0000) >> 16); - bios_device.pci_vendor_id = (uint16_t) (pci_config_0 & 0x0000FFFF); - DEBUG_PRINTF("PCI Device ID: %04x, PCI Vendor ID: %x\n", - bios_device.pci_device_id, bios_device.pci_vendor_id); -} - -/* check, wether the device has a valid Expansion ROM, also search the PCI Data Structure and - * any Expansion ROM Header (using dev_scan_exp_header()) for needed information */ -uint8_t -dev_check_exprom(void) -{ - int i = 0; - translate_address_t ta; - uint64_t rom_base_addr = 0; - uint16_t pci_ds_offset; - pci_data_struct_t pci_ds; - // check for ExpROM Address (Offset 30) in taa - for (i = 0; i <= taa_last_entry; i++) { - ta = translate_address_array[i]; - if (ta.cfg_space_offset == 0x30) { - rom_base_addr = ta.address + ta.address_offset; //translated address - break; - } - } - // in the ROM there could be multiple Expansion ROM Images... start searching - // them for a x86 image - do { - if (rom_base_addr == 0) { - printf("Error: no Expansion ROM address found!\n"); - return -1; - } - set_ci(); - uint16_t rom_signature = *((uint16_t *) rom_base_addr); - clr_ci(); - if (rom_signature != 0x55aa) { - printf - ("Error: invalid Expansion ROM signature: %02x!\n", - *((uint16_t *) rom_base_addr)); - return -1; - } - set_ci(); - // at offset 0x18 is the (16bit little-endian) pointer to the PCI Data Structure - pci_ds_offset = in16le((void *) (rom_base_addr + 0x18)); - //copy the PCI Data Structure - memcpy(&pci_ds, (void *) (rom_base_addr + pci_ds_offset), - sizeof(pci_ds)); - clr_ci(); -#ifdef DEBUG - DEBUG_PRINTF("PCI Data Structure @%llx:\n", - rom_base_addr + pci_ds_offset); - dump((void *) &pci_ds, sizeof(pci_ds)); -#endif - if (strncmp((const char *) pci_ds.signature, "PCIR", 4) != 0) { - printf("Invalid PCI Data Structure found!\n"); - break; - } - //little-endian conversion - pci_ds.vendor_id = in16le(&pci_ds.vendor_id); - pci_ds.device_id = in16le(&pci_ds.device_id); - pci_ds.img_length = in16le(&pci_ds.img_length); - pci_ds.pci_ds_length = in16le(&pci_ds.pci_ds_length); - if (pci_ds.vendor_id != bios_device.pci_vendor_id) { - printf - ("Image has invalid Vendor ID: %04x, expected: %04x\n", - pci_ds.vendor_id, bios_device.pci_vendor_id); - break; - } - if (pci_ds.device_id != bios_device.pci_device_id) { - printf - ("Image has invalid Device ID: %04x, expected: %04x\n", - pci_ds.device_id, bios_device.pci_device_id); - break; - } - //DEBUG_PRINTF("Image Length: %d\n", pci_ds.img_length * 512); - //DEBUG_PRINTF("Image Code Type: %d\n", pci_ds.code_type); - if (pci_ds.code_type == 0) { - //x86 image - //store image address and image length in bios_device struct - bios_device.img_addr = rom_base_addr; - bios_device.img_size = pci_ds.img_length * 512; - // we found the image, exit the loop - break; - } else { - // no x86 image, check next image (if any) - rom_base_addr += pci_ds.img_length * 512; - } - if ((pci_ds.indicator & 0x80) == 0x80) { - //last image found, exit the loop - DEBUG_PRINTF("Last PCI Expansion ROM Image found.\n"); - break; - } - } - while (bios_device.img_addr == 0); - // in case we did not find a valid x86 Expansion ROM Image - if (bios_device.img_addr == 0) { - printf("Error: no valid x86 Expansion ROM Image found!\n"); - return -1; - } - return 0; -} - -uint8_t -dev_init(char *device_name) -{ - uint8_t rval = 0; - //init bios_device struct - DEBUG_PRINTF("%s(%s)\n", __FUNCTION__, device_name); - memset(&bios_device, 0, sizeof(bios_device)); - bios_device.ihandle = of_open(device_name); - if (bios_device.ihandle == 0) { - DEBUG_PRINTF("%s is no valid device!\n", device_name); - return -1; - } - bios_device.phandle = of_finddevice(device_name); - dev_get_addr_info(); - dev_find_vmem_addr(); - dev_get_puid(); - dev_get_device_vendor_id(); - return rval; -} - -// translate address function using translate_address_array assembled -// by dev_get_addr_info... MUCH faster than calling translate_address_dev -// and accessing client interface for every translation... -// returns: 0 if addr not found in translate_address_array, 1 if found. -uint8_t -dev_translate_address(uint64_t * addr) -{ - int i = 0; - translate_address_t ta; - //check if it is an access to legacy VGA Mem... if it is, map the address - //to the vmem BAR and then translate it... - // (translation info provided by Ben Herrenschmidt) - // NOTE: the translation seems to only work for NVIDIA cards... but it is needed - // to make some NVIDIA cards work at all... - if ((bios_device.vmem_size > 0) - && ((*addr >= 0xA0000) && (*addr < 0xB8000))) { - *addr = (*addr - 0xA0000) * 4 + 2 + bios_device.vmem_addr; - } - if ((bios_device.vmem_size > 0) - && ((*addr >= 0xB8000) && (*addr < 0xC0000))) { - uint8_t shift = *addr & 1; - *addr &= 0xfffffffe; - *addr = (*addr - 0xB8000) * 4 + shift + bios_device.vmem_addr; - } - for (i = 0; i <= taa_last_entry; i++) { - ta = translate_address_array[i]; - if ((*addr >= ta.address) && (*addr <= (ta.address + ta.size))) { - *addr += ta.address_offset; - return 1; - } - } - return 0; -} diff --git a/qemu/roms/SLOF/clients/net-snk/app/biosemu/device.h b/qemu/roms/SLOF/clients/net-snk/app/biosemu/device.h deleted file mode 100644 index 425dd3caf..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/biosemu/device.h +++ /dev/null @@ -1,157 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2008 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -#ifndef DEVICE_LIB_H -#define DEVICE_LIB_H - -#include <stdint.h> -#include <cpu.h> -#include "of.h" -#include <stdio.h> - -// a Expansion Header Struct as defined in Plug and Play BIOS Spec 1.0a Chapter 3.2 -typedef struct { - char signature[4]; // signature - uint8_t structure_revision; - uint8_t length; // in 16 byte blocks - uint16_t next_header_offset; // offset to next Expansion Header as 16bit little-endian value, as offset from the start of the Expansion ROM - uint8_t reserved; - uint8_t checksum; // the sum of all bytes of the Expansion Header must be 0 - uint32_t device_id; // PnP Device ID as 32bit little-endian value - uint16_t p_manufacturer_string; //16bit little-endian offset from start of Expansion ROM - uint16_t p_product_string; //16bit little-endian offset from start of Expansion ROM - uint8_t device_base_type; - uint8_t device_sub_type; - uint8_t device_if_type; - uint8_t device_indicators; - // the following vectors are all 16bit little-endian offsets from start of Expansion ROM - uint16_t bcv; // Boot Connection Vector - uint16_t dv; // Disconnect Vector - uint16_t bev; // Bootstrap Entry Vector - uint16_t reserved_2; - uint16_t sriv; // Static Resource Information Vector -} __attribute__ ((__packed__)) exp_header_struct_t; - -// a PCI Data Struct as defined in PCI 2.3 Spec Chapter 6.3.1.2 -typedef struct { - uint8_t signature[4]; // signature, the String "PCIR" - uint16_t vendor_id; - uint16_t device_id; - uint16_t reserved; - uint16_t pci_ds_length; // PCI Data Structure Length, 16bit little-endian value - uint8_t pci_ds_revision; - uint8_t class_code[3]; - uint16_t img_length; // length of the Exp.ROM Image, 16bit little-endian value in 512 bytes - uint16_t img_revision; - uint8_t code_type; - uint8_t indicator; - uint16_t reserved_2; -} __attribute__ ((__packed__)) pci_data_struct_t; - -typedef struct { - uint8_t bus; - uint8_t devfn; - uint64_t puid; - phandle_t phandle; - ihandle_t ihandle; - // store the address of the BAR that is used to simulate - // legacy VGA memory accesses - uint64_t vmem_addr; - uint64_t vmem_size; - // used to buffer I/O Accesses, that do not access the I/O Range of the device... - // 64k might be overkill, but we can buffer all I/O accesses... - uint8_t io_buffer[64 * 1024]; - uint16_t pci_vendor_id; - uint16_t pci_device_id; - // translated address of the "PC-Compatible" Expansion ROM Image for this device - uint64_t img_addr; - uint32_t img_size; // size of the Expansion ROM Image (read from the PCI Data Structure) -} device_t; - -typedef struct { - uint8_t info; - uint8_t bus; - uint8_t devfn; - uint8_t cfg_space_offset; - uint64_t address; - uint64_t address_offset; - uint64_t size; -} __attribute__ ((__packed__)) translate_address_t; - -// array to store address translations for this -// device. Needed for faster address translation, so -// not every I/O or Memory Access needs to call translate_address_dev -// and access the device tree -// 6 BARs, 1 Exp. ROM, 1 Cfg.Space, and 3 Legacy -// translations are supported... this should be enough for -// most devices... for VGA it is enough anyways... -translate_address_t translate_address_array[11]; - -// index of last translate_address_array entry -// set by get_dev_addr_info function -uint8_t taa_last_entry; - -device_t bios_device; - -uint8_t dev_init(char *device_name); -// NOTE: for dev_check_exprom to work, dev_init MUST be called first! -uint8_t dev_check_exprom(void); - -uint8_t dev_translate_address(uint64_t * addr); - -/* endianness swap functions for 16 and 32 bit words - * copied from axon_pciconfig.c - */ -static inline void -out32le(void *addr, uint32_t val) -{ - asm volatile ("stwbrx %0, 0, %1"::"r" (val), "r"(addr)); -} - -static inline uint32_t -in32le(void *addr) -{ - uint32_t val; - const uint32_t *zaddr = addr; - asm volatile ("lwbrx %0, %y1" : "=r"(val) : "Z"(*zaddr)); - return val; -} - -static inline void -out16le(void *addr, uint16_t val) -{ - asm volatile ("sthbrx %0, 0, %1"::"r" (val), "r"(addr)); -} - -static inline uint16_t -in16le(void *addr) -{ - uint16_t val; - const uint16_t *zaddr = addr; - asm volatile ("lhbrx %0, %y1" : "=r"(val) : "Z"(*zaddr)); - return val; -} - -/* debug function, dumps HID1 and HID4 to detect wether caches are on/off */ -static inline void -dumpHID(void) -{ - uint64_t hid; - //HID1 = 1009 - __asm__ __volatile__("mfspr %0, 1009":"=r"(hid)); - printf("HID1: %016llx\n", hid); - //HID4 = 1012 - __asm__ __volatile__("mfspr %0, 1012":"=r"(hid)); - printf("HID4: %016llx\n", hid); -} - -#endif diff --git a/qemu/roms/SLOF/clients/net-snk/app/biosemu/interrupt.c b/qemu/roms/SLOF/clients/net-snk/app/biosemu/interrupt.c deleted file mode 100644 index ac3f5b430..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/biosemu/interrupt.c +++ /dev/null @@ -1,606 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2008 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -#include <stdio.h> - -#include <rtas.h> - -#include "biosemu.h" -#include "mem.h" -#include "device.h" -#include "debug.h" -#include "interrupt.h" - -#include <x86emu/x86emu.h> -#include <x86emu/prim_ops.h> - - - -//setup to run the code at the address, that the Interrupt Vector points to... -static void -setupInt(int intNum) -{ - DEBUG_PRINTF_INTR("%s(%x): executing interrupt handler @%08x\n", - __FUNCTION__, intNum, my_rdl(intNum * 4)); - // push current R_FLG... will be popped by IRET - push_word((u16) M.x86.R_FLG); - CLEAR_FLAG(F_IF); - CLEAR_FLAG(F_TF); - // push current CS:IP to the stack, will be popped by IRET - push_word(M.x86.R_CS); - push_word(M.x86.R_IP); - // set CS:IP to the interrupt handler address... so the next executed instruction will - // be the interrupt handler - M.x86.R_CS = my_rdw(intNum * 4 + 2); - M.x86.R_IP = my_rdw(intNum * 4); -} - -// handle int10 (VGA BIOS Interrupt) -static void -handleInt10(void) -{ - // the data for INT10 is stored in BDA (0000:0400h) offset 49h-66h - // function number in AH - //DEBUG_PRINTF_CS_IP("%s:\n", __FUNCTION__); - //x86emu_dump_xregs(); - //if ((M.x86.R_IP == 0x32c2) && (M.x86.R_SI == 0x1ce2)){ - //X86EMU_trace_on(); - //M.x86.debug &= ~DEBUG_DECODE_NOPRINT_F; - //} - switch (M.x86.R_AH) { - case 0x00: - // set video mode - // BDA offset 49h is current video mode - my_wrb(0x449, M.x86.R_AL); - if (M.x86.R_AL > 7) - M.x86.R_AL = 0x20; - else if (M.x86.R_AL == 6) - M.x86.R_AL = 0x3f; - else - M.x86.R_AL = 0x30; - break; - case 0x01: - // set cursor shape - // ignore - break; - case 0x02: - // set cursor position - // BH: pagenumber, DX: cursor_pos (DH:row, DL:col) - // BDA offset 50h-60h are 8 cursor position words for - // eight possible video pages - my_wrw(0x450 + (M.x86.R_BH * 2), M.x86.R_DX); - break; - case 0x03: - //get cursor position - // BH: pagenumber - // BDA offset 50h-60h are 8 cursor position words for - // eight possible video pages - M.x86.R_AX = 0; - M.x86.R_CH = 0; // start scan line ??? - M.x86.R_CL = 0; // end scan line ??? - M.x86.R_DX = my_rdw(0x450 + (M.x86.R_BH * 2)); - break; - case 0x05: - // set active page - // BDA offset 62h is current page number - my_wrb(0x462, M.x86.R_AL); - break; - case 0x06: - //scroll up windows - break; - case 0x07: - //scroll down windows - break; - case 0x08: - //read character and attribute at position - M.x86.R_AH = 0x07; // white-on-black - M.x86.R_AL = 0x20; // a space... - break; - case 0x09: - // write character and attribute - //AL: char, BH: page number, BL: attribute, CX: number of times to write - //BDA offset 62h is current page number - CHECK_DBG(DEBUG_PRINT_INT10) { - uint32_t i = 0; - if (M.x86.R_BH == my_rdb(0x462)) { - for (i = 0; i < M.x86.R_CX; i++) - printf("%c", M.x86.R_AL); - } - } - break; - case 0x0a: - // write character - //AL: char, BH: page number, BL: attribute, CX: number of times to write - //BDA offset 62h is current page number - CHECK_DBG(DEBUG_PRINT_INT10) { - uint32_t i = 0; - if (M.x86.R_BH == my_rdb(0x462)) { - for (i = 0; i < M.x86.R_CX; i++) - printf("%c", M.x86.R_AL); - } - } - break; - case 0x0e: - // teletype output: write character and advance cursor... - //AL: char, BH: page number, BL: attribute - //BDA offset 62h is current page number - CHECK_DBG(DEBUG_PRINT_INT10) { - // we ignore the pagenumber on this call... - //if (M.x86.R_BH == my_rdb(0x462)) - { - printf("%c", M.x86.R_AL); - // for debugging, to read all lines - //if (M.x86.R_AL == 0xd) // carriage return - // printf("\n"); - } - } - break; - case 0x0f: - // get video mode - // BDA offset 49h is current video mode - // BDA offset 62h is current page number - // BDA offset 4ah is columns on screen - M.x86.R_AH = 80; //number of character columns... we hardcode it to 80 - M.x86.R_AL = my_rdb(0x449); - M.x86.R_BH = my_rdb(0x462); - break; - default: - printf("%s(): unknown function (%x) for int10 handler.\n", - __FUNCTION__, M.x86.R_AH); - DEBUG_PRINTF_INTR("AX=%04x BX=%04x CX=%04x DX=%04x\n", - M.x86.R_AX, M.x86.R_BX, M.x86.R_CX, - M.x86.R_DX); - HALT_SYS(); - break; - } -} - -// this table translates ASCII chars into their XT scan codes: -static uint8_t keycode_table[256] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0 - 7 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 8 - 15 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 16 - 23 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 24 - 31 - 0x39, 0x02, 0x28, 0x04, 0x05, 0x06, 0x08, 0x28, // 32 - 39 - 0x0a, 0x0b, 0x09, 0x2b, 0x33, 0x0d, 0x34, 0x35, // 40 - 47 - 0x0b, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // 48 - 55 - 0x09, 0x0a, 0x27, 0x27, 0x33, 0x2b, 0x34, 0x35, // 56 - 63 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 64 - 71 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 72 - 79 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 80 - 87 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 88 - 95 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 96 - 103 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 104 - 111 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 112 - 119 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 120 - 127 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ... - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -static void -translate_keycode(uint64_t * keycode) -{ - uint8_t scan_code = 0; - uint8_t char_code = 0; - if (*keycode < 256) { - scan_code = keycode_table[*keycode]; - char_code = (uint8_t) * keycode & 0xff; - } else { - switch (*keycode) { - case 0x1b50: - // F1 - scan_code = 0x3b; - char_code = 0x0; - break; - default: - printf("%s(): unknown multibyte keycode: %llx\n", - __FUNCTION__, *keycode); - break; - } - } - //assemble scan/char code in keycode - *keycode = (uint64_t) ((((uint16_t) scan_code) << 8) | char_code); -} - -// handle int16 (Keyboard BIOS Interrupt) -static void -handleInt16(void) -{ - // keyboard buffer is in BIOS Memory Area: - // offset 0x1a (WORD) pointer to next char in keybuffer - // offset 0x1c (WORD) pointer to next insert slot in keybuffer - // offset 0x1e-0x3e: 16 WORD Ring Buffer - // since we currently always read the char from the FW buffer, - // we misuse the ring buffer, we use it as pointer to a uint64_t that stores - // multi-byte keys (e.g. special keys in VT100 terminal) - // and as long as a key is available (not 0) we dont read further keys - uint64_t *keycode = (uint64_t *) (M.mem_base + 0x41e); - int8_t c; - // function number in AH - DEBUG_PRINTF_INTR("%s(): Keyboard Interrupt: function: %x.\n", - __FUNCTION__, M.x86.R_AH); - DEBUG_PRINTF_INTR("AX=%04x BX=%04x CX=%04x DX=%04x\n", M.x86.R_AX, - M.x86.R_BX, M.x86.R_CX, M.x86.R_DX); - switch (M.x86.R_AH) { - case 0x00: - // get keystroke - if (*keycode) { - M.x86.R_AX = (uint16_t) * keycode; - // clear keycode - *keycode = 0; - } else { - M.x86.R_AH = 0x61; // scancode for space key - M.x86.R_AL = 0x20; // a space - } - break; - case 0x01: - // check keystroke - // ZF set = no keystroke - // read first byte of key code - if (*keycode) { - // already read, but not yet taken - CLEAR_FLAG(F_ZF); - M.x86.R_AX = (uint16_t) * keycode; - } else { - c = getchar(); - if (c == -1) { - // no key available - SET_FLAG(F_ZF); - } else { - *keycode = c; - - // since after an ESC it may take a while to receive the next char, - // we send something that is not shown on the screen, and then try to get - // the next char - // TODO: only after ESC?? what about other multibyte keys - printf("tt%c%c", 0x08, 0x08); // 0x08 == Backspace - - while ((c = getchar()) != -1) { - *keycode = (*keycode << 8) | c; - DEBUG_PRINTF(" key read: %0llx\n", - *keycode); - } - translate_keycode(keycode); - DEBUG_PRINTF(" translated key: %0llx\n", - *keycode); - if (*keycode == 0) { - //not found - SET_FLAG(F_ZF); - } else { - CLEAR_FLAG(F_ZF); - M.x86.R_AX = (uint16_t) * keycode; - //X86EMU_trace_on(); - //M.x86.debug &= ~DEBUG_DECODE_NOPRINT_F; - } - } - } - break; - default: - printf("%s(): unknown function (%x) for int16 handler.\n", - __FUNCTION__, M.x86.R_AH); - DEBUG_PRINTF_INTR("AX=%04x BX=%04x CX=%04x DX=%04x\n", - M.x86.R_AX, M.x86.R_BX, M.x86.R_CX, - M.x86.R_DX); - HALT_SYS(); - break; - } -} - -// handle int1a (PCI BIOS Interrupt) -static void -handleInt1a(void) -{ - // function number in AX - uint8_t bus, devfn, offs; - switch (M.x86.R_AX) { - case 0xb101: - // Installation check - CLEAR_FLAG(F_CF); // clear CF - M.x86.R_EDX = 0x20494350; // " ICP" endian swapped "PCI " - M.x86.R_AL = 0x1; // Config Space Mechanism 1 supported - M.x86.R_BX = 0x0210; // PCI Interface Level Version 2.10 - M.x86.R_CL = 0xff; // number of last PCI Bus in system TODO: check! - break; - case 0xb102: - // Find PCI Device - // NOTE: we currently only allow the device to find itself... - // it SHOULD be all we ever need... - // device_id in CX, vendor_id in DX - // device index in SI (i.e. if multiple devices with same vendor/device id - // are connected). We currently only support device index 0 - DEBUG_PRINTF_INTR("%s(): function: %x: PCI Find Device\n", - __FUNCTION__, M.x86.R_AX); - if ((M.x86.R_CX == bios_device.pci_device_id) - && (M.x86.R_DX == bios_device.pci_vendor_id) - // device index must be 0 - && (M.x86.R_SI == 0)) { - CLEAR_FLAG(F_CF); - M.x86.R_AH = 0x00; // return code: success - M.x86.R_BH = bios_device.bus; - M.x86.R_BL = bios_device.devfn; - DEBUG_PRINTF_INTR - ("%s(): function %x: PCI Find Device --> 0x%04x\n", - __FUNCTION__, M.x86.R_AX, M.x86.R_BX); - } else { - DEBUG_PRINTF_INTR - ("%s(): function %x: invalid device/vendor/device index! (%04x/%04x/%02x expected: %04x/%04x/0) \n", - __FUNCTION__, M.x86.R_AX, M.x86.R_CX, M.x86.R_DX, - M.x86.R_SI, bios_device.pci_device_id, - bios_device.pci_vendor_id); - SET_FLAG(F_CF); - M.x86.R_AH = 0x86; // return code: device not found - } - break; - case 0xb108: //read configuration byte - case 0xb109: //read configuration word - case 0xb10a: //read configuration dword - bus = M.x86.R_BH; - devfn = M.x86.R_BL; - offs = M.x86.R_DI; - if ((bus != bios_device.bus) - || (devfn != bios_device.devfn)) { - // fail accesses to any device but ours... - printf - ("%s(): Config read access invalid! bus: %x (%x), devfn: %x (%x), offs: %x\n", - __FUNCTION__, bus, bios_device.bus, devfn, - bios_device.devfn, offs); - SET_FLAG(F_CF); - M.x86.R_AH = 0x87; //return code: bad pci register - HALT_SYS(); - return; - } else { - switch (M.x86.R_AX) { - case 0xb108: - M.x86.R_CL = - (uint8_t) rtas_pci_config_read(bios_device. - puid, 1, - bus, devfn, - offs); - DEBUG_PRINTF_INTR - ("%s(): function %x: PCI Config Read @%02x --> 0x%02x\n", - __FUNCTION__, M.x86.R_AX, offs, - M.x86.R_CL); - break; - case 0xb109: - M.x86.R_CX = - (uint16_t) rtas_pci_config_read(bios_device. - puid, 2, - bus, devfn, - offs); - DEBUG_PRINTF_INTR - ("%s(): function %x: PCI Config Read @%02x --> 0x%04x\n", - __FUNCTION__, M.x86.R_AX, offs, - M.x86.R_CX); - break; - case 0xb10a: - M.x86.R_ECX = - (uint32_t) rtas_pci_config_read(bios_device. - puid, 4, - bus, devfn, - offs); - DEBUG_PRINTF_INTR - ("%s(): function %x: PCI Config Read @%02x --> 0x%08x\n", - __FUNCTION__, M.x86.R_AX, offs, - M.x86.R_ECX); - break; - } - CLEAR_FLAG(F_CF); - M.x86.R_AH = 0x0; // return code: success - } - break; - case 0xb10b: //write configuration byte - case 0xb10c: //write configuration word - case 0xb10d: //write configuration dword - bus = M.x86.R_BH; - devfn = M.x86.R_BL; - offs = M.x86.R_DI; - if ((bus != bios_device.bus) - || (devfn != bios_device.devfn)) { - // fail accesses to any device but ours... - printf - ("%s(): Config read access invalid! bus: %x (%x), devfn: %x (%x), offs: %x\n", - __FUNCTION__, bus, bios_device.bus, devfn, - bios_device.devfn, offs); - SET_FLAG(F_CF); - M.x86.R_AH = 0x87; //return code: bad pci register - HALT_SYS(); - return; - } else { - switch (M.x86.R_AX) { - case 0xb10b: - rtas_pci_config_write(bios_device.puid, 1, bus, - devfn, offs, M.x86.R_CL); - DEBUG_PRINTF_INTR - ("%s(): function %x: PCI Config Write @%02x <-- 0x%02x\n", - __FUNCTION__, M.x86.R_AX, offs, - M.x86.R_CL); - break; - case 0xb10c: - rtas_pci_config_write(bios_device.puid, 2, bus, - devfn, offs, M.x86.R_CX); - DEBUG_PRINTF_INTR - ("%s(): function %x: PCI Config Write @%02x <-- 0x%04x\n", - __FUNCTION__, M.x86.R_AX, offs, - M.x86.R_CX); - break; - case 0xb10d: - rtas_pci_config_write(bios_device.puid, 4, bus, - devfn, offs, M.x86.R_ECX); - DEBUG_PRINTF_INTR - ("%s(): function %x: PCI Config Write @%02x <-- 0x%08x\n", - __FUNCTION__, M.x86.R_AX, offs, - M.x86.R_ECX); - break; - } - CLEAR_FLAG(F_CF); - M.x86.R_AH = 0x0; // return code: success - } - break; - default: - printf("%s(): unknown function (%x) for int1a handler.\n", - __FUNCTION__, M.x86.R_AX); - DEBUG_PRINTF_INTR("AX=%04x BX=%04x CX=%04x DX=%04x\n", - M.x86.R_AX, M.x86.R_BX, M.x86.R_CX, - M.x86.R_DX); - HALT_SYS(); - break; - } -} - -// main Interrupt Handler routine, should be registered as x86emu interrupt handler -void -handleInterrupt(int intNum) -{ - uint8_t int_handled = 0; -#ifndef DEBUG_PRINT_INT10 - // this printf makes output by int 10 unreadable... - // so we only enable it, if int10 print is disabled - DEBUG_PRINTF_INTR("%s(%x)\n", __FUNCTION__, intNum); -#endif - switch (intNum) { - case 0x10: //BIOS video interrupt - case 0x42: // INT 10h relocated by EGA/VGA BIOS - case 0x6d: // INT 10h relocated by VGA BIOS - // get interrupt vector from IDT (4 bytes per Interrupt starting at address 0 - if ((my_rdl(intNum * 4) == 0xF000F065) || //F000:F065 is default BIOS interrupt handler address - (my_rdl(intNum * 4) == 0xF4F4F4F4)) //invalid - { -#if 0 - // ignore interrupt... - DEBUG_PRINTF_INTR - ("%s(%x): invalid interrupt Vector (%08x) found, interrupt ignored...\n", - __FUNCTION__, intNum, my_rdl(intNum * 4)); - DEBUG_PRINTF_INTR("AX=%04x BX=%04x CX=%04x DX=%04x\n", - M.x86.R_AX, M.x86.R_BX, M.x86.R_CX, - M.x86.R_DX); - //HALT_SYS(); -#endif - handleInt10(); - int_handled = 1; - } - break; - case 0x16: - // Keyboard BIOS Interrupt - handleInt16(); - int_handled = 1; - break; - case 0x1a: - // PCI BIOS Interrupt - handleInt1a(); - int_handled = 1; - break; - default: - printf("Interrupt %#x (Vector: %x) not implemented\n", intNum, - my_rdl(intNum * 4)); - DEBUG_PRINTF_INTR("AX=%04x BX=%04x CX=%04x DX=%04x\n", - M.x86.R_AX, M.x86.R_BX, M.x86.R_CX, - M.x86.R_DX); - int_handled = 1; - HALT_SYS(); - break; - } - // if we did not handle the interrupt, jump to the interrupt vector... - if (!int_handled) { - setupInt(intNum); - } -} - -// prepare and execute Interrupt 10 (VGA Interrupt) -void -runInt10() -{ - // Initialize stack and data segment - M.x86.R_SS = STACK_SEGMENT; - M.x86.R_DS = DATA_SEGMENT; - M.x86.R_SP = STACK_START_OFFSET; - - // push a HLT instruction and a pointer to it onto the stack - // any return will pop the pointer and jump to the HLT, thus - // exiting (more or less) cleanly - push_word(0xf4f4); //F4=HLT - //push_word(M.x86.R_SS); - //push_word(M.x86.R_SP + 2); - - // setupInt will push the current CS and IP to the stack to return to it, - // but we want to halt, so set CS:IP to the HLT instruction we just pushed - // to the stack - M.x86.R_CS = M.x86.R_SS; - M.x86.R_IP = M.x86.R_SP; // + 4; - - CHECK_DBG(DEBUG_TRACE_X86EMU) { - X86EMU_trace_on(); - } - CHECK_DBG(DEBUG_JMP) { - M.x86.debug |= DEBUG_TRACEJMP_REGS_F; - M.x86.debug |= DEBUG_TRACEJMP_REGS_F; - M.x86.debug |= DEBUG_TRACECALL_F; - M.x86.debug |= DEBUG_TRACECALL_REGS_F; - } - setupInt(0x10); - DEBUG_PRINTF_INTR("%s(): starting execution of INT10...\n", - __FUNCTION__); - X86EMU_exec(); - DEBUG_PRINTF_INTR("%s(): execution finished\n", __FUNCTION__); -} - -// prepare and execute Interrupt 13 (Disk Interrupt) -void -runInt13(void) -{ - // Initialize stack and data segment - M.x86.R_SS = STACK_SEGMENT; - M.x86.R_DS = DATA_SEGMENT; - M.x86.R_SP = STACK_START_OFFSET; - - // push a HLT instruction and a pointer to it onto the stack - // any return will pop the pointer and jump to the HLT, thus - // exiting (more or less) cleanly - push_word(0xf4f4); //F4=HLT - //push_word(M.x86.R_SS); - //push_word(M.x86.R_SP + 2); - - // setupInt will push the current CS and IP to the stack to return to it, - // but we want to halt, so set CS:IP to the HLT instruction we just pushed - // to the stack - M.x86.R_CS = M.x86.R_SS; - M.x86.R_IP = M.x86.R_SP; - - CHECK_DBG(DEBUG_TRACE_X86EMU) { - X86EMU_trace_on(); - } - CHECK_DBG(DEBUG_JMP) { - M.x86.debug |= DEBUG_TRACEJMP_REGS_F; - M.x86.debug |= DEBUG_TRACEJMP_REGS_F; - M.x86.debug |= DEBUG_TRACECALL_F; - M.x86.debug |= DEBUG_TRACECALL_REGS_F; - } - - setupInt(0x13); - DEBUG_PRINTF_INTR("%s(): starting execution of INT13...\n", - __FUNCTION__); - X86EMU_exec(); - DEBUG_PRINTF_INTR("%s(): execution finished\n", __FUNCTION__); -} diff --git a/qemu/roms/SLOF/clients/net-snk/app/biosemu/interrupt.h b/qemu/roms/SLOF/clients/net-snk/app/biosemu/interrupt.h deleted file mode 100644 index 11755e102..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/biosemu/interrupt.h +++ /dev/null @@ -1,21 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2008 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ -#ifndef _BIOSEMU_INTERRUPT_H_ -#define _BIOSEMU_INTERRUPT_H_ - -void handleInterrupt(int intNum); - -void runInt10(void); - -void runInt13(void); - -#endif diff --git a/qemu/roms/SLOF/clients/net-snk/app/biosemu/io.c b/qemu/roms/SLOF/clients/net-snk/app/biosemu/io.c deleted file mode 100644 index e9c08932a..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/biosemu/io.c +++ /dev/null @@ -1,382 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2008 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -#include <stdio.h> -#include <cpu.h> -#include <pci.h> -#include "device.h" -#include "rtas.h" -#include "debug.h" -#include "device.h" -#include <stdint.h> -#include <x86emu/x86emu.h> -#include <time.h> -#include "io.h" - -//defined in net-snk/kernel/timer.c -extern uint64_t get_time(void); - -uint32_t pci_cfg_read(X86EMU_pioAddr addr, uint8_t size); -void pci_cfg_write(X86EMU_pioAddr addr, uint32_t val, uint8_t size); -uint8_t handle_port_61h(void); - -uint8_t -my_inb(X86EMU_pioAddr addr) -{ - uint8_t rval = 0xFF; - uint64_t translated_addr = addr; - uint8_t translated = dev_translate_address(&translated_addr); - if (translated != 0) { - //translation successful, access Device I/O (BAR or Legacy...) - DEBUG_PRINTF_IO("%s(%x): access to Device I/O\n", __FUNCTION__, - addr); - //DEBUG_PRINTF_IO("%s(%04x): translated_addr: %llx\n", __FUNCTION__, addr, translated_addr); - rval = read_io((void *)translated_addr, 1); - DEBUG_PRINTF_IO("%s(%04x) Device I/O --> %02x\n", __FUNCTION__, - addr, rval); - return rval; - } else { - switch (addr) { - case 0x61: - //8254 KB Controller / Timer Port - rval = handle_port_61h(); - //DEBUG_PRINTF_IO("%s(%04x) KB / Timer Port B --> %02x\n", __FUNCTION__, addr, rval); - return rval; - break; - case 0xCFC: - case 0xCFD: - case 0xCFE: - case 0xCFF: - // PCI Config Mechanism 1 Ports - return (uint8_t) pci_cfg_read(addr, 1); - break; - case 0x0a: - CHECK_DBG(DEBUG_INTR) { - X86EMU_trace_on(); - } - M.x86.debug &= ~DEBUG_DECODE_NOPRINT_F; - //HALT_SYS(); - // no break, intentional fall-through to default!! - default: - DEBUG_PRINTF_IO - ("%s(%04x) reading from bios_device.io_buffer\n", - __FUNCTION__, addr); - rval = *((uint8_t *) (bios_device.io_buffer + addr)); - DEBUG_PRINTF_IO("%s(%04x) I/O Buffer --> %02x\n", - __FUNCTION__, addr, rval); - return rval; - break; - } - } -} - -uint16_t -my_inw(X86EMU_pioAddr addr) -{ - uint64_t translated_addr = addr; - uint8_t translated = dev_translate_address(&translated_addr); - if (translated != 0) { - //translation successful, access Device I/O (BAR or Legacy...) - DEBUG_PRINTF_IO("%s(%x): access to Device I/O\n", __FUNCTION__, - addr); - //DEBUG_PRINTF_IO("%s(%04x): translated_addr: %llx\n", __FUNCTION__, addr, translated_addr); - uint16_t rval; - if ((translated_addr & (uint64_t) 0x1) == 0) { - // 16 bit aligned access... - uint16_t tempval = read_io((void *)translated_addr, 2); - //little endian conversion - rval = in16le((void *) &tempval); - } else { - // unaligned access, read single bytes, little-endian - rval = (read_io((void *)translated_addr, 1) << 8) - | (read_io((void *)(translated_addr + 1), 1)); - } - DEBUG_PRINTF_IO("%s(%04x) Device I/O --> %04x\n", __FUNCTION__, - addr, rval); - return rval; - } else { - switch (addr) { - case 0xCFC: - case 0xCFE: - //PCI Config Mechanism 1 - return (uint16_t) pci_cfg_read(addr, 2); - break; - default: - DEBUG_PRINTF_IO - ("%s(%04x) reading from bios_device.io_buffer\n", - __FUNCTION__, addr); - uint16_t rval = - in16le((void *) bios_device.io_buffer + addr); - DEBUG_PRINTF_IO("%s(%04x) I/O Buffer --> %04x\n", - __FUNCTION__, addr, rval); - return rval; - break; - } - } -} - -uint32_t -my_inl(X86EMU_pioAddr addr) -{ - uint64_t translated_addr = addr; - uint8_t translated = dev_translate_address(&translated_addr); - if (translated != 0) { - //translation successful, access Device I/O (BAR or Legacy...) - DEBUG_PRINTF_IO("%s(%x): access to Device I/O\n", __FUNCTION__, - addr); - //DEBUG_PRINTF_IO("%s(%04x): translated_addr: %llx\n", __FUNCTION__, addr, translated_addr); - uint32_t rval; - if ((translated_addr & (uint64_t) 0x3) == 0) { - // 32 bit aligned access... - uint32_t tempval = read_io((void *) translated_addr, 4); - //little endian conversion - rval = in32le((void *) &tempval); - } else { - // unaligned access, read single bytes, little-endian - rval = (read_io((void *)(translated_addr), 1) << 24) - | (read_io((void *)(translated_addr + 1), 1) << 16) - | (read_io((void *)(translated_addr + 2), 1) << 8) - | (read_io((void *)(translated_addr + 3), 1)); - } - DEBUG_PRINTF_IO("%s(%04x) Device I/O --> %08x\n", __FUNCTION__, - addr, rval); - return rval; - } else { - switch (addr) { - case 0xCFC: - //PCI Config Mechanism 1 - return pci_cfg_read(addr, 4); - break; - default: - DEBUG_PRINTF_IO - ("%s(%04x) reading from bios_device.io_buffer\n", - __FUNCTION__, addr); - uint32_t rval = - in32le((void *) bios_device.io_buffer + addr); - DEBUG_PRINTF_IO("%s(%04x) I/O Buffer --> %08x\n", - __FUNCTION__, addr, rval); - return rval; - break; - } - } -} - -void -my_outb(X86EMU_pioAddr addr, uint8_t val) -{ - uint64_t translated_addr = addr; - uint8_t translated = dev_translate_address(&translated_addr); - if (translated != 0) { - //translation successful, access Device I/O (BAR or Legacy...) - DEBUG_PRINTF_IO("%s(%x, %x): access to Device I/O\n", - __FUNCTION__, addr, val); - //DEBUG_PRINTF_IO("%s(%04x): translated_addr: %llx\n", __FUNCTION__, addr, translated_addr); - write_io((void *) translated_addr, val, 1); - DEBUG_PRINTF_IO("%s(%04x) Device I/O <-- %02x\n", __FUNCTION__, - addr, val); - } else { - switch (addr) { - case 0xCFC: - case 0xCFD: - case 0xCFE: - case 0xCFF: - // PCI Config Mechanism 1 Ports - pci_cfg_write(addr, val, 1); - break; - default: - DEBUG_PRINTF_IO - ("%s(%04x,%02x) writing to bios_device.io_buffer\n", - __FUNCTION__, addr, val); - *((uint8_t *) (bios_device.io_buffer + addr)) = val; - break; - } - } -} - -void -my_outw(X86EMU_pioAddr addr, uint16_t val) -{ - uint64_t translated_addr = addr; - uint8_t translated = dev_translate_address(&translated_addr); - if (translated != 0) { - //translation successful, access Device I/O (BAR or Legacy...) - DEBUG_PRINTF_IO("%s(%x, %x): access to Device I/O\n", - __FUNCTION__, addr, val); - //DEBUG_PRINTF_IO("%s(%04x): translated_addr: %llx\n", __FUNCTION__, addr, translated_addr); - if ((translated_addr & (uint64_t) 0x1) == 0) { - // little-endian conversion - uint16_t tempval = in16le((void *) &val); - // 16 bit aligned access... - write_io((void *) translated_addr, tempval, 2); - } else { - // unaligned access, write single bytes, little-endian - write_io(((void *) (translated_addr + 1)), - (uint8_t) ((val & 0xFF00) >> 8), 1); - write_io(((void *) translated_addr), - (uint8_t) (val & 0x00FF), 1); - } - DEBUG_PRINTF_IO("%s(%04x) Device I/O <-- %04x\n", __FUNCTION__, - addr, val); - } else { - switch (addr) { - case 0xCFC: - case 0xCFE: - // PCI Config Mechanism 1 Ports - pci_cfg_write(addr, val, 2); - break; - default: - DEBUG_PRINTF_IO - ("%s(%04x,%04x) writing to bios_device.io_buffer\n", - __FUNCTION__, addr, val); - out16le((void *) bios_device.io_buffer + addr, val); - break; - } - } -} - -void -my_outl(X86EMU_pioAddr addr, uint32_t val) -{ - uint64_t translated_addr = addr; - uint8_t translated = dev_translate_address(&translated_addr); - if (translated != 0) { - //translation successful, access Device I/O (BAR or Legacy...) - DEBUG_PRINTF_IO("%s(%x, %x): access to Device I/O\n", - __FUNCTION__, addr, val); - //DEBUG_PRINTF_IO("%s(%04x): translated_addr: %llx\n", __FUNCTION__, addr, translated_addr); - if ((translated_addr & (uint64_t) 0x3) == 0) { - // little-endian conversion - uint32_t tempval = in32le((void *) &val); - // 32 bit aligned access... - write_io((void *) translated_addr, tempval, 4); - } else { - // unaligned access, write single bytes, little-endian - write_io(((void *) translated_addr + 3), - (uint8_t) ((val & 0xFF000000) >> 24), 1); - write_io(((void *) translated_addr + 2), - (uint8_t) ((val & 0x00FF0000) >> 16), 1); - write_io(((void *) translated_addr + 1), - (uint8_t) ((val & 0x0000FF00) >> 8), 1); - write_io(((void *) translated_addr), - (uint8_t) (val & 0x000000FF), 1); - } - DEBUG_PRINTF_IO("%s(%04x) Device I/O <-- %08x\n", __FUNCTION__, - addr, val); - } else { - switch (addr) { - case 0xCFC: - // PCI Config Mechanism 1 Ports - pci_cfg_write(addr, val, 4); - break; - default: - DEBUG_PRINTF_IO - ("%s(%04x,%08x) writing to bios_device.io_buffer\n", - __FUNCTION__, addr, val); - out32le((void *) bios_device.io_buffer + addr, val); - break; - } - } -} - -uint32_t -pci_cfg_read(X86EMU_pioAddr addr, uint8_t size) -{ - uint32_t rval = 0xFFFFFFFF; - if ((addr >= 0xCFC) && ((addr + size) <= 0xCFF)) { - // PCI Configuration Mechanism 1 step 1 - // write to 0xCF8, sets bus, device, function and Config Space offset - // later read from 0xCFC-0xCFF returns the value... - uint8_t bus, devfn, offs; - uint32_t port_cf8_val = my_inl(0xCF8); - if ((port_cf8_val & 0x80000000) != 0) { - //highest bit enables config space mapping - bus = (port_cf8_val & 0x00FF0000) >> 16; - devfn = (port_cf8_val & 0x0000FF00) >> 8; - offs = (port_cf8_val & 0x000000FF); - offs += (addr - 0xCFC); // if addr is not 0xcfc, the offset is moved accordingly - if ((bus != bios_device.bus) - || (devfn != bios_device.devfn)) { - // fail accesses to any device but ours... - printf - ("Config access invalid! bus: %x, devfn: %x, offs: %x\n", - bus, devfn, offs); - HALT_SYS(); - } else { - rval = - (uint32_t) rtas_pci_config_read(bios_device. - puid, size, - bus, devfn, - offs); - DEBUG_PRINTF_IO - ("%s(%04x) PCI Config Read @%02x, size: %d --> 0x%08x\n", - __FUNCTION__, addr, offs, size, rval); - } - } - } - return rval; -} - -void -pci_cfg_write(X86EMU_pioAddr addr, uint32_t val, uint8_t size) -{ - if ((addr >= 0xCFC) && ((addr + size) <= 0xCFF)) { - // PCI Configuration Mechanism 1 step 1 - // write to 0xCF8, sets bus, device, function and Config Space offset - // later write to 0xCFC-0xCFF sets the value... - uint8_t bus, devfn, offs; - uint32_t port_cf8_val = my_inl(0xCF8); - if ((port_cf8_val & 0x80000000) != 0) { - //highest bit enables config space mapping - bus = (port_cf8_val & 0x00FF0000) >> 16; - devfn = (port_cf8_val & 0x0000FF00) >> 8; - offs = (port_cf8_val & 0x000000FF); - offs += (addr - 0xCFC); // if addr is not 0xcfc, the offset is moved accordingly - if ((bus != bios_device.bus) - || (devfn != bios_device.devfn)) { - // fail accesses to any device but ours... - printf - ("Config access invalid! bus: %x, devfn: %x, offs: %x\n", - bus, devfn, offs); - HALT_SYS(); - } else { - rtas_pci_config_write(bios_device.puid, - size, bus, devfn, offs, - val); - DEBUG_PRINTF_IO - ("%s(%04x) PCI Config Write @%02x, size: %d <-- 0x%08x\n", - __FUNCTION__, addr, offs, size, val); - } - } - } -} - -uint8_t -handle_port_61h(void) -{ - static uint64_t last_time = 0; - uint64_t curr_time = get_time(); - uint64_t time_diff; // time since last call - uint32_t period_ticks; // length of a period in ticks - uint32_t nr_periods; //number of periods passed since last call - // bit 4 should toggle with every (DRAM) refresh cycle... (66kHz??) - time_diff = curr_time - last_time; - // at 66kHz a period is ~ 15 ns long, converted to ticks: (tb_freq is ticks/second) - // TODO: as long as the frequency does not change, we should not calculate this every time - period_ticks = (15 * tb_freq) / 1000000; - nr_periods = time_diff / period_ticks; - // if the number if ticks passed since last call is odd, we toggle bit 4 - if ((nr_periods % 2) != 0) { - *((uint8_t *) (bios_device.io_buffer + 0x61)) ^= 0x10; - } - //finally read the value from the io_buffer - return *((uint8_t *) (bios_device.io_buffer + 0x61)); -} diff --git a/qemu/roms/SLOF/clients/net-snk/app/biosemu/io.h b/qemu/roms/SLOF/clients/net-snk/app/biosemu/io.h deleted file mode 100644 index 5a0bb4b4b..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/biosemu/io.h +++ /dev/null @@ -1,30 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2008 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -#ifndef _BIOSEMU_IO_H_ -#define _BIOSEMU_IO_H_ -#include <x86emu/x86emu.h> -#include <stdint.h> - -uint8_t my_inb(X86EMU_pioAddr addr); - -uint16_t my_inw(X86EMU_pioAddr addr); - -uint32_t my_inl(X86EMU_pioAddr addr); - -void my_outb(X86EMU_pioAddr addr, uint8_t val); - -void my_outw(X86EMU_pioAddr addr, uint16_t val); - -void my_outl(X86EMU_pioAddr addr, uint32_t val); - -#endif diff --git a/qemu/roms/SLOF/clients/net-snk/app/biosemu/mem.c b/qemu/roms/SLOF/clients/net-snk/app/biosemu/mem.c deleted file mode 100644 index 1a6207554..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/biosemu/mem.c +++ /dev/null @@ -1,464 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2008 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -#include <stdio.h> -#include <stdint.h> -#include <cpu.h> -#include "debug.h" -#include "device.h" -#include "x86emu/x86emu.h" -#include "biosemu.h" -#include <time.h> -#include "mem.h" - -// define a check for access to certain (virtual) memory regions (interrupt handlers, BIOS Data Area, ...) -#ifdef DEBUG -static uint8_t in_check = 0; // to avoid recursion... -uint16_t ebda_segment; -uint32_t ebda_size; - -//TODO: these macros have grown so large, that they should be changed to an inline function, -//just for the sake of readability... - -//declare prototypes of the functions to follow, for use in DEBUG_CHECK_VMEM_ACCESS -uint8_t my_rdb(uint32_t); -uint16_t my_rdw(uint32_t); -uint32_t my_rdl(uint32_t); - -#define DEBUG_CHECK_VMEM_READ(_addr, _rval) \ - if ((debug_flags & DEBUG_CHECK_VMEM_ACCESS) && (in_check == 0)) { \ - in_check = 1; \ - /* determine ebda_segment and size \ - * since we are using my_rdx calls, make sure, this is after setting in_check! */ \ - /* offset 03 in BDA is EBDA segment */ \ - ebda_segment = my_rdw(0x40e); \ - /* first value in ebda is size in KB */ \ - ebda_size = my_rdb(ebda_segment << 4) * 1024; \ - /* check Interrupt Vector Access (0000:0000h - 0000:0400h) */ \ - if (_addr < 0x400) { \ - DEBUG_PRINTF_CS_IP("%s: read from Interrupt Vector %x --> %x\n", \ - __FUNCTION__, _addr / 4, _rval); \ - } \ - /* access to BIOS Data Area (0000:0400h - 0000:0500h)*/ \ - else if ((_addr >= 0x400) && (addr < 0x500)) { \ - DEBUG_PRINTF_CS_IP("%s: read from BIOS Data Area: addr: %x --> %x\n", \ - __FUNCTION__, _addr, _rval); \ - /* dump registers */ \ - /* x86emu_dump_xregs(); */ \ - } \ - /* access to first 64k of memory... */ \ - else if (_addr < 0x10000) { \ - DEBUG_PRINTF_CS_IP("%s: read from segment 0000h: addr: %x --> %x\n", \ - __FUNCTION__, _addr, _rval); \ - /* dump registers */ \ - /* x86emu_dump_xregs(); */ \ - } \ - /* read from PMM_CONV_SEGMENT */ \ - else if ((_addr <= ((PMM_CONV_SEGMENT << 4) | 0xffff)) && (_addr >= (PMM_CONV_SEGMENT << 4))) { \ - DEBUG_PRINTF_CS_IP("%s: read from PMM Segment %04xh: addr: %x --> %x\n", \ - __FUNCTION__, PMM_CONV_SEGMENT, _addr, _rval); \ - /* HALT_SYS(); */ \ - /* dump registers */ \ - /* x86emu_dump_xregs(); */ \ - } \ - /* read from PNP_DATA_SEGMENT */ \ - else if ((_addr <= ((PNP_DATA_SEGMENT << 4) | 0xffff)) && (_addr >= (PNP_DATA_SEGMENT << 4))) { \ - DEBUG_PRINTF_CS_IP("%s: read from PnP Data Segment %04xh: addr: %x --> %x\n", \ - __FUNCTION__, PNP_DATA_SEGMENT, _addr, _rval); \ - /* HALT_SYS(); */ \ - /* dump registers */ \ - /* x86emu_dump_xregs(); */ \ - } \ - /* read from EBDA Segment */ \ - else if ((_addr <= ((ebda_segment << 4) | (ebda_size - 1))) && (_addr >= (ebda_segment << 4))) { \ - DEBUG_PRINTF_CS_IP("%s: read from Extended BIOS Data Area %04xh, size: %04x: addr: %x --> %x\n", \ - __FUNCTION__, ebda_segment, ebda_size, _addr, _rval); \ - } \ - /* read from BIOS_DATA_SEGMENT */ \ - else if ((_addr <= ((BIOS_DATA_SEGMENT << 4) | 0xffff)) && (_addr >= (BIOS_DATA_SEGMENT << 4))) { \ - DEBUG_PRINTF_CS_IP("%s: read from BIOS Data Segment %04xh: addr: %x --> %x\n", \ - __FUNCTION__, BIOS_DATA_SEGMENT, _addr, _rval); \ - /* for PMM debugging */ \ - /*if (_addr == BIOS_DATA_SEGMENT << 4) { \ - X86EMU_trace_on(); \ - M.x86.debug &= ~DEBUG_DECODE_NOPRINT_F; \ - }*/ \ - /* dump registers */ \ - /* x86emu_dump_xregs(); */ \ - } \ - in_check = 0; \ - } -#define DEBUG_CHECK_VMEM_WRITE(_addr, _val) \ - if ((debug_flags & DEBUG_CHECK_VMEM_ACCESS) && (in_check == 0)) { \ - in_check = 1; \ - /* determine ebda_segment and size \ - * since we are using my_rdx calls, make sure, this is after setting in_check! */ \ - /* offset 03 in BDA is EBDA segment */ \ - ebda_segment = my_rdw(0x40e); \ - /* first value in ebda is size in KB */ \ - ebda_size = my_rdb(ebda_segment << 4) * 1024; \ - /* check Interrupt Vector Access (0000:0000h - 0000:0400h) */ \ - if (_addr < 0x400) { \ - DEBUG_PRINTF_CS_IP("%s: write to Interrupt Vector %x <-- %x\n", \ - __FUNCTION__, _addr / 4, _val); \ - } \ - /* access to BIOS Data Area (0000:0400h - 0000:0500h)*/ \ - else if ((_addr >= 0x400) && (addr < 0x500)) { \ - DEBUG_PRINTF_CS_IP("%s: write to BIOS Data Area: addr: %x <-- %x\n", \ - __FUNCTION__, _addr, _val); \ - /* dump registers */ \ - /* x86emu_dump_xregs(); */ \ - } \ - /* access to first 64k of memory...*/ \ - else if (_addr < 0x10000) { \ - DEBUG_PRINTF_CS_IP("%s: write to segment 0000h: addr: %x <-- %x\n", \ - __FUNCTION__, _addr, _val); \ - /* dump registers */ \ - /* x86emu_dump_xregs(); */ \ - } \ - /* write to PMM_CONV_SEGMENT... */ \ - else if ((_addr <= ((PMM_CONV_SEGMENT << 4) | 0xffff)) && (_addr >= (PMM_CONV_SEGMENT << 4))) { \ - DEBUG_PRINTF_CS_IP("%s: write to PMM Segment %04xh: addr: %x <-- %x\n", \ - __FUNCTION__, PMM_CONV_SEGMENT, _addr, _val); \ - /* dump registers */ \ - /* x86emu_dump_xregs(); */ \ - } \ - /* write to PNP_DATA_SEGMENT... */ \ - else if ((_addr <= ((PNP_DATA_SEGMENT << 4) | 0xffff)) && (_addr >= (PNP_DATA_SEGMENT << 4))) { \ - DEBUG_PRINTF_CS_IP("%s: write to PnP Data Segment %04xh: addr: %x <-- %x\n", \ - __FUNCTION__, PNP_DATA_SEGMENT, _addr, _val); \ - /* dump registers */ \ - /* x86emu_dump_xregs(); */ \ - } \ - /* write to EBDA Segment... */ \ - else if ((_addr <= ((ebda_segment << 4) | (ebda_size - 1))) && (_addr >= (ebda_segment << 4))) { \ - DEBUG_PRINTF_CS_IP("%s: write to Extended BIOS Data Area %04xh, size: %04x: addr: %x <-- %x\n", \ - __FUNCTION__, ebda_segment, ebda_size, _addr, _val); \ - } \ - /* write to BIOS_DATA_SEGMENT... */ \ - else if ((_addr <= ((BIOS_DATA_SEGMENT << 4) | 0xffff)) && (_addr >= (BIOS_DATA_SEGMENT << 4))) { \ - DEBUG_PRINTF_CS_IP("%s: write to BIOS Data Segment %04xh: addr: %x <-- %x\n", \ - __FUNCTION__, BIOS_DATA_SEGMENT, _addr, _val); \ - /* dump registers */ \ - /* x86emu_dump_xregs(); */ \ - } \ - /* write to current CS segment... */ \ - else if ((_addr < ((M.x86.R_CS << 4) | 0xffff)) && (_addr > (M.x86.R_CS << 4))) { \ - DEBUG_PRINTF_CS_IP("%s: write to CS segment %04xh: addr: %x <-- %x\n", \ - __FUNCTION__, M.x86.R_CS, _addr, _val); \ - /* dump registers */ \ - /* x86emu_dump_xregs(); */ \ - } \ - in_check = 0; \ - } -#else -#define DEBUG_CHECK_VMEM_READ(_addr, _rval) -#define DEBUG_CHECK_VMEM_WRITE(_addr, _val) -#endif - -//defined in net-snk/kernel/timer.c -extern uint64_t get_time(void); - -void update_time(uint32_t); - -// read byte from memory -uint8_t -my_rdb(uint32_t addr) -{ - uint64_t translated_addr = addr; - uint8_t translated = dev_translate_address(&translated_addr); - uint8_t rval; - if (translated != 0) { - //translation successful, access VGA Memory (BAR or Legacy...) - DEBUG_PRINTF_MEM("%s(%08x): access to VGA Memory\n", - __FUNCTION__, addr); - //DEBUG_PRINTF_MEM("%s(%08x): translated_addr: %llx\n", __FUNCTION__, addr, translated_addr); - set_ci(); - rval = *((uint8_t *) translated_addr); - clr_ci(); - DEBUG_PRINTF_MEM("%s(%08x) VGA --> %02x\n", __FUNCTION__, addr, - rval); - return rval; - } else if (addr > M.mem_size) { - DEBUG_PRINTF("%s(%08x): Memory Access out of range!\n", - __FUNCTION__, addr); - //disassemble_forward(M.x86.saved_cs, M.x86.saved_ip, 1); - HALT_SYS(); - } else { - /* read from virtual memory */ - rval = *((uint8_t *) (M.mem_base + addr)); - DEBUG_CHECK_VMEM_READ(addr, rval); - return rval; - } - return -1; -} - -//read word from memory -uint16_t -my_rdw(uint32_t addr) -{ - uint64_t translated_addr = addr; - uint8_t translated = dev_translate_address(&translated_addr); - uint16_t rval; - if (translated != 0) { - //translation successful, access VGA Memory (BAR or Legacy...) - DEBUG_PRINTF_MEM("%s(%08x): access to VGA Memory\n", - __FUNCTION__, addr); - //DEBUG_PRINTF_MEM("%s(%08x): translated_addr: %llx\n", __FUNCTION__, addr, translated_addr); - // check for legacy memory, because of the remapping to BARs, the reads must - // be byte reads... - if ((addr >= 0xa0000) && (addr < 0xc0000)) { - //read bytes a using my_rdb, because of the remapping to BARs - //words may not be contiguous in memory, so we need to translate - //every address... - rval = ((uint8_t) my_rdb(addr)) | - (((uint8_t) my_rdb(addr + 1)) << 8); - } else { - if ((translated_addr & (uint64_t) 0x1) == 0) { - // 16 bit aligned access... - set_ci(); - rval = in16le((void *) translated_addr); - clr_ci(); - } else { - // unaligned access, read single bytes - set_ci(); - rval = (*((uint8_t *) translated_addr)) | - (*((uint8_t *) translated_addr + 1) << 8); - clr_ci(); - } - } - DEBUG_PRINTF_MEM("%s(%08x) VGA --> %04x\n", __FUNCTION__, addr, - rval); - return rval; - } else if (addr > M.mem_size) { - DEBUG_PRINTF("%s(%08x): Memory Access out of range!\n", - __FUNCTION__, addr); - //disassemble_forward(M.x86.saved_cs, M.x86.saved_ip, 1); - HALT_SYS(); - } else { - /* read from virtual memory */ - rval = in16le((void *) (M.mem_base + addr)); - DEBUG_CHECK_VMEM_READ(addr, rval); - return rval; - } - return -1; -} - -//read long from memory -uint32_t -my_rdl(uint32_t addr) -{ - uint64_t translated_addr = addr; - uint8_t translated = dev_translate_address(&translated_addr); - uint32_t rval; - if (translated != 0) { - //translation successful, access VGA Memory (BAR or Legacy...) - DEBUG_PRINTF_MEM("%s(%x): access to VGA Memory\n", - __FUNCTION__, addr); - //DEBUG_PRINTF_MEM("%s(%08x): translated_addr: %llx\n", __FUNCTION__, addr, translated_addr); - // check for legacy memory, because of the remapping to BARs, the reads must - // be byte reads... - if ((addr >= 0xa0000) && (addr < 0xc0000)) { - //read bytes a using my_rdb, because of the remapping to BARs - //dwords may not be contiguous in memory, so we need to translate - //every address... - rval = ((uint8_t) my_rdb(addr)) | - (((uint8_t) my_rdb(addr + 1)) << 8) | - (((uint8_t) my_rdb(addr + 2)) << 16) | - (((uint8_t) my_rdb(addr + 3)) << 24); - } else { - if ((translated_addr & (uint64_t) 0x3) == 0) { - // 32 bit aligned access... - set_ci(); - rval = in32le((void *) translated_addr); - clr_ci(); - } else { - // unaligned access, read single bytes - set_ci(); - rval = (*((uint8_t *) translated_addr)) | - (*((uint8_t *) translated_addr + 1) << 8) | - (*((uint8_t *) translated_addr + 2) << 16) | - (*((uint8_t *) translated_addr + 3) << 24); - clr_ci(); - } - } - DEBUG_PRINTF_MEM("%s(%08x) VGA --> %08x\n", __FUNCTION__, addr, - rval); - //HALT_SYS(); - return rval; - } else if (addr > M.mem_size) { - DEBUG_PRINTF("%s(%08x): Memory Access out of range!\n", - __FUNCTION__, addr); - //disassemble_forward(M.x86.saved_cs, M.x86.saved_ip, 1); - HALT_SYS(); - } else { - /* read from virtual memory */ - rval = in32le((void *) (M.mem_base + addr)); - switch (addr) { - case 0x46c: - //BDA Time Data, update it, before reading - update_time(rval); - rval = in32le((void *) (M.mem_base + addr)); - break; - } - DEBUG_CHECK_VMEM_READ(addr, rval); - return rval; - } - return -1; -} - -//write byte to memory -void -my_wrb(uint32_t addr, uint8_t val) -{ - uint64_t translated_addr = addr; - uint8_t translated = dev_translate_address(&translated_addr); - if (translated != 0) { - //translation successful, access VGA Memory (BAR or Legacy...) - DEBUG_PRINTF_MEM("%s(%x, %x): access to VGA Memory\n", - __FUNCTION__, addr, val); - //DEBUG_PRINTF_MEM("%s(%08x): translated_addr: %llx\n", __FUNCTION__, addr, translated_addr); - set_ci(); - *((uint8_t *) translated_addr) = val; - clr_ci(); - } else if (addr > M.mem_size) { - DEBUG_PRINTF("%s(%08x): Memory Access out of range!\n", - __FUNCTION__, addr); - //disassemble_forward(M.x86.saved_cs, M.x86.saved_ip, 1); - HALT_SYS(); - } else { - /* write to virtual memory */ - DEBUG_CHECK_VMEM_WRITE(addr, val); - *((uint8_t *) (M.mem_base + addr)) = val; - } -} - -void -my_wrw(uint32_t addr, uint16_t val) -{ - uint64_t translated_addr = addr; - uint8_t translated = dev_translate_address(&translated_addr); - if (translated != 0) { - //translation successful, access VGA Memory (BAR or Legacy...) - DEBUG_PRINTF_MEM("%s(%x, %x): access to VGA Memory\n", - __FUNCTION__, addr, val); - //DEBUG_PRINTF_MEM("%s(%08x): translated_addr: %llx\n", __FUNCTION__, addr, translated_addr); - // check for legacy memory, because of the remapping to BARs, the reads must - // be byte reads... - if ((addr >= 0xa0000) && (addr < 0xc0000)) { - //read bytes a using my_rdb, because of the remapping to BARs - //words may not be contiguous in memory, so we need to translate - //every address... - my_wrb(addr, (uint8_t) (val & 0x00FF)); - my_wrb(addr + 1, (uint8_t) ((val & 0xFF00) >> 8)); - } else { - if ((translated_addr & (uint64_t) 0x1) == 0) { - // 16 bit aligned access... - set_ci(); - out16le((void *) translated_addr, val); - clr_ci(); - } else { - // unaligned access, write single bytes - set_ci(); - *((uint8_t *) translated_addr) = - (uint8_t) (val & 0x00FF); - *((uint8_t *) translated_addr + 1) = - (uint8_t) ((val & 0xFF00) >> 8); - clr_ci(); - } - } - } else if (addr > M.mem_size) { - DEBUG_PRINTF("%s(%08x): Memory Access out of range!\n", - __FUNCTION__, addr); - //disassemble_forward(M.x86.saved_cs, M.x86.saved_ip, 1); - HALT_SYS(); - } else { - /* write to virtual memory */ - DEBUG_CHECK_VMEM_WRITE(addr, val); - out16le((void *) (M.mem_base + addr), val); - } -} -void -my_wrl(uint32_t addr, uint32_t val) -{ - uint64_t translated_addr = addr; - uint8_t translated = dev_translate_address(&translated_addr); - if (translated != 0) { - //translation successful, access VGA Memory (BAR or Legacy...) - DEBUG_PRINTF_MEM("%s(%x, %x): access to VGA Memory\n", - __FUNCTION__, addr, val); - //DEBUG_PRINTF_MEM("%s(%08x): translated_addr: %llx\n", __FUNCTION__, addr, translated_addr); - // check for legacy memory, because of the remapping to BARs, the reads must - // be byte reads... - if ((addr >= 0xa0000) && (addr < 0xc0000)) { - //read bytes a using my_rdb, because of the remapping to BARs - //words may not be contiguous in memory, so we need to translate - //every address... - my_wrb(addr, (uint8_t) (val & 0x000000FF)); - my_wrb(addr + 1, (uint8_t) ((val & 0x0000FF00) >> 8)); - my_wrb(addr + 2, (uint8_t) ((val & 0x00FF0000) >> 16)); - my_wrb(addr + 3, (uint8_t) ((val & 0xFF000000) >> 24)); - } else { - if ((translated_addr & (uint64_t) 0x3) == 0) { - // 32 bit aligned access... - set_ci(); - out32le((void *) translated_addr, val); - clr_ci(); - } else { - // unaligned access, write single bytes - set_ci(); - *((uint8_t *) translated_addr) = - (uint8_t) (val & 0x000000FF); - *((uint8_t *) translated_addr + 1) = - (uint8_t) ((val & 0x0000FF00) >> 8); - *((uint8_t *) translated_addr + 2) = - (uint8_t) ((val & 0x00FF0000) >> 16); - *((uint8_t *) translated_addr + 3) = - (uint8_t) ((val & 0xFF000000) >> 24); - clr_ci(); - } - } - } else if (addr > M.mem_size) { - DEBUG_PRINTF("%s(%08x): Memory Access out of range!\n", - __FUNCTION__, addr); - //disassemble_forward(M.x86.saved_cs, M.x86.saved_ip, 1); - HALT_SYS(); - } else { - /* write to virtual memory */ - DEBUG_CHECK_VMEM_WRITE(addr, val); - out32le((void *) (M.mem_base + addr), val); - } -} - -//update time in BIOS Data Area -//DWord at offset 0x6c is the timer ticks since midnight, timer is running at 18Hz -//byte at 0x70 is timer overflow (set if midnight passed since last call to interrupt 1a function 00 -//cur_val is the current value, of offset 6c... -void -update_time(uint32_t cur_val) -{ - //for convenience, we let the start of timebase be at midnight, we currently dont support - //real daytime anyway... - uint64_t ticks_per_day = tb_freq * 60 * 24; - // at 18Hz a period is ~55ms, converted to ticks (tb_freq is ticks/second) - uint32_t period_ticks = (55 * tb_freq) / 1000; - uint64_t curr_time = get_time(); - uint64_t ticks_since_midnight = curr_time % ticks_per_day; - uint32_t periods_since_midnight = ticks_since_midnight / period_ticks; - // if periods since midnight is smaller than last value, set overflow - // at BDA Offset 0x70 - if (periods_since_midnight < cur_val) { - my_wrb(0x470, 1); - } - // store periods since midnight at BDA offset 0x6c - my_wrl(0x46c, periods_since_midnight); -} diff --git a/qemu/roms/SLOF/clients/net-snk/app/biosemu/mem.h b/qemu/roms/SLOF/clients/net-snk/app/biosemu/mem.h deleted file mode 100644 index f0fbad96c..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/biosemu/mem.h +++ /dev/null @@ -1,36 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2008 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -#ifndef _BIOSEMU_MEM_H_ -#define _BIOSEMU_MEM_H_ -#include <x86emu/x86emu.h> -#include <stdint.h> - -// read byte from memory -uint8_t my_rdb(uint32_t addr); - -//read word from memory -uint16_t my_rdw(uint32_t addr); - -//read long from memory -uint32_t my_rdl(uint32_t addr); - -//write byte to memory -void my_wrb(uint32_t addr, uint8_t val); - -//write word to memory -void my_wrw(uint32_t addr, uint16_t val); - -//write long to memory -void my_wrl(uint32_t addr, uint32_t val); - -#endif diff --git a/qemu/roms/SLOF/clients/net-snk/app/biosemu/vbe.c b/qemu/roms/SLOF/clients/net-snk/app/biosemu/vbe.c deleted file mode 100644 index 957a1f2a0..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/biosemu/vbe.c +++ /dev/null @@ -1,780 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2008 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include <stdint.h> -#include <cpu.h> - -#include "debug.h" - -#include <x86emu/x86emu.h> -#include <x86emu/regs.h> -#include <x86emu/prim_ops.h> // for push_word - -#include "biosemu.h" -#include "io.h" -#include "mem.h" -#include "interrupt.h" -#include "device.h" -#include "vbe.h" - -static X86EMU_memFuncs my_mem_funcs = { - my_rdb, my_rdw, my_rdl, - my_wrb, my_wrw, my_wrl -}; - -static X86EMU_pioFuncs my_pio_funcs = { - my_inb, my_inw, my_inl, - my_outb, my_outw, my_outl -}; - -// pointer to VBEInfoBuffer, set by vbe_prepare -uint8_t *vbe_info_buffer = 0; -// virtual BIOS Memory -uint8_t *biosmem; -uint32_t biosmem_size; - -// these structs are for input from and output to OF -typedef struct { - uint8_t display_type; // 0=NONE, 1= analog, 2=digital - uint16_t screen_width; - uint16_t screen_height; - uint16_t screen_linebytes; // bytes per line in framebuffer, may be more than screen_width - uint8_t color_depth; // color depth in bpp - uint32_t framebuffer_address; - uint8_t edid_block_zero[128]; -} __attribute__ ((__packed__)) screen_info_t; - -typedef struct { - uint8_t signature[4]; - uint16_t size_reserved; - uint8_t monitor_number; - uint16_t max_screen_width; - uint8_t color_depth; -} __attribute__ ((__packed__)) screen_info_input_t; - -// these structs only store a subset of the VBE defined fields -// only those needed. -typedef struct { - char signature[4]; - uint16_t version; - uint8_t *oem_string_ptr; - uint32_t capabilities; - uint16_t video_mode_list[256]; // lets hope we never have more than 256 video modes... - uint16_t total_memory; -} vbe_info_t; - -typedef struct { - uint16_t video_mode; - uint8_t mode_info_block[256]; - uint16_t attributes; - uint16_t linebytes; - uint16_t x_resolution; - uint16_t y_resolution; - uint8_t x_charsize; - uint8_t y_charsize; - uint8_t bits_per_pixel; - uint8_t memory_model; - uint32_t framebuffer_address; -} vbe_mode_info_t; - -typedef struct { - uint8_t port_number; // i.e. monitor number - uint8_t edid_transfer_time; - uint8_t ddc_level; - uint8_t edid_block_zero[128]; -} vbe_ddc_info_t; - -static inline uint8_t -vbe_prepare(void) -{ - vbe_info_buffer = biosmem + (VBE_SEGMENT << 4); // segment:offset off VBE Data Area - //clear buffer - memset(vbe_info_buffer, 0, 512); - //set VbeSignature to "VBE2" to indicate VBE 2.0+ request - vbe_info_buffer[0] = 'V'; - vbe_info_buffer[0] = 'B'; - vbe_info_buffer[0] = 'E'; - vbe_info_buffer[0] = '2'; - // ES:DI store pointer to buffer in virtual mem see vbe_info_buffer above... - M.x86.R_EDI = 0x0; - M.x86.R_ES = VBE_SEGMENT; - - return 0; // successful init -} - -// VBE Function 00h -static uint8_t -vbe_info(vbe_info_t * info) -{ - vbe_prepare(); - // call VBE function 00h (Info Function) - M.x86.R_EAX = 0x4f00; - - // enable trace - CHECK_DBG(DEBUG_TRACE_X86EMU) { - X86EMU_trace_on(); - } - // run VESA Interrupt - runInt10(); - - if (M.x86.R_AL != 0x4f) { - DEBUG_PRINTF_VBE("%s: VBE Info Function NOT supported! AL=%x\n", - __FUNCTION__, M.x86.R_AL); - return -1; - } - - if (M.x86.R_AH != 0x0) { - DEBUG_PRINTF_VBE - ("%s: VBE Info Function Return Code NOT OK! AH=%x\n", - __FUNCTION__, M.x86.R_AH); - return M.x86.R_AH; - } - //printf("VBE Info Dump:"); - //dump(vbe_info_buffer, 64); - - //offset 0: signature - info->signature[0] = vbe_info_buffer[0]; - info->signature[1] = vbe_info_buffer[1]; - info->signature[2] = vbe_info_buffer[2]; - info->signature[3] = vbe_info_buffer[3]; - - // offset 4: 16bit le containing VbeVersion - info->version = in16le(vbe_info_buffer + 4); - - // offset 6: 32bit le containg segment:offset of OEM String in virtual Mem. - info->oem_string_ptr = - biosmem + ((in16le(vbe_info_buffer + 8) << 4) + - in16le(vbe_info_buffer + 6)); - - // offset 10: 32bit le capabilities - info->capabilities = in32le(vbe_info_buffer + 10); - - // offset 14: 32 bit le containing segment:offset of supported video mode table - uint16_t *video_mode_ptr; - video_mode_ptr = - (uint16_t *) (biosmem + - ((in16le(vbe_info_buffer + 16) << 4) + - in16le(vbe_info_buffer + 14))); - uint32_t i = 0; - do { - info->video_mode_list[i] = in16le(video_mode_ptr + i); - i++; - } - while ((i < - (sizeof(info->video_mode_list) / - sizeof(info->video_mode_list[0]))) - && (info->video_mode_list[i - 1] != 0xFFFF)); - - //offset 18: 16bit le total memory in 64KB blocks - info->total_memory = in16le(vbe_info_buffer + 18); - - return 0; -} - -// VBE Function 01h -static uint8_t -vbe_get_mode_info(vbe_mode_info_t * mode_info) -{ - vbe_prepare(); - // call VBE function 01h (Return VBE Mode Info Function) - M.x86.R_EAX = 0x4f01; - M.x86.R_CX = mode_info->video_mode; - - // enable trace - CHECK_DBG(DEBUG_TRACE_X86EMU) { - X86EMU_trace_on(); - } - // run VESA Interrupt - runInt10(); - - if (M.x86.R_AL != 0x4f) { - DEBUG_PRINTF_VBE - ("%s: VBE Return Mode Info Function NOT supported! AL=%x\n", - __FUNCTION__, M.x86.R_AL); - return -1; - } - - if (M.x86.R_AH != 0x0) { - DEBUG_PRINTF_VBE - ("%s: VBE Return Mode Info (mode: %04x) Function Return Code NOT OK! AH=%02x\n", - __FUNCTION__, mode_info->video_mode, M.x86.R_AH); - return M.x86.R_AH; - } - //pointer to mode_info_block is in ES:DI - memcpy(mode_info->mode_info_block, - biosmem + ((M.x86.R_ES << 4) + M.x86.R_DI), - sizeof(mode_info->mode_info_block)); - - //printf("Mode Info Dump:"); - //dump(mode_info_block, 64); - - // offset 0: 16bit le mode attributes - mode_info->attributes = in16le(mode_info->mode_info_block); - - // offset 16: 16bit le bytes per scan line - mode_info->linebytes = in16le(mode_info->mode_info_block + 16); - - // offset 18: 16bit le x resolution - mode_info->x_resolution = in16le(mode_info->mode_info_block + 18); - - // offset 20: 16bit le y resolution - mode_info->y_resolution = in16le(mode_info->mode_info_block + 20); - - // offset 22: 8bit le x charsize - mode_info->x_charsize = *(mode_info->mode_info_block + 22); - - // offset 23: 8bit le y charsize - mode_info->y_charsize = *(mode_info->mode_info_block + 23); - - // offset 25: 8bit le bits per pixel - mode_info->bits_per_pixel = *(mode_info->mode_info_block + 25); - - // offset 27: 8bit le memory model - mode_info->memory_model = *(mode_info->mode_info_block + 27); - - // offset 40: 32bit le containg offset of frame buffer memory ptr - mode_info->framebuffer_address = - in32le(mode_info->mode_info_block + 40); - - return 0; -} - -// VBE Function 02h -static uint8_t -vbe_set_mode(vbe_mode_info_t * mode_info) -{ - vbe_prepare(); - // call VBE function 02h (Set VBE Mode Function) - M.x86.R_EAX = 0x4f02; - M.x86.R_BX = mode_info->video_mode; - M.x86.R_BX |= 0x4000; // set bit 14 to request linear framebuffer mode - M.x86.R_BX &= 0x7FFF; // clear bit 15 to request clearing of framebuffer - - DEBUG_PRINTF_VBE("%s: setting mode: 0x%04x\n", __FUNCTION__, - M.x86.R_BX); - - // enable trace - CHECK_DBG(DEBUG_TRACE_X86EMU) { - X86EMU_trace_on(); - } - // run VESA Interrupt - runInt10(); - - if (M.x86.R_AL != 0x4f) { - DEBUG_PRINTF_VBE - ("%s: VBE Set Mode Function NOT supported! AL=%x\n", - __FUNCTION__, M.x86.R_AL); - return -1; - } - - if (M.x86.R_AH != 0x0) { - DEBUG_PRINTF_VBE - ("%s: mode: %x VBE Set Mode Function Return Code NOT OK! AH=%x\n", - __FUNCTION__, mode_info->video_mode, M.x86.R_AH); - return M.x86.R_AH; - } - return 0; -} - -//VBE Function 08h -static uint8_t -vbe_set_palette_format(uint8_t format) -{ - vbe_prepare(); - // call VBE function 09h (Set/Get Palette Data Function) - M.x86.R_EAX = 0x4f08; - M.x86.R_BL = 0x00; // set format - M.x86.R_BH = format; - - DEBUG_PRINTF_VBE("%s: setting palette format: %d\n", __FUNCTION__, - format); - - // enable trace - CHECK_DBG(DEBUG_TRACE_X86EMU) { - X86EMU_trace_on(); - } - // run VESA Interrupt - runInt10(); - - if (M.x86.R_AL != 0x4f) { - DEBUG_PRINTF_VBE - ("%s: VBE Set Palette Format Function NOT supported! AL=%x\n", - __FUNCTION__, M.x86.R_AL); - return -1; - } - - if (M.x86.R_AH != 0x0) { - DEBUG_PRINTF_VBE - ("%s: VBE Set Palette Format Function Return Code NOT OK! AH=%x\n", - __FUNCTION__, M.x86.R_AH); - return M.x86.R_AH; - } - return 0; -} - -// VBE Function 09h -static uint8_t -vbe_set_color(uint16_t color_number, uint32_t color_value) -{ - vbe_prepare(); - // call VBE function 09h (Set/Get Palette Data Function) - M.x86.R_EAX = 0x4f09; - M.x86.R_BL = 0x00; // set color - M.x86.R_CX = 0x01; // set only one entry - M.x86.R_DX = color_number; - // ES:DI is address where color_value is stored, we store it at 2000:0000 - M.x86.R_ES = 0x2000; - M.x86.R_DI = 0x0; - - // store color value at ES:DI - out32le(biosmem + (M.x86.R_ES << 4) + M.x86.R_DI, color_value); - - DEBUG_PRINTF_VBE("%s: setting color #%x: 0x%04x\n", __FUNCTION__, - color_number, color_value); - - // enable trace - CHECK_DBG(DEBUG_TRACE_X86EMU) { - X86EMU_trace_on(); - } - // run VESA Interrupt - runInt10(); - - if (M.x86.R_AL != 0x4f) { - DEBUG_PRINTF_VBE - ("%s: VBE Set Palette Function NOT supported! AL=%x\n", - __FUNCTION__, M.x86.R_AL); - return -1; - } - - if (M.x86.R_AH != 0x0) { - DEBUG_PRINTF_VBE - ("%s: VBE Set Palette Function Return Code NOT OK! AH=%x\n", - __FUNCTION__, M.x86.R_AH); - return M.x86.R_AH; - } - return 0; -} - -#if 0 -static uint8_t -vbe_get_color(uint16_t color_number, uint32_t * color_value) -{ - vbe_prepare(); - // call VBE function 09h (Set/Get Palette Data Function) - M.x86.R_EAX = 0x4f09; - M.x86.R_BL = 0x00; // get color - M.x86.R_CX = 0x01; // get only one entry - M.x86.R_DX = color_number; - // ES:DI is address where color_value is stored, we store it at 2000:0000 - M.x86.R_ES = 0x2000; - M.x86.R_DI = 0x0; - - // enable trace - CHECK_DBG(DEBUG_TRACE_X86EMU) { - X86EMU_trace_on(); - } - // run VESA Interrupt - runInt10(); - - if (M.x86.R_AL != 0x4f) { - DEBUG_PRINTF_VBE - ("%s: VBE Set Palette Function NOT supported! AL=%x\n", - __FUNCTION__, M.x86.R_AL); - return -1; - } - - if (M.x86.R_AH != 0x0) { - DEBUG_PRINTF_VBE - ("%s: VBE Set Palette Function Return Code NOT OK! AH=%x\n", - __FUNCTION__, M.x86.R_AH); - return M.x86.R_AH; - } - // read color value from ES:DI - *color_value = in32le(biosmem + (M.x86.R_ES << 4) + M.x86.R_DI); - - DEBUG_PRINTF_VBE("%s: getting color #%x --> 0x%04x\n", __FUNCTION__, - color_number, *color_value); - - return 0; -} -#endif - -// VBE Function 15h -static uint8_t -vbe_get_ddc_info(vbe_ddc_info_t * ddc_info) -{ - vbe_prepare(); - // call VBE function 15h (DDC Info Function) - M.x86.R_EAX = 0x4f15; - M.x86.R_BL = 0x00; // get DDC Info - M.x86.R_CX = ddc_info->port_number; - M.x86.R_ES = 0x0; - M.x86.R_DI = 0x0; - - // enable trace - CHECK_DBG(DEBUG_TRACE_X86EMU) { - X86EMU_trace_on(); - } - // run VESA Interrupt - runInt10(); - - if (M.x86.R_AL != 0x4f) { - DEBUG_PRINTF_VBE - ("%s: VBE Get DDC Info Function NOT supported! AL=%x\n", - __FUNCTION__, M.x86.R_AL); - return -1; - } - - if (M.x86.R_AH != 0x0) { - DEBUG_PRINTF_VBE - ("%s: port: %x VBE Get DDC Info Function Return Code NOT OK! AH=%x\n", - __FUNCTION__, ddc_info->port_number, M.x86.R_AH); - return M.x86.R_AH; - } - // BH = approx. time in seconds to transfer one EDID block - ddc_info->edid_transfer_time = M.x86.R_BH; - // BL = DDC Level - ddc_info->ddc_level = M.x86.R_BL; - - vbe_prepare(); - // call VBE function 15h (DDC Info Function) - M.x86.R_EAX = 0x4f15; - M.x86.R_BL = 0x01; // read EDID - M.x86.R_CX = ddc_info->port_number; - M.x86.R_DX = 0x0; // block number - // ES:DI is address where EDID is stored, we store it at 2000:0000 - M.x86.R_ES = 0x2000; - M.x86.R_DI = 0x0; - - // enable trace - CHECK_DBG(DEBUG_TRACE_X86EMU) { - X86EMU_trace_on(); - } - // run VESA Interrupt - runInt10(); - - if (M.x86.R_AL != 0x4f) { - DEBUG_PRINTF_VBE - ("%s: VBE Read EDID Function NOT supported! AL=%x\n", - __FUNCTION__, M.x86.R_AL); - return -1; - } - - if (M.x86.R_AH != 0x0) { - DEBUG_PRINTF_VBE - ("%s: port: %x VBE Read EDID Function Return Code NOT OK! AH=%x\n", - __FUNCTION__, ddc_info->port_number, M.x86.R_AH); - return M.x86.R_AH; - } - - memcpy(ddc_info->edid_block_zero, - biosmem + (M.x86.R_ES << 4) + M.x86.R_DI, - sizeof(ddc_info->edid_block_zero)); - - return 0; -} - -uint32_t -vbe_get_info(uint8_t argc, char ** argv) -{ - uint8_t rval; - static const uint8_t valid_edid_sig[] = { - 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00 - }; - uint32_t i; - - if (argc < 4) { - printf - ("Usage %s <vmem_base> <device_path> <address of screen_info_t>\n", - argv[0]); - int i = 0; - for (i = 0; i < argc; i++) { - printf("argv[%d]: %s\n", i, argv[i]); - } - return -1; - } - // get a copy of input struct... - screen_info_input_t input = - *((screen_info_input_t *) strtoul((char *) argv[4], 0, 16)); - // output is pointer to the address passed as argv[4] - screen_info_t *output = - (screen_info_t *) strtoul((char *) argv[4], 0, 16); - // zero output - memset(output, 0, sizeof(screen_info_t)); - - // argv[1] is address of virtual BIOS mem... - // argv[2] is the size - biosmem = (uint8_t *) strtoul(argv[1], 0, 16); - biosmem_size = strtoul(argv[2], 0, 16);; - if (biosmem_size < MIN_REQUIRED_VMEM_SIZE) { - printf("Error: Not enough virtual memory: %x, required: %x!\n", - biosmem_size, MIN_REQUIRED_VMEM_SIZE); - return -1; - } - // argv[3] is the device to open and use... - if (dev_init((char *) argv[3]) != 0) { - printf("Error initializing device!\n"); - return -1; - } - //setup interrupt handler - X86EMU_intrFuncs intrFuncs[256]; - for (i = 0; i < 256; i++) - intrFuncs[i] = handleInterrupt; - X86EMU_setupIntrFuncs(intrFuncs); - X86EMU_setupPioFuncs(&my_pio_funcs); - X86EMU_setupMemFuncs(&my_mem_funcs); - - // set mem_base - M.mem_base = (long) biosmem; - M.mem_size = biosmem_size; - DEBUG_PRINTF_VBE("membase set: %08x, size: %08x\n", (int) M.mem_base, - (int) M.mem_size); - - vbe_info_t info; - rval = vbe_info(&info); - if (rval != 0) - return rval; - - DEBUG_PRINTF_VBE("VbeSignature: %s\n", info.signature); - DEBUG_PRINTF_VBE("VbeVersion: 0x%04x\n", info.version); - DEBUG_PRINTF_VBE("OemString: %s\n", info.oem_string_ptr); - DEBUG_PRINTF_VBE("Capabilities:\n"); - DEBUG_PRINTF_VBE("\tDAC: %s\n", - (info.capabilities & 0x1) == - 0 ? "fixed 6bit" : "switchable 6/8bit"); - DEBUG_PRINTF_VBE("\tVGA: %s\n", - (info.capabilities & 0x2) == - 0 ? "compatible" : "not compatible"); - DEBUG_PRINTF_VBE("\tRAMDAC: %s\n", - (info.capabilities & 0x4) == - 0 ? "normal" : "use blank bit in Function 09h"); - - // argv[4] may be a pointer with enough space to return screen_info_t - // as input, it must contain a screen_info_input_t with the following content: - // byte[0:3] = "DDC\0" (zero-terminated signature header) - // byte[4:5] = reserved space for the return struct... just in case we ever change - // the struct and dont have reserved enough memory (and let's hope the struct - // never gets larger than 64KB) - // byte[6] = monitor port number for DDC requests ("only" one byte... so lets hope we never have more than 255 monitors... - // byte[7:8] = max. screen width (OF may want to limit this) - // byte[9] = required color depth in bpp - if (strncmp((char *) input.signature, "DDC", 4) != 0) { - printf - ("%s: Invalid input signature! expected: %s, is: %s\n", - __FUNCTION__, "DDC", input.signature); - return -1; - } - if (input.size_reserved != sizeof(screen_info_t)) { - printf - ("%s: Size of return struct is wrong, required: %d, available: %d\n", - __FUNCTION__, (int) sizeof(screen_info_t), - input.size_reserved); - return -1; - } - - vbe_ddc_info_t ddc_info; - ddc_info.port_number = input.monitor_number; - vbe_get_ddc_info(&ddc_info); - -#if 0 - DEBUG_PRINTF_VBE("DDC: edid_tranfer_time: %d\n", - ddc_info.edid_transfer_time); - DEBUG_PRINTF_VBE("DDC: ddc_level: %x\n", ddc_info.ddc_level); - DEBUG_PRINTF_VBE("DDC: EDID: \n"); - CHECK_DBG(DEBUG_VBE) { - dump(ddc_info.edid_block_zero, - sizeof(ddc_info.edid_block_zero)); - } -#endif - if (memcmp(ddc_info.edid_block_zero, valid_edid_sig, 8) != 0) { - // invalid EDID signature... probably no monitor - output->display_type = 0x0; - return 0; - } else if ((ddc_info.edid_block_zero[20] & 0x80) != 0) { - // digital display - output->display_type = 2; - } else { - // analog - output->display_type = 1; - } - DEBUG_PRINTF_VBE("DDC: found display type %d\n", output->display_type); - memcpy(output->edid_block_zero, ddc_info.edid_block_zero, - sizeof(ddc_info.edid_block_zero)); - i = 0; - vbe_mode_info_t mode_info; - vbe_mode_info_t best_mode_info; - // initialize best_mode to 0 - memset(&best_mode_info, 0, sizeof(best_mode_info)); - while ((mode_info.video_mode = info.video_mode_list[i]) != 0xFFFF) { - //DEBUG_PRINTF_VBE("%x: Mode: %04x\n", i, mode_info.video_mode); - vbe_get_mode_info(&mode_info); -#if 0 - DEBUG_PRINTF_VBE("Video Mode 0x%04x available, %s\n", - mode_info.video_mode, - (mode_info.attributes & 0x1) == - 0 ? "not supported" : "supported"); - DEBUG_PRINTF_VBE("\tTTY: %s\n", - (mode_info.attributes & 0x4) == - 0 ? "no" : "yes"); - DEBUG_PRINTF_VBE("\tMode: %s %s\n", - (mode_info.attributes & 0x8) == - 0 ? "monochrome" : "color", - (mode_info.attributes & 0x10) == - 0 ? "text" : "graphics"); - DEBUG_PRINTF_VBE("\tVGA: %s\n", - (mode_info.attributes & 0x20) == - 0 ? "compatible" : "not compatible"); - DEBUG_PRINTF_VBE("\tWindowed Mode: %s\n", - (mode_info.attributes & 0x40) == - 0 ? "yes" : "no"); - DEBUG_PRINTF_VBE("\tFramebuffer: %s\n", - (mode_info.attributes & 0x80) == - 0 ? "no" : "yes"); - DEBUG_PRINTF_VBE("\tResolution: %dx%d\n", - mode_info.x_resolution, - mode_info.y_resolution); - DEBUG_PRINTF_VBE("\tChar Size: %dx%d\n", - mode_info.x_charsize, mode_info.y_charsize); - DEBUG_PRINTF_VBE("\tColor Depth: %dbpp\n", - mode_info.bits_per_pixel); - DEBUG_PRINTF_VBE("\tMemory Model: 0x%x\n", - mode_info.memory_model); - DEBUG_PRINTF_VBE("\tFramebuffer Offset: %08x\n", - mode_info.framebuffer_address); -#endif - if ((mode_info.bits_per_pixel == input.color_depth) - && (mode_info.x_resolution <= input.max_screen_width) - && ((mode_info.attributes & 0x80) != 0) // framebuffer mode - && ((mode_info.attributes & 0x10) != 0) // graphics - && ((mode_info.attributes & 0x8) != 0) // color - && (mode_info.x_resolution > best_mode_info.x_resolution)) // better than previous best_mode - { - // yiiiihaah... we found a new best mode - memcpy(&best_mode_info, &mode_info, sizeof(mode_info)); - } - i++; - } - - if (best_mode_info.video_mode != 0) { - DEBUG_PRINTF_VBE - ("Best Video Mode found: 0x%x, %dx%d, %dbpp, framebuffer_address: 0x%x\n", - best_mode_info.video_mode, - best_mode_info.x_resolution, - best_mode_info.y_resolution, - best_mode_info.bits_per_pixel, - best_mode_info.framebuffer_address); - - //printf("Mode Info Dump:"); - //dump(best_mode_info.mode_info_block, 64); - - // set the video mode - vbe_set_mode(&best_mode_info); - - if ((info.capabilities & 0x1) != 0) { - // switch to 8 bit palette format - vbe_set_palette_format(8); - } - // setup a palette: - // - first 216 colors are mixed colors for each component in 6 steps - // (6*6*6=216) - // - then 10 shades of the three primary colors - // - then 10 shades of grey - // ------- - // = 256 colors - // - // - finally black is color 0 and white color FF (because SLOF expects it - // this way...) - // this resembles the palette that the kernel/X Server seems to expect... - - uint8_t mixed_color_values[6] = - { 0xFF, 0xDA, 0xB3, 0x87, 0x54, 0x00 }; - uint8_t primary_color_values[10] = - { 0xF3, 0xE7, 0xCD, 0xC0, 0xA5, 0x96, 0x77, 0x66, 0x3F, - 0x27 - }; - uint8_t mc_size = sizeof(mixed_color_values); - uint8_t prim_size = sizeof(primary_color_values); - - uint8_t curr_color_index; - uint32_t curr_color; - - uint8_t r, g, b; - // 216 mixed colors - for (r = 0; r < mc_size; r++) { - for (g = 0; g < mc_size; g++) { - for (b = 0; b < mc_size; b++) { - curr_color_index = - (r * mc_size * mc_size) + - (g * mc_size) + b; - curr_color = 0; - curr_color |= ((uint32_t) mixed_color_values[r]) << 16; //red value - curr_color |= ((uint32_t) mixed_color_values[g]) << 8; //green value - curr_color |= (uint32_t) mixed_color_values[b]; //blue value - vbe_set_color(curr_color_index, - curr_color); - } - } - } - - // 10 shades of each primary color - // red - for (r = 0; r < prim_size; r++) { - curr_color_index = mc_size * mc_size * mc_size + r; - curr_color = ((uint32_t) primary_color_values[r]) << 16; - vbe_set_color(curr_color_index, curr_color); - } - //green - for (g = 0; g < prim_size; g++) { - curr_color_index = - mc_size * mc_size * mc_size + prim_size + g; - curr_color = ((uint32_t) primary_color_values[g]) << 8; - vbe_set_color(curr_color_index, curr_color); - } - //blue - for (b = 0; b < prim_size; b++) { - curr_color_index = - mc_size * mc_size * mc_size + prim_size * 2 + b; - curr_color = (uint32_t) primary_color_values[b]; - vbe_set_color(curr_color_index, curr_color); - } - // 10 shades of grey - for (i = 0; i < prim_size; i++) { - curr_color_index = - mc_size * mc_size * mc_size + prim_size * 3 + i; - curr_color = 0; - curr_color |= ((uint32_t) primary_color_values[i]) << 16; //red - curr_color |= ((uint32_t) primary_color_values[i]) << 8; //green - curr_color |= ((uint32_t) primary_color_values[i]); //blue - vbe_set_color(curr_color_index, curr_color); - } - - // SLOF is using color 0x0 (black) and 0xFF (white) to draw to the screen... - vbe_set_color(0x00, 0x00000000); - vbe_set_color(0xFF, 0x00FFFFFF); - - output->screen_width = best_mode_info.x_resolution; - output->screen_height = best_mode_info.y_resolution; - output->screen_linebytes = best_mode_info.linebytes; - output->color_depth = best_mode_info.bits_per_pixel; - output->framebuffer_address = - best_mode_info.framebuffer_address; - } else { - printf("%s: No suitable video mode found!\n", __FUNCTION__); - //unset display_type... - output->display_type = 0; - } - return 0; -} diff --git a/qemu/roms/SLOF/clients/net-snk/app/biosemu/vbe.h b/qemu/roms/SLOF/clients/net-snk/app/biosemu/vbe.h deleted file mode 100644 index 17e982632..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/biosemu/vbe.h +++ /dev/null @@ -1,18 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2008 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -#ifndef _BIOSEMU_VBE_H_ -#define _BIOSEMU_VBE_H_ - -uint32_t vbe_get_info(uint8_t argc, char ** argv); - -#endif diff --git a/qemu/roms/SLOF/clients/net-snk/app/main.c b/qemu/roms/SLOF/clients/net-snk/app/main.c deleted file mode 100644 index 90e14b370..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/main.c +++ /dev/null @@ -1,77 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2011 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -#include <string.h> -#include <stdio.h> -#include <of.h> -#include <netapps/netapps.h> -#include <libbootmsg.h> - -#ifdef SNK_BIOSEMU_APPS -#include "biosemu/biosemu.h" -#include "biosemu/vbe.h" -#endif - -extern void _callback_entry(void); -int callback(int argc, char *argv[]); - - -int -main(int argc, char *argv[]) -{ - int i; - of_set_callback((void *) &_callback_entry); - - if (strcmp(argv[0], "netboot") == 0 && argc >= 5) - return netboot(argc, argv); - if (strcmp(argv[0], "ping") == 0) - return ping(argc, argv); -#ifdef SNK_BIOSEMU_APPS - // BIOS Emulator applications - if (strcmp(argv[0], "biosemu") == 0) - return biosemu(argc, argv); - if (strcmp(argv[0], "get_vbe_info") == 0) - return vbe_get_info(argc, argv); -#endif - - printf("Unknown client application called\n"); - for (i = 0; i < argc; i++) - printf("argv[%d] %s\n", i, argv[i]); - - return -1; -} - -int -callback(int argc, char *argv[]) -{ - int i; - - printf("\n"); - - /* - * Register your application's callback handler here, similar to - * the way you would register an application. - * Please note that callback functions can be called safely only after - * your application has called of_yield(). If you return or exit() from - * your client application, the callback can no longer be used. - */ -#if 0 - if (strcmp(argv[0], "example") == 0) - return example(argc, argv); -#endif - - printf("No such callback function\n"); - for (i = 0; i < argc; i++) - printf("argv[%d] %s\n", i, argv[i]); - - return (-1); -} diff --git a/qemu/roms/SLOF/clients/net-snk/app/netapps/Makefile b/qemu/roms/SLOF/clients/net-snk/app/netapps/Makefile deleted file mode 100644 index 70b990a77..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/netapps/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -# ***************************************************************************** -# * Copyright (c) 2004, 2008 IBM Corporation -# * All rights reserved. -# * This program and the accompanying materials -# * are made available under the terms of the BSD License -# * which accompanies this distribution, and is available at -# * http://www.opensource.org/licenses/bsd-license.php -# * -# * Contributors: -# * IBM Corporation - initial implementation -# ****************************************************************************/ - -ifndef TOP - TOP = $(shell while ! test -e make.rules; do cd .. ; done; pwd) - export TOP -endif -include $(TOP)/make.rules - -CFLAGS += -I../ -I../../../../lib/ -Wall -W - -OBJS = netboot.o ping.o args.o - -all: $(OBJS) - -clean: - $(RM) -f *.o *.a *.i - -include $(TOP)/make.depend diff --git a/qemu/roms/SLOF/clients/net-snk/app/netapps/args.c b/qemu/roms/SLOF/clients/net-snk/app/netapps/args.c deleted file mode 100644 index 52215e6a7..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/netapps/args.c +++ /dev/null @@ -1,143 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2008 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -#include <stdint.h> -#include <ctype.h> -#include <stdlib.h> -#include <string.h> -#include "args.h" - -/** - * Returns pointer of the n'th argument within a string. - * - * @param arg_str string with arguments, separated with ',' - * @param index index of the requested arguments within arg_str - * @return pointer of argument[index] on success - * NULL if index is out of range - */ -const char * -get_arg_ptr(const char *arg_str, unsigned int index) -{ - unsigned int i; - - for (i = 0; i < index; ++i) { - for (; *arg_str != ',' && *arg_str != 0; ++arg_str); - if (*arg_str == 0) - return 0; - ++arg_str; - } - return arg_str; -} - -/** - * Returns number of arguments within a string. - * - * @param arg_str string with arguments, separated with ',' - * @return number of arguments - */ -unsigned int -get_args_count(const char *arg_str) -{ - unsigned int count = 1; - - while ((arg_str = get_arg_ptr(arg_str, 1)) != 0) - ++count; - return count; -} - -/** - * Returns the length of the first argument. - * - * @param arg_str string with arguments, separated with ',' - * @return length of first argument - */ -unsigned int -get_arg_length(const char *arg_str) -{ - unsigned int i; - - for (i = 0; *arg_str != ',' && *arg_str != 0; ++i) - ++arg_str; - return i; -} - -/** - * Copy the n'th argument within a string into a buffer in respect - * to a limited buffer size - * - * @param arg_str string with arguments, separated with ',' - * @param index index of the requested arguments within arg_str - * @param buffer pointer to the buffer - * @param length size of the buffer - * @return pointer of buffer on success - * NULL if index is out of range. - */ -char * -argncpy(const char *arg_str, unsigned int index, char *buffer, - unsigned int length) -{ - const char *ptr = get_arg_ptr(arg_str, index); - unsigned int len; - - if (!ptr) - return 0; - len = get_arg_length(ptr); - if (!strncpy(buffer, ptr, length)) - return 0; - buffer[len] = 0; - return buffer; -} - -/** - * Converts "255.255.255.255" -> char[4] = { 0xff, 0xff, 0xff, 0xff } - * - * @param str string to be converted - * @param ip in case of SUCCESS - 32-bit long IP - in case of FAULT - zero - * @return TRUE - IP converted successfully; - * FALSE - error condition occurs (e.g. bad format) - */ -int -strtoip(const char *str, char ip[4]) -{ - char octet[10]; - int res; - unsigned int i = 0, len; - - while (*str != 0) { - if (i > 3 || !isdigit(*str)) - return 0; - if (strstr(str, ".") != NULL) { - len = (int16_t) (strstr(str, ".") - str); - if (len >= 10) - return 0; - strncpy(octet, str, len); - octet[len] = 0; - str += len; - } else { - strncpy(octet, str, 9); - octet[9] = 0; - str += strlen(octet); - } - res = strtol(octet, NULL, 10); - if ((res > 255) || (res < 0)) - return 0; - ip[i] = (char) res; - i++; - if (*str == '.') - str++; - } - - if (i != 4) - return 0; - return -1; -} diff --git a/qemu/roms/SLOF/clients/net-snk/app/netapps/args.h b/qemu/roms/SLOF/clients/net-snk/app/netapps/args.h deleted file mode 100644 index b80982a39..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/netapps/args.h +++ /dev/null @@ -1,22 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2008 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -#ifndef _ARGS_H -#define _ARGS_H - -const char *get_arg_ptr(const char *, unsigned int); -unsigned int get_args_count(const char *); -unsigned int get_arg_length(const char *); -char *argncpy(const char *, unsigned int, char *, unsigned int); -int strtoip(const char *, char[4]); - -#endif /* _ARGS_H */ diff --git a/qemu/roms/SLOF/clients/net-snk/app/netapps/netapps.h b/qemu/roms/SLOF/clients/net-snk/app/netapps/netapps.h deleted file mode 100644 index 18e607f53..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/netapps/netapps.h +++ /dev/null @@ -1,30 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2008 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -#ifndef _NETAPPS_H_ -#define _NETAPPS_H_ - -#include <netlib/tftp.h> - -#define F_IPV4 4 -#define F_IPV6 6 - -int netboot(int argc, char *argv[]); -int netsave(int argc, char *argv[]); -int netflash(int argc, char *argv[]); -int bcmflash(int argc, char *argv[]); -int mac_sync(int argc, char *argv[]); -int net_eeprom_version( void ); -int ping(int argc, char *argv[]); -int dhcp(char *ret_buffer, filename_ip_t * fn_ip, unsigned int retries, int flags); - -#endif diff --git a/qemu/roms/SLOF/clients/net-snk/app/netapps/netboot.c b/qemu/roms/SLOF/clients/net-snk/app/netapps/netboot.c deleted file mode 100644 index bb1db03e3..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/netapps/netboot.c +++ /dev/null @@ -1,858 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2008 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -#include <netlib/tftp.h> -#include <netlib/ethernet.h> -#include <netlib/dhcp.h> -#include <netlib/dhcpv6.h> -#include <netlib/ipv4.h> -#include <netlib/ipv6.h> -#include <netlib/dns.h> -#include <string.h> -#include <stdio.h> -#include <time.h> -#include <stdlib.h> -#include <sys/socket.h> -#include <netapps/args.h> -#include <libbootmsg/libbootmsg.h> -#include <of.h> -#include "netapps.h" - -#define IP_INIT_DEFAULT 5 -#define IP_INIT_NONE 0 -#define IP_INIT_BOOTP 1 -#define IP_INIT_DHCP 2 -#define IP_INIT_DHCPV6_STATELESS 3 -#define IP_INIT_IPV6_MANUAL 4 - -#define DEFAULT_BOOT_RETRIES 10 -#define DEFAULT_TFTP_RETRIES 20 -static int ip_version = 4; - -typedef struct { - char filename[100]; - int ip_init; - char siaddr[4]; - ip6_addr_t si6addr; - char ciaddr[4]; - ip6_addr_t ci6addr; - char giaddr[4]; - ip6_addr_t gi6addr; - int bootp_retries; - int tftp_retries; -} obp_tftp_args_t; - - -/** - * Parses a argument string for IPv6 booting, extracts all - * parameters and fills a structure accordingly - * - * @param arg_str string with arguments, separated with ',' - * @param argc number of arguments - * @param obp_tftp_args structure which contains the result - * @return updated arg_str - */ -static const char * -parse_ipv6args (const char *arg_str, unsigned int argc, - obp_tftp_args_t *obp_tftp_args) -{ - char *ptr = NULL; - char arg_buf[100]; - - // find out siaddr - if (argc == 0) - memset(&obp_tftp_args->si6addr.addr, 0, 16); - else { - argncpy(arg_str, 0, arg_buf, 100); - if(str_to_ipv6(arg_buf, (uint8_t *) &(obp_tftp_args->si6addr.addr[0]))) { - arg_str = get_arg_ptr(arg_str, 1); - --argc; - } - else if(arg_buf[0] == 0) { - memset(&obp_tftp_args->si6addr.addr, 0, 16); - arg_str = get_arg_ptr(arg_str, 1); - --argc; - } - else - memset(&obp_tftp_args->si6addr.addr, 0, 16); - } - - // find out filename - if (argc == 0) - obp_tftp_args->filename[0] = 0; - else { - argncpy(arg_str, 0, obp_tftp_args->filename, 100); - for(ptr = obp_tftp_args->filename; *ptr != 0; ++ptr) - if(*ptr == '\\') { - *ptr = '/'; - } - arg_str = get_arg_ptr(arg_str, 1); - --argc; - } - - // find out ciaddr - if (argc == 0) - memset(&obp_tftp_args->ci6addr, 0, 16); - else { - argncpy(arg_str, 0, arg_buf, 100); - if (str_to_ipv6(arg_buf, (uint8_t *) &(obp_tftp_args->ci6addr.addr[0]))) { - arg_str = get_arg_ptr(arg_str, 1); - --argc; - } - else if(arg_buf[0] == 0) { - memset(&obp_tftp_args->ci6addr.addr, 0, 16); - arg_str = get_arg_ptr(arg_str, 1); - --argc; - } - else - memset(&obp_tftp_args->ci6addr.addr, 0, 16); - } - - // find out giaddr - if (argc == 0) - memset(&obp_tftp_args->gi6addr, 0, 16); - else { - argncpy(arg_str, 0, arg_buf, 100); - if (str_to_ipv6(arg_buf, (uint8_t *) &(obp_tftp_args->gi6addr.addr)) ) { - arg_str = get_arg_ptr(arg_str, 1); - --argc; - } - else if(arg_buf[0] == 0) { - memset(&obp_tftp_args->gi6addr, 0, 16); - arg_str = get_arg_ptr(arg_str, 1); - --argc; - } - else - memset(&obp_tftp_args->gi6addr.addr, 0, 16); - } - - return arg_str; -} - - -/** - * Parses a argument string for IPv4 booting, extracts all - * parameters and fills a structure accordingly - * - * @param arg_str string with arguments, separated with ',' - * @param argc number of arguments - * @param obp_tftp_args structure which contains the result - * @return updated arg_str - */ -static const char * -parse_ipv4args (const char *arg_str, unsigned int argc, - obp_tftp_args_t *obp_tftp_args) -{ - char *ptr = NULL; - char arg_buf[100]; - - // find out siaddr - if(argc==0) { - memset(obp_tftp_args->siaddr, 0, 4); - } else { - argncpy(arg_str, 0, arg_buf, 100); - if(strtoip(arg_buf, obp_tftp_args->siaddr)) { - arg_str = get_arg_ptr(arg_str, 1); - --argc; - } - else if(arg_buf[0] == 0) { - memset(obp_tftp_args->siaddr, 0, 4); - arg_str = get_arg_ptr(arg_str, 1); - --argc; - } - else - memset(obp_tftp_args->siaddr, 0, 4); - } - - // find out filename - if(argc==0) - obp_tftp_args->filename[0] = 0; - else { - argncpy(arg_str, 0, obp_tftp_args->filename, 100); - for(ptr = obp_tftp_args->filename; *ptr != 0; ++ptr) - if(*ptr == '\\') - *ptr = '/'; - arg_str = get_arg_ptr(arg_str, 1); - --argc; - } - - // find out ciaddr - if(argc==0) - memset(obp_tftp_args->ciaddr, 0, 4); - else { - argncpy(arg_str, 0, arg_buf, 100); - if(strtoip(arg_buf, obp_tftp_args->ciaddr)) { - arg_str = get_arg_ptr(arg_str, 1); - --argc; - } - else if(arg_buf[0] == 0) { - memset(obp_tftp_args->ciaddr, 0, 4); - arg_str = get_arg_ptr(arg_str, 1); - --argc; - } - else - memset(obp_tftp_args->ciaddr, 0, 4); - } - - // find out giaddr - if(argc==0) - memset(obp_tftp_args->giaddr, 0, 4); - else { - argncpy(arg_str, 0, arg_buf, 100); - if(strtoip(arg_buf, obp_tftp_args->giaddr)) { - arg_str = get_arg_ptr(arg_str, 1); - --argc; - } - else if(arg_buf[0] == 0) { - memset(obp_tftp_args->giaddr, 0, 4); - arg_str = get_arg_ptr(arg_str, 1); - --argc; - } - else - memset(obp_tftp_args->giaddr, 0, 4); - } - - return arg_str; -} - -/** - * Parses a argument string which is given by netload, extracts all - * parameters and fills a structure according to this - * - * Netload-Parameters: - * [bootp,]siaddr,filename,ciaddr,giaddr,bootp-retries,tftp-retries - * - * @param arg_str string with arguments, separated with ',' - * @param obp_tftp_args structure which contains the result - * @return none - */ -static void -parse_args(const char *arg_str, obp_tftp_args_t *obp_tftp_args) -{ - unsigned int argc; - char arg_buf[100]; - - memset(obp_tftp_args, 0, sizeof(*obp_tftp_args)); - - argc = get_args_count(arg_str); - - // find out if we should use BOOTP or DHCP - if(argc==0) - obp_tftp_args->ip_init = IP_INIT_DEFAULT; - else { - argncpy(arg_str, 0, arg_buf, 100); - if (strcasecmp(arg_buf, "bootp") == 0) { - obp_tftp_args->ip_init = IP_INIT_BOOTP; - arg_str = get_arg_ptr(arg_str, 1); - --argc; - } - else if(strcasecmp(arg_buf, "dhcp") == 0) { - obp_tftp_args->ip_init = IP_INIT_DHCP; - arg_str = get_arg_ptr(arg_str, 1); - --argc; - } - else if(strcasecmp(arg_buf, "ipv6") == 0) { - obp_tftp_args->ip_init = IP_INIT_DHCPV6_STATELESS; - arg_str = get_arg_ptr(arg_str, 1); - --argc; - ip_version = 6; - } - else - obp_tftp_args->ip_init = IP_INIT_DEFAULT; - } - - if (ip_version == 4) { - arg_str = parse_ipv4args (arg_str, argc, obp_tftp_args); - } - else if (ip_version == 6) { - arg_str = parse_ipv6args (arg_str, argc, obp_tftp_args); - } - - // find out bootp-retries - if (argc == 0) - obp_tftp_args->bootp_retries = DEFAULT_BOOT_RETRIES; - else { - argncpy(arg_str, 0, arg_buf, 100); - if(arg_buf[0] == 0) - obp_tftp_args->bootp_retries = DEFAULT_BOOT_RETRIES; - else { - obp_tftp_args->bootp_retries = strtol(arg_buf, 0, 10); - if(obp_tftp_args->bootp_retries < 0) - obp_tftp_args->bootp_retries = DEFAULT_BOOT_RETRIES; - } - arg_str = get_arg_ptr(arg_str, 1); - --argc; - } - - // find out tftp-retries - if (argc == 0) - obp_tftp_args->tftp_retries = DEFAULT_TFTP_RETRIES; - else { - argncpy(arg_str, 0, arg_buf, 100); - if(arg_buf[0] == 0) - obp_tftp_args->tftp_retries = DEFAULT_TFTP_RETRIES; - else { - obp_tftp_args->tftp_retries = strtol(arg_buf, 0, 10); - if(obp_tftp_args->tftp_retries < 0) - obp_tftp_args->tftp_retries = DEFAULT_TFTP_RETRIES; - } - arg_str = get_arg_ptr(arg_str, 1); - --argc; - } -} - -/** - * DHCP: Wrapper for obtaining IP and configuration info from DHCP server - * for both IPv4 and IPv6. - * (makes several attempts). - * - * @param ret_buffer buffer for returning BOOTP-REPLY packet data - * @param fn_ip contains the following configuration information: - * client MAC, client IP, TFTP-server MAC, - * TFTP-server IP, Boot file name - * @param retries No. of DHCP attempts - * @param flags flags for specifying type of dhcp attempt (IPv4/IPv6) - * ZERO - attempt DHCPv4 followed by DHCPv6 - * F_IPV4 - attempt only DHCPv4 - * F_IPV6 - attempt only DHCPv6 - * @return ZERO - IP and configuration info obtained; - * NON ZERO - error condition occurs. - */ -int dhcp(char *ret_buffer, filename_ip_t * fn_ip, unsigned int retries, int flags) -{ - int i = (int) retries+1; - int rc = -1; - - printf(" Requesting information via DHCP%s: ", - flags == F_IPV4 ? "v4" : flags == F_IPV6 ? "v6" : ""); - - if (flags != F_IPV6) - dhcpv4_generate_transaction_id(); - if (flags != F_IPV4) - dhcpv6_generate_transaction_id(); - - do { - printf("\b\b\b%03d", i-1); - if (getchar() == 27) { - printf("\nAborted\n"); - return -1; - } - if (!--i) { - printf("\nGiving up after %d DHCP requests\n", retries); - return -1; - } - if (!flags || (flags == F_IPV4)) { - ip_version = 4; - rc = dhcpv4(ret_buffer, fn_ip); - } - if ((!flags && (rc == -1)) || (flags == F_IPV6)) { - ip_version = 6; - set_ipv6_address(fn_ip->fd, 0); - rc = dhcpv6(ret_buffer, fn_ip); - if (rc == 0) { - memcpy(&fn_ip->own_ip6, get_ipv6_address(), 16); - break; - } - - } - if (rc != -1) /* either success or non-dhcp failure */ - break; - } while (1); - printf("\b\b\b\bdone\n"); - - return rc; -} - -/** - * Seed the random number generator with our mac and current timestamp - */ -static void seed_rng(uint8_t mac[]) -{ - unsigned int seed; - - asm volatile("mftbl %0" : "=r"(seed)); - seed ^= (mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5]; - srand(seed); -} - -int -netboot(int argc, char *argv[]) -{ - char buf[256]; - int rc; - int len = strtol(argv[2], 0, 16); - char *buffer = (char *) strtol(argv[1], 0, 16); - char *ret_buffer = (char *) strtol(argv[3], 0, 16); - filename_ip_t fn_ip; - int fd_device; - tftp_err_t tftp_err; - obp_tftp_args_t obp_tftp_args; - char null_ip[4] = { 0x00, 0x00, 0x00, 0x00 }; - char null_ip6[16] = { 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 }; - int huge_load = strtol(argv[4], 0, 10); - int32_t block_size = strtol(argv[5], 0, 10); - uint8_t own_mac[6]; - - puts("\n Initializing NIC"); - memset(&fn_ip, 0, sizeof(filename_ip_t)); - - /*********************************************************** - * - * Initialize network stuff and retrieve boot informations - * - ***********************************************************/ - - /* Wait for link up and get mac_addr from device */ - for(rc=0; rc<DEFAULT_BOOT_RETRIES; ++rc) { - if(rc > 0) { - set_timer(TICKS_SEC); - while (get_timer() > 0); - } - fd_device = socket(0, 0, 0, (char*) own_mac); - if(fd_device != -2) - break; - if(getchar() == 27) { - fd_device = -2; - break; - } - } - - if (fd_device == -1) { - strcpy(buf,"E3000: (net) Could not read MAC address"); - bootmsg_error(0x3000, &buf[7]); - - write_mm_log(buf, strlen(buf), 0x91); - return -100; - } - else if (fd_device == -2) { - strcpy(buf,"E3006: (net) Could not initialize network device"); - bootmsg_error(0x3006, &buf[7]); - - write_mm_log(buf, strlen(buf), 0x91); - return -101; - } - - fn_ip.fd = fd_device; - - printf(" Reading MAC address from device: " - "%02x:%02x:%02x:%02x:%02x:%02x\n", - own_mac[0], own_mac[1], own_mac[2], - own_mac[3], own_mac[4], own_mac[5]); - - // init ethernet layer - set_mac_address(own_mac); - - seed_rng(own_mac); - - if (argc > 6) { - parse_args(argv[6], &obp_tftp_args); - if(obp_tftp_args.bootp_retries - rc < DEFAULT_BOOT_RETRIES) - obp_tftp_args.bootp_retries = DEFAULT_BOOT_RETRIES; - else - obp_tftp_args.bootp_retries -= rc; - } - else { - memset(&obp_tftp_args, 0, sizeof(obp_tftp_args_t)); - obp_tftp_args.ip_init = IP_INIT_DEFAULT; - obp_tftp_args.bootp_retries = DEFAULT_BOOT_RETRIES; - obp_tftp_args.tftp_retries = DEFAULT_TFTP_RETRIES; - } - memcpy(&fn_ip.own_ip, obp_tftp_args.ciaddr, 4); - - // reset of error code - rc = 0; - - /* if we still have got all necessary parameters, then we don't - need to perform an BOOTP/DHCP-Request */ - if (ip_version == 4) { - if (memcmp(obp_tftp_args.ciaddr, null_ip, 4) != 0 - && memcmp(obp_tftp_args.siaddr, null_ip, 4) != 0 - && obp_tftp_args.filename[0] != 0) { - - memcpy(&fn_ip.server_ip, &obp_tftp_args.siaddr, 4); - obp_tftp_args.ip_init = IP_INIT_NONE; - } - } - else if (ip_version == 6) { - if (memcmp(&obp_tftp_args.si6addr, null_ip6, 16) != 0 - && obp_tftp_args.filename[0] != 0) { - memcpy(&fn_ip.server_ip6.addr[0], - &obp_tftp_args.si6addr.addr, 16); - obp_tftp_args.ip_init = IP_INIT_IPV6_MANUAL; - } - else { - obp_tftp_args.ip_init = IP_INIT_DHCPV6_STATELESS; - } - } - - // construction of fn_ip from parameter - switch(obp_tftp_args.ip_init) { - case IP_INIT_BOOTP: - // if giaddr in not specified, then we have to identify - // the BOOTP server via broadcasts - if(memcmp(obp_tftp_args.giaddr, null_ip, 4) == 0) { - // don't do this, when using DHCP !!! - fn_ip.server_ip = 0xFFFFFFFF; - } - // if giaddr is specified, then we have to use this - // IP address as proxy to identify the BOOTP server - else { - memcpy(&fn_ip.server_ip, obp_tftp_args.giaddr, 4); - } - rc = bootp(ret_buffer, &fn_ip, obp_tftp_args.bootp_retries); - break; - case IP_INIT_DHCP: - rc = dhcp(ret_buffer, &fn_ip, obp_tftp_args.bootp_retries, F_IPV4); - break; - case IP_INIT_DHCPV6_STATELESS: - rc = dhcp(ret_buffer, &fn_ip, - obp_tftp_args.bootp_retries, F_IPV6); - break; - case IP_INIT_IPV6_MANUAL: - if (memcmp(&obp_tftp_args.ci6addr, null_ip6, 16)) { - set_ipv6_address(fn_ip.fd, &obp_tftp_args.ci6addr); - } else { - /* - * If no client address has been specified, then - * use a link-local or stateless autoconfig address - */ - set_ipv6_address(fn_ip.fd, NULL); - memcpy(&fn_ip.own_ip6, get_ipv6_address(), 16); - } - break; - case IP_INIT_DEFAULT: - rc = dhcp(ret_buffer, &fn_ip, obp_tftp_args.bootp_retries, 0); - break; - case IP_INIT_NONE: - default: - break; - } - - if(rc >= 0 && ip_version == 4) { - if(memcmp(obp_tftp_args.ciaddr, null_ip, 4) != 0 - && memcmp(obp_tftp_args.ciaddr, &fn_ip.own_ip, 4) != 0) - memcpy(&fn_ip.own_ip, obp_tftp_args.ciaddr, 4); - - if(memcmp(obp_tftp_args.siaddr, null_ip, 4) != 0 - && memcmp(obp_tftp_args.siaddr, &fn_ip.server_ip, 4) != 0) - memcpy(&fn_ip.server_ip, obp_tftp_args.siaddr, 4); - - // init IPv4 layer - set_ipv4_address(fn_ip.own_ip); - } - else if (rc >= 0 && ip_version == 6) { - if(memcmp(&obp_tftp_args.ci6addr.addr, null_ip6, 16) != 0 - && memcmp(&obp_tftp_args.ci6addr.addr, &fn_ip.own_ip6, 16) != 0) - memcpy(&fn_ip.own_ip6, &obp_tftp_args.ci6addr.addr, 16); - - if(memcmp(&obp_tftp_args.si6addr.addr, null_ip6, 16) != 0 - && memcmp(&obp_tftp_args.si6addr.addr, &fn_ip.server_ip6.addr, 16) != 0) - memcpy(&fn_ip.server_ip6.addr, &obp_tftp_args.si6addr.addr, 16); - } - if (rc == -1) { - strcpy(buf,"E3001: (net) Could not get IP address"); - bootmsg_error(0x3001, &buf[7]); - - write_mm_log(buf, strlen(buf), 0x91); - return -101; - } - - if (ip_version == 4) { - printf(" Using IPv4 address: %d.%d.%d.%d\n", - ((fn_ip.own_ip >> 24) & 0xFF), ((fn_ip.own_ip >> 16) & 0xFF), - ((fn_ip.own_ip >> 8) & 0xFF), ( fn_ip.own_ip & 0xFF)); - } else if (ip_version == 6) { - char ip6_str[40]; - ipv6_to_str(fn_ip.own_ip6.addr, ip6_str); - printf(" Using IPv6 address: %s\n", ip6_str); - } - - if (rc == -2) { - sprintf(buf, - "E3002: (net) ARP request to TFTP server " - "(%d.%d.%d.%d) failed", - ((fn_ip.server_ip >> 24) & 0xFF), - ((fn_ip.server_ip >> 16) & 0xFF), - ((fn_ip.server_ip >> 8) & 0xFF), - ( fn_ip.server_ip & 0xFF)); - bootmsg_error(0x3002, &buf[7]); - - write_mm_log(buf, strlen(buf), 0x91); - return -102; - } - if (rc == -4 || rc == -3) { - strcpy(buf,"E3008: (net) Can't obtain TFTP server IP address"); - bootmsg_error(0x3008, &buf[7]); - - write_mm_log(buf, strlen(buf), 0x91); - return -107; - } - - - /*********************************************************** - * - * Load file via TFTP into buffer provided by OpenFirmware - * - ***********************************************************/ - - if (obp_tftp_args.filename[0] != 0) { - strncpy((char *) fn_ip.filename, obp_tftp_args.filename, sizeof(fn_ip.filename)-1); - fn_ip.filename[sizeof(fn_ip.filename)-1] = 0; - } - - if (ip_version == 4) { - printf(" Requesting file \"%s\" via TFTP from %d.%d.%d.%d\n", - fn_ip.filename, - ((fn_ip.server_ip >> 24) & 0xFF), - ((fn_ip.server_ip >> 16) & 0xFF), - ((fn_ip.server_ip >> 8) & 0xFF), - ( fn_ip.server_ip & 0xFF)); - } else if (ip_version == 6) { - char ip6_str[40]; - printf(" Requesting file \"%s\" via TFTP from ", fn_ip.filename); - ipv6_to_str(fn_ip.server_ip6.addr, ip6_str); - printf("%s\n", ip6_str); - } - - // accept at most 20 bad packets - // wait at most for 40 packets - rc = tftp(&fn_ip, (unsigned char *) buffer, - len, obp_tftp_args.tftp_retries, - &tftp_err, huge_load, block_size, ip_version); - - if(obp_tftp_args.ip_init == IP_INIT_DHCP) - dhcp_send_release(fn_ip.fd); - - if (rc > 0) { - printf(" TFTP: Received %s (%d KBytes)\n", fn_ip.filename, - rc / 1024); - } else if (rc == -1) { - bootmsg_error(0x3003, "(net) unknown TFTP error"); - return -103; - } else if (rc == -2) { - sprintf(buf, - "E3004: (net) TFTP buffer of %d bytes " - "is too small for %s", - len, fn_ip.filename); - bootmsg_error(0x3004, &buf[7]); - - write_mm_log(buf, strlen(buf), 0x91); - return -104; - } else if (rc == -3) { - sprintf(buf,"E3009: (net) file not found: %s", - fn_ip.filename); - bootmsg_error(0x3009, &buf[7]); - - write_mm_log(buf, strlen(buf), 0x91); - return -108; - } else if (rc == -4) { - strcpy(buf,"E3010: (net) TFTP access violation"); - bootmsg_error(0x3010, &buf[7]); - - write_mm_log(buf, strlen(buf), 0x91); - return -109; - } else if (rc == -5) { - strcpy(buf,"E3011: (net) illegal TFTP operation"); - bootmsg_error(0x3011, &buf[7]); - - write_mm_log(buf, strlen(buf), 0x91); - return -110; - } else if (rc == -6) { - strcpy(buf, "E3012: (net) unknown TFTP transfer ID"); - bootmsg_error(0x3012, &buf[7]); - - write_mm_log(buf, strlen(buf), 0x91); - return -111; - } else if (rc == -7) { - strcpy(buf, "E3013: (net) no such TFTP user"); - bootmsg_error(0x3013, &buf[7]); - - write_mm_log(buf, strlen(buf), 0x91); - return -112; - } else if (rc == -8) { - strcpy(buf, "E3017: (net) TFTP blocksize negotiation failed"); - bootmsg_error(0x3017, &buf[7]); - - write_mm_log(buf, strlen(buf), 0x91); - return -116; - } else if (rc == -9) { - strcpy(buf,"E3018: (net) file exceeds maximum TFTP transfer size"); - bootmsg_error(0x3018, &buf[7]); - - write_mm_log(buf, strlen(buf), 0x91); - return -117; - } else if (rc <= -10 && rc >= -15) { - sprintf(buf,"E3005: (net) ICMP ERROR \""); - switch (rc) { - case -ICMP_NET_UNREACHABLE - 10: - sprintf(buf+strlen(buf),"net unreachable"); - break; - case -ICMP_HOST_UNREACHABLE - 10: - sprintf(buf+strlen(buf),"host unreachable"); - break; - case -ICMP_PROTOCOL_UNREACHABLE - 10: - sprintf(buf+strlen(buf),"protocol unreachable"); - break; - case -ICMP_PORT_UNREACHABLE - 10: - sprintf(buf+strlen(buf),"port unreachable"); - break; - case -ICMP_FRAGMENTATION_NEEDED - 10: - sprintf(buf+strlen(buf),"fragmentation needed and DF set"); - break; - case -ICMP_SOURCE_ROUTE_FAILED - 10: - sprintf(buf+strlen(buf),"source route failed"); - break; - default: - sprintf(buf+strlen(buf)," UNKNOWN"); - break; - } - sprintf(buf+strlen(buf),"\""); - bootmsg_error(0x3005, &buf[7]); - - write_mm_log(buf, strlen(buf), 0x91); - return -105; - } else if (rc == -40) { - sprintf(buf, - "E3014: (net) TFTP error occurred after " - "%d bad packets received", - tftp_err.bad_tftp_packets); - bootmsg_error(0x3014, &buf[7]); - write_mm_log(buf, strlen(buf), 0x91); - return -113; - } else if (rc == -41) { - sprintf(buf, - "E3015: (net) TFTP error occurred after " - "missing %d responses", - tftp_err.no_packets); - bootmsg_error(0x3015, &buf[7]); - write_mm_log(buf, strlen(buf), 0x91); - return -114; - } else if (rc == -42) { - sprintf(buf, - "E3016: (net) TFTP error missing block %d, " - "expected block was %d", - tftp_err.blocks_missed, - tftp_err.blocks_received); - bootmsg_error(0x3016, &buf[7]); - write_mm_log(buf, strlen(buf), 0x91); - return -115; - } - return rc; -} - -/** - * Parses a tftp arguments, extracts all - * parameters and fills server ip according to this - * - * Parameters: - * @param buffer string with arguments, - * @param server_ip server ip as result - * @param filename default filename - * @param fd Socket descriptor - * @param len len of the buffer, - * @return 0 on SUCCESS and -1 on failure - */ -int parse_tftp_args(char buffer[], char *server_ip, char filename[], int fd, - int len) -{ - char *raw; - char *tmp, *tmp1; - int i, j = 0; - char domainname[256]; - uint8_t server_ip6[16]; - - raw = malloc(len); - if (raw == NULL) { - printf("\n unable to allocate memory, parsing failed\n"); - return -1; - } - strncpy(raw,(const char *)buffer,len); - /*tftp url contains tftp://[fd00:4f53:4444:90:214:5eff:fed9:b200]/testfile*/ - if(strncmp(raw,"tftp://",7)){ - printf("\n tftp missing in %s\n",raw); - free(raw); - return -1; - } - tmp = strchr(raw,'['); - if(tmp != NULL && *tmp == '[') { - /*check for valid ipv6 address*/ - tmp1 = strchr(tmp,']'); - if (tmp1 == NULL) { - printf("\n missing ] in %s\n",raw); - free(raw); - return -1; - } - i = tmp1 - tmp; - /*look for file name*/ - tmp1 = strchr(tmp,'/'); - if (tmp1 == NULL) { - printf("\n missing filename in %s\n",raw); - free(raw); - return -1; - } - tmp[i] = '\0'; - /*check for 16 byte ipv6 address */ - if (!str_to_ipv6((tmp+1), (uint8_t *)(server_ip))) { - printf("\n wrong format IPV6 address in %s\n",raw); - free(raw); - return -1;; - } - else { - /*found filename */ - strcpy(filename,(tmp1+1)); - free(raw); - return 0; - } - } - else { - /*here tftp://hostname/testfile from option request of dhcp*/ - /*look for dns server name */ - tmp1 = strchr(raw,'.'); - if(tmp1 == NULL) { - printf("\n missing . seperator in %s\n",raw); - free(raw); - return -1; - } - /*look for domain name beyond dns server name - * so ignore the current . and look for one more - */ - tmp = strchr((tmp1+1),'.'); - if(tmp == NULL) { - printf("\n missing domain in %s\n",raw); - free(raw); - return -1; - } - tmp1 = strchr(tmp1,'/'); - if (tmp1 == NULL) { - printf("\n missing filename in %s\n",raw); - free(raw); - return -1; - } - j = tmp1 - (raw + 7); - tmp = raw + 7; - tmp[j] = '\0'; - strcpy(domainname, tmp); - if (dns_get_ip(fd, domainname, server_ip6, 6) == 0) { - printf("\n DNS failed for IPV6\n"); - return -1; - } - ipv6_to_str(server_ip6, server_ip); - - strcpy(filename,(tmp1+1)); - free(raw); - return 0; - } - -} diff --git a/qemu/roms/SLOF/clients/net-snk/app/netapps/ping.c b/qemu/roms/SLOF/clients/net-snk/app/netapps/ping.c deleted file mode 100644 index 2c7dadbde..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/netapps/ping.c +++ /dev/null @@ -1,196 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2008 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -#include <netlib/ipv4.h> -#include <netlib/dhcp.h> -#include <netlib/ethernet.h> -#include <sys/socket.h> -#include <string.h> -#include <stdio.h> -#include <stdlib.h> -#include <time.h> -#include <netapps/args.h> -#include "netapps.h" - -struct ping_args { - union { - char string[4]; - unsigned int integer; - } server_ip; - union { - char string[4]; - unsigned int integer; - } client_ip; - union { - char string[4]; - unsigned int integer; - } gateway_ip; - unsigned int timeout; -}; - -static void -usage(void) -{ - printf - ("\nping device-path:[device-args,]server-ip,[client-ip],[gateway-ip][,timeout]\n"); - -} - -static int -parse_args(const char *args, struct ping_args *ping_args) -{ - unsigned int argc = get_args_count(args); - char buf[64]; - ping_args->timeout = 10; - if (argc == 0) - /* at least server-ip has to be specified */ - return -1; - if (argc == 1) { - /* probably only server ip is specified */ - argncpy(args, 0, buf, 64); - if (!strtoip(buf, ping_args->server_ip.string)) - return -1; - return 0; - } - /* get first option from list */ - argncpy(args, 0, buf, 64); - if (!strtoip(buf, ping_args->server_ip.string)) { - /* it is not an IP address - * therefore it has to be device-args - * device-args are not supported and just ignored */ - args = get_arg_ptr(args, 1); - argc--; - } - - argncpy(args, 0, buf, 64); - if (!strtoip(buf, ping_args->server_ip.string)) { - /* this should have been the server IP address */ - return -1; - } else { - args = get_arg_ptr(args, 1); - if (!--argc) - return 0; - } - - argncpy(args, 0, buf, 64); - if (!strtoip(buf, ping_args->client_ip.string)) { - /* this should have been the client (our) IP address */ - return -1; - } else { - args = get_arg_ptr(args, 1); - if (!--argc) - return 0; - } - argncpy(args, 0, buf, 64); - if (!strtoip(buf, ping_args->gateway_ip.string)) { - /* this should have been the gateway IP address */ - return -1; - } else { - args = get_arg_ptr(args, 1); - if (!--argc) - return 0; - } - argncpy(args, 0, buf, 64); - ping_args->timeout = strtol(args, 0, 10); - return 0; -} - -int -ping(int argc, char *argv[]) -{ - short arp_failed = 0; - filename_ip_t fn_ip; - int fd_device; - struct ping_args ping_args; - uint8_t own_mac[6]; - - memset(&ping_args, 0, sizeof(struct ping_args)); - - if (argc == 2) { - if (parse_args(argv[1], &ping_args)) { - usage(); - return -1; - } - } else { - usage(); - return -1; - } - - memset(&fn_ip, 0, sizeof(filename_ip_t)); - - /* Get mac_addr from device */ - printf("\n Reading MAC address from device: "); - fd_device = socket(0, 0, 0, (char *) own_mac); - if (fd_device == -1) { - printf("\nE3000: Could not read MAC address\n"); - return -100; - } else if (fd_device == -2) { - printf("\nE3006: Could not initialize network device\n"); - return -101; - } - - fn_ip.fd = fd_device; - - printf("%02x:%02x:%02x:%02x:%02x:%02x\n", - own_mac[0], own_mac[1], own_mac[2], - own_mac[3], own_mac[4], own_mac[5]); - - // init ethernet layer - set_mac_address(own_mac); - // identify the BOOTP/DHCP server via broadcasts - // don't do this, when using DHCP !!! - // fn_ip.server_ip = 0xFFFFFFFF; - // memset(fn_ip.server_mac, 0xff, 6); - - if (!ping_args.client_ip.integer) { - /* Get ip address for our mac address */ - printf(" Requesting IP address via DHCP: "); - arp_failed = dhcp(0, &fn_ip, 30, F_IPV4); - - if (arp_failed == -1) { - printf("\n DHCP: Could not get ip address\n"); - return -1; - } - - } else { - memcpy(&fn_ip.own_ip, &ping_args.client_ip.integer, 4); - arp_failed = 1; - printf(" Own IP address: "); - } - - // reinit network stack - set_ipv4_address(fn_ip.own_ip); - - printf("%d.%d.%d.%d\n", - ((fn_ip.own_ip >> 24) & 0xFF), ((fn_ip.own_ip >> 16) & 0xFF), - ((fn_ip.own_ip >> 8) & 0xFF), (fn_ip.own_ip & 0xFF)); - - memcpy(&fn_ip.server_ip, &ping_args.server_ip.integer, 4); - printf(" Ping to %d.%d.%d.%d ", ((fn_ip.server_ip >> 24) & 0xFF), - ((fn_ip.server_ip >> 16) & 0xFF), - ((fn_ip.server_ip >> 8) & 0xFF), (fn_ip.server_ip & 0xFF)); - - - ping_ipv4(fd_device, fn_ip.server_ip); - - set_timer(TICKS_SEC / 10 * ping_args.timeout); - while(get_timer() > 0) { - receive_ether(fd_device); - if(pong_ipv4() == 0) { - printf("success\n"); - return 0; - } - } - - printf("failed\n"); - return -1; -} diff --git a/qemu/roms/SLOF/clients/net-snk/app/netlib/Makefile b/qemu/roms/SLOF/clients/net-snk/app/netlib/Makefile deleted file mode 100644 index df09bf82e..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/netlib/Makefile +++ /dev/null @@ -1,42 +0,0 @@ -# ***************************************************************************** -# * Copyright (c) 2004, 2008 IBM Corporation -# * All rights reserved. -# * This program and the accompanying materials -# * are made available under the terms of the BSD License -# * which accompanies this distribution, and is available at -# * http://www.opensource.org/licenses/bsd-license.php -# * -# * Contributors: -# * IBM Corporation - initial implementation -# ****************************************************************************/ - -ifndef TOP - TOP = $(shell while ! test -e make.rules; do cd .. ; done; pwd) - export TOP -endif -include $(TOP)/make.rules - -CFLAGS += -I../ - -ifeq ($(SNK_USE_MTFTP), 1) -CFLAGS += -DUSE_MTFTP -endif - -OBJS = ethernet.o ipv4.o udp.o tcp.o dns.o bootp.o \ - dhcp.o ipv6.o dhcpv6.o icmpv6.o ndp.o - -ifeq ($(SNK_USE_MTFTP), 1) -OBJS += mtftp.o -else -OBJS += tftp.o -endif - -all: netlib.o - -netlib.o: $(OBJS) - $(LD) $(LDFLAGS) $^ -o $@ -r - -clean: - $(RM) -f *.o *.a *.i - -include $(TOP)/make.depend diff --git a/qemu/roms/SLOF/clients/net-snk/app/netlib/bootp.c b/qemu/roms/SLOF/clients/net-snk/app/netlib/bootp.c deleted file mode 100644 index 6d58cef7d..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/netlib/bootp.c +++ /dev/null @@ -1,255 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2008 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - - -#include <stdio.h> -#include <string.h> -#include <sys/socket.h> -#include <time.h> - -#include <ethernet.h> -#include <ipv4.h> -#include <udp.h> -#include <dhcp.h> - -#define DEBUG 0 - -static char * response_buffer; - -#if DEBUG -static void -print_ip(char *ip) -{ - printf("%d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]); -} -#endif - -/* IP header checksum calculation */ -static unsigned short -checksum(unsigned short *packet, int words) -{ - unsigned long checksum; - for (checksum = 0; words > 0; words--) - checksum += *packet++; - checksum = (checksum >> 16) + (checksum & 0xffff); - checksum += (checksum >> 16); - return ~checksum; -} - - -static int -send_bootp(filename_ip_t * fn_ip) -{ -#if DEBUG - int i; -#endif - unsigned int packetsize = - sizeof(struct iphdr) + sizeof(struct ethhdr) + - sizeof(struct udphdr) + sizeof(struct btphdr); - unsigned char packet[packetsize]; - struct iphdr *iph; - struct udphdr *udph; - struct btphdr *btph; - - iph = (struct iphdr *) packet; - udph = (struct udphdr *) (iph + 1); - btph = (struct btphdr *) (udph + 1); - - memset(packet, 0, packetsize); - - fill_iphdr((uint8_t *) iph, htons(packetsize - sizeof(struct ethhdr)), - IPTYPE_UDP, 0, fn_ip->server_ip); - fill_udphdr((uint8_t *) udph, - htons(sizeof(struct udphdr) + sizeof(struct btphdr)), - htons(UDPPORT_BOOTPC), htons(UDPPORT_BOOTPS)); - btph->op = 1; - btph->htype = 1; - btph->hlen = 6; - strcpy((char *) btph->file, "bla"); - memcpy(btph->chaddr, get_mac_address(), 6); - -#if DEBUG - printf("Sending packet\n"); - printf("Packet is "); - for (i = 0; i < packetsize; i++) - printf(" %02x", packet[i]); - printf(".\n"); -#endif - - send_ipv4(fn_ip->fd, packet, iph->ip_len); -#if DEBUG - printf("%d bytes transmitted over socket.\n", i); -#endif - - return 0; -} - - -static int -receive_bootp(filename_ip_t * fn_ip) -{ - int len, old_sum; - unsigned int packetsize = 2000; - unsigned char packet[packetsize]; - struct iphdr *iph; - struct udphdr *udph; - struct btphdr *btph; - -#if DEBUG - struct ethhdr *ethh; - ethh = (struct ethhdr *) packet; -#endif - - iph = (struct iphdr *) (packet + sizeof(struct ethhdr)); - udph = (struct udphdr *) (iph + 1); - btph = (struct btphdr *) (udph + 1); - - memset(packet, 0, packetsize); - - /* setting up a timer with a timeout of one second */ - set_timer(TICKS_SEC); - - do { - - /* let's receive a packet */ - len = recv(fn_ip->fd, packet, packetsize, 0); - -#if DEBUG - int j; - printf("%d bytes received, %d expected \n", len, packetsize); - if (len == 346) { - printf("Rec packet\n"); - printf("Packet is "); - for (j = 0; j < len; j++) { - if (j % 16 == 0) - printf("\n"); - printf(" %02x", packet[j]); - } - printf(".\n"); - } -#endif - if (len == 0) - continue; - - /* check if the ip checksum is correct */ - old_sum = iph->ip_sum; - iph->ip_sum = 0x00; - if (old_sum != - checksum((unsigned short *) iph, sizeof(struct iphdr) >> 1)) - /* checksum failed */ - continue; - /* is it a udp packet */ - if (iph->ip_p != IPTYPE_UDP) - continue; - /* check if the source port and destination port and the packet - * say that it is a bootp answer */ - if (udph->uh_dport != htons(UDPPORT_BOOTPC) || udph->uh_sport != htons(UDPPORT_BOOTPS)) - continue; - /* check if it is a Boot Reply */ - if (btph->op != 2) - continue; - /* Comparing our mac address with the one in the bootp reply */ - if (memcmp(get_mac_address(), btph->chaddr, ETH_ALEN)) - continue; - - if(response_buffer) - memcpy(response_buffer, btph, 1720); - - fn_ip->own_ip = btph->yiaddr; - fn_ip->server_ip = btph->siaddr; - strcpy((char *) fn_ip->filename, (char *) btph->file); - -#if DEBUG - printf("\nThese are the details of the bootp reply:\n"); - printf("Our IP address: "); - print_ip((char*) &fn_ip->own_ip); - printf("Next server IP address: "); - print_ip((char*) &fn_ip->server_ip); - printf("Boot file name: %s\n", btph->file); - printf("Packet is: %s\n", btph->file); - for (j = 0; j < len; j++) { - if (j % 16 == 0) - printf("\n"); - printf(" %02x", packet[j]); - } - printf(".\n"); - printf("fn_ip->own_mac: %02x:%02x:%02x:%02x:%02x:%02x\n", - get_mac_address()[0], get_mac_address()[1], - get_mac_address()[2], get_mac_address()[3], - get_mac_address()[4], get_mac_address()[5]); - printf("Header ethh->dest_mac: %02x:%02x:%02x:%02x:%02x:%02x\n", - ethh->dest_mac[0], ethh->dest_mac[1], ethh->dest_mac[2], - ethh->dest_mac[3], ethh->dest_mac[4], ethh->dest_mac[5]); - printf("Header ethh->src_mac: %02x:%02x:%02x:%02x:%02x:%02x\n", - ethh->src_mac[0], ethh->src_mac[1], ethh->src_mac[2], - ethh->src_mac[3], ethh->src_mac[4], ethh->src_mac[5]); - printf("Header ethh->typ: %x\n",ethh->type); - printf("Header iph->ip_hlv: %x\n",iph->ip_hlv); - printf("Header iph->ip_len: %x\n",iph->ip_len); - printf("Header iph->ip_id: %x\n",iph->ip_id); - printf("Header iph->ip_off: %x\n",iph->ip_off); - printf("Header iph->ip_ttl: %x\n",iph->ip_ttl); - printf("Header iph->ip_p: %x\n",iph->ip_p); - printf("Header iph->ip_sum: %x\n",iph->ip_sum); - printf("Header iph->ip_src: %x\n",iph->ip_src); - printf("Header iph->ip_dst: %x\n",iph->ip_dst); - - printf("Header btph->op: %x\n",btph->op); - printf("Header btph->htype: %x\n",btph->htype); - printf("Header btph->hlen: %x\n",btph->hlen); - printf("Header btph->hops: %x\n",btph->hops); - printf("Header btph->xid: %x\n",btph->xid); - printf("Header btph->secs: %x\n",btph->secs); - printf("Header btph->ciaddr: %x\n",btph->ciaddr); - printf("Header btph->yiaddr: %x\n",btph->yiaddr); - printf("Header btph->siaddr: %x\n",btph->siaddr); - printf("Header btph->giaddr: %x\n",btph->giaddr); - - printf("Header btph->chaddr: %02x:%02x:%02x:%02x:%02x:%02x:\n", - btph->chaddr[0], btph->chaddr[1], btph->chaddr[2], - btph->chaddr[3], btph->chaddr[4], btph->chaddr[5]); -#endif - return 0; - - /* only do this for the time specified during set_timer() */ - } while (get_timer() > 0); - return -1; -} - - -int -bootp(char *ret_buffer, filename_ip_t * fn_ip, unsigned int retries) -{ - int i = (int) retries+1; - fn_ip->own_ip = 0; - - printf(" Requesting IP address via BOOTP: "); - - response_buffer = ret_buffer; - - do { - printf("\b\b%02d", i); - if (!i--) { - printf("\nGiving up after %d bootp requests\n", - retries+1); - return -1; - } - send_bootp(fn_ip); - /* if the timer in receive_bootp expired it will return - * -1 and we will just send another bootp request just - * in case the previous one was lost. And because we don't - * trust the network cable we keep on doing this 30 times */ - } while (receive_bootp(fn_ip) != 0); - - printf("\b\b\bdone\n"); - return 0; -} diff --git a/qemu/roms/SLOF/clients/net-snk/app/netlib/dhcp.c b/qemu/roms/SLOF/clients/net-snk/app/netlib/dhcp.c deleted file mode 100644 index 7e2e88ccf..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/netlib/dhcp.c +++ /dev/null @@ -1,955 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2008 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - - -/******************************* ALGORITHMS ******************************/ - -/** \file dhcp.c <pre> - * **************** State-transition diagram for DHCP client ************* - * - * +---------+ Note: DHCP-server msg / DHCP-client msg - * | INIT | - * +---------+ - * | - * | - / Discover - * V - * +---------+ - * | SELECT | Timeout - * +---------+ | - * | | - * | Offer / Request | - * | | - * V V - * +---------+ NACK / - *********** - * | REQUEST | ----------------> * FAULT * - * +---------+ *********** - * | - * | ACK / - *********** - * +----------------------> * SUCCESS * - * *********** - * - * ************************************************************************ - * </pre> */ - - -/********************** DEFINITIONS & DECLARATIONS ***********************/ - -#include <dhcp.h> -#include <ethernet.h> -#include <ipv4.h> -#include <udp.h> -#include <dns.h> -#include <netapps/args.h> - -#include <stdio.h> -#include <string.h> -#include <time.h> -#include <sys/socket.h> -#include <ctype.h> -#include <stdlib.h> - -/* 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 DHCPINFORM 8 - -/* DHCP Option Codes */ -#define DHCP_MASK 1 -#define DHCP_ROUTER 3 -#define DHCP_DNS 6 -#define DHCP_REQUESTED_IP 50 -#define DHCP_OVERLOAD 52 -#define DHCP_MSG_TYPE 53 -#define DHCP_SERVER_ID 54 -#define DHCP_REQUEST_LIST 55 -#define DHCP_TFTP_SERVER 66 -#define DHCP_BOOTFILE 67 -#define DHCP_CLIENT_ARCH 93 -#define DHCP_ENDOPT 0xFF -#define DHCP_PADOPT 0x00 - -/* "file/sname" overload option values */ -#define DHCP_OVERLOAD_FILE 1 -#define DHCP_OVERLOAD_SNAME 2 -#define DHCP_OVERLOAD_BOTH 3 - -/* DHCP states codes */ -#define DHCP_STATE_SELECT 1 -#define DHCP_STATE_REQUEST 2 -#define DHCP_STATE_SUCCESS 3 -#define DHCP_STATE_FAULT 4 - -/* DHCP Client Architecture */ -#ifndef DHCPARCH -#define USE_DHCPARCH 0 -#define DHCPARCH 0 -#else -#define USE_DHCPARCH 1 -#endif - -static uint8_t dhcp_magic[] = {0x63, 0x82, 0x53, 0x63}; -/**< DHCP_magic is a cookie, that identifies DHCP options (see RFC 2132) */ - -/** \struct dhcp_options_t - * This structure is used to fill options in DHCP-msg during transmitting - * or to retrieve options from DHCP-msg during receiving. - * <p> - * If flag[i] == TRUE then field for i-th option retains valid value and - * information from this field may retrived (in case of receiving) or will - * be transmitted (in case of transmitting). - * - */ -typedef struct { - uint8_t flag[256]; /**< Show if corresponding opt. is valid */ - uint8_t request_list[256]; /**< o.55 If i-th member is TRUE, then i-th - option will be requested from server */ - uint32_t server_ID; /**< o.54 Identifies DHCP-server */ - uint32_t requested_IP; /**< o.50 Must be filled in DHCP-Request */ - uint32_t dns_IP; /**< o. 6 DNS IP */ - uint32_t router_IP; /**< o. 3 Router IP */ - uint32_t subnet_mask; /**< o. 1 Subnet mask */ - uint8_t msg_type; /**< o.53 DHCP-message type */ - uint8_t overload; /**< o.52 Overload sname/file fields */ - int8_t tftp_server[256]; /**< o.66 TFTP server name */ - int8_t bootfile[256]; /**< o.67 Boot file name */ - uint16_t client_arch; /**< o.93 Client architecture type */ -} dhcp_options_t; - -/** Stores state of DHCP-client (refer to State-transition diagram) */ -static uint8_t dhcp_state; - - -/***************************** PROTOTYPES ********************************/ - -static int32_t dhcp_attempt(int fd); - -static int32_t dhcp_encode_options(uint8_t * opt_field, dhcp_options_t * opt_struct); - -static int32_t dhcp_decode_options(uint8_t opt_field[], uint32_t opt_len, - dhcp_options_t * opt_struct); - -static int8_t dhcp_merge_options(uint8_t dst_options[], uint32_t * dst_len, - uint8_t src_options[], uint32_t src_len); - -static int8_t dhcp_find_option(uint8_t options[], uint32_t len, - uint8_t op_code, uint32_t * op_offset); - -static void dhcp_append_option(uint8_t dst_options[], uint32_t * dst_len, - uint8_t * new_option); - -static void dhcp_combine_option(uint8_t dst_options[], uint32_t * dst_len, - uint32_t dst_offset, uint8_t * new_option); - -static void dhcp_send_discover(int fd); - -static void dhcp_send_request(int fd); - -/***************************** LOCAL VARIABLES ***************************/ - -static uint8_t ether_packet[ETH_MTU_SIZE]; -static uint32_t dhcp_own_ip = 0; -static uint32_t dhcp_server_ip = 0; -static uint32_t dhcp_siaddr_ip = 0; -static char dhcp_filename[256]; -static char dhcp_tftp_name[256]; -static uint32_t dhcp_xid; - -static char * response_buffer; - -/***************************** IMPLEMENTATION ****************************/ - -void dhcpv4_generate_transaction_id(void) -{ - dhcp_xid = (rand() << 16) ^ rand(); -} - -int32_t dhcpv4(char *ret_buffer, filename_ip_t *fn_ip) -{ - uint32_t dhcp_tftp_ip = 0; - int fd = fn_ip->fd; - - strcpy(dhcp_filename, ""); - strcpy(dhcp_tftp_name, ""); - - response_buffer = ret_buffer; - - if (dhcp_attempt(fd) == 0) - return -1; - - if (fn_ip->own_ip) { - dhcp_own_ip = fn_ip->own_ip; - } - if (fn_ip->server_ip) { - dhcp_siaddr_ip = fn_ip->server_ip; - } - if(fn_ip->filename[0] != 0) { - strcpy(dhcp_filename, (char *) fn_ip->filename); - } - - // TFTP SERVER - if (!strlen(dhcp_tftp_name)) { - if (!dhcp_siaddr_ip) { - // ERROR: TFTP name is not presented - return -3; - } - - // take TFTP-ip from siaddr field - dhcp_tftp_ip = dhcp_siaddr_ip; - } - else { - // TFTP server defined by its name - if (!strtoip(dhcp_tftp_name, (char *)&dhcp_tftp_ip)) { - if (!dns_get_ip(fd, dhcp_tftp_name, (uint8_t *)&dhcp_tftp_ip, 4)) { - // DNS error - can't obtain TFTP-server name - // Use TFTP-ip from siaddr field, if presented - if (dhcp_siaddr_ip) { - dhcp_tftp_ip = dhcp_siaddr_ip; - } - else { - // ERROR: Can't obtain TFTP server IP - return -4; - } - } - } - } - - // Store configuration info into filename_ip strucutre - fn_ip -> own_ip = dhcp_own_ip; - fn_ip -> server_ip = dhcp_tftp_ip; - strcpy((char *) fn_ip -> filename, dhcp_filename); - - return 0; -} - -/** - * DHCP: Tries o obtain DHCP parameters, refer to state-transition diagram - */ -static int32_t dhcp_attempt(int fd) -{ - int sec; - - // Send DISCOVER message and switch DHCP-client to SELECT state - dhcp_send_discover(fd); - - dhcp_state = DHCP_STATE_SELECT; - - // setting up a timer with a timeout of two seconds - for (sec = 0; sec < 2; sec++) { - set_timer(TICKS_SEC); - do { - receive_ether(fd); - - // Wait until client will switch to Final state or Timeout occurs - switch (dhcp_state) { - case DHCP_STATE_SUCCESS : - return 1; - case DHCP_STATE_FAULT : - return 0; - } - } while (get_timer() > 0); - } - - // timeout - return 0; -} - -/** - * DHCP: Supplements DHCP-message with options stored in structure. - * For more information about option coding see dhcp_options_t. - * - * @param opt_field Points to the "vend" field of DHCP-message - * (destination) - * @param opt_struct this structure stores info about the options which - * will be added to DHCP-message (source) - * @return TRUE - options packed; - * FALSE - error condition occurs. - * @see dhcp_options_t - */ -static int32_t dhcp_encode_options(uint8_t * opt_field, dhcp_options_t * opt_struct) -{ - uint8_t * options = opt_field; - uint16_t i, sum; // used to define is any options set - - // magic - memcpy(options, dhcp_magic, 4); - options += 4; - - // fill message type - switch (opt_struct -> msg_type) { - case DHCPDISCOVER : - case DHCPREQUEST : - case DHCPDECLINE : - case DHCPINFORM : - case DHCPRELEASE : - options[0] = DHCP_MSG_TYPE; - options[1] = 1; - options[2] = opt_struct -> msg_type; - options += 3; - break; - default : - return 0; // Unsupported DHCP-message - } - - if (opt_struct -> overload) { - options[0] = DHCP_OVERLOAD; - options[1] = 0x01; - options[2] = opt_struct -> overload; - options +=3; - } - - if (opt_struct -> flag[DHCP_REQUESTED_IP]) { - options[0] = DHCP_REQUESTED_IP; - options[1] = 0x04; - * (uint32_t *) (options + 2) = htonl (opt_struct -> requested_IP); - options +=6; - } - - if (opt_struct -> flag[DHCP_SERVER_ID]) { - options[0] = DHCP_SERVER_ID; - options[1] = 0x04; - * (uint32_t *) (options + 2) = htonl (opt_struct -> server_ID); - options +=6; - } - - sum = 0; - for (i = 0; i < 256; i++) - sum += opt_struct -> request_list[i]; - - if (sum) { - options[0] = DHCP_REQUEST_LIST; - options[1] = sum; - options += 2; - for (i = 0; i < 256; i++) { - if (opt_struct -> request_list[i]) { - options[0] = i; options++; - } - } - } - - if (opt_struct -> flag[DHCP_TFTP_SERVER]) { - options[0] = DHCP_TFTP_SERVER; - options[1] = strlen((char *) opt_struct -> tftp_server) + 1; - memcpy(options + 2, opt_struct -> tftp_server, options[1]); - options += options[1] + 2; - } - - if (opt_struct -> flag[DHCP_BOOTFILE]) { - options[0] = DHCP_BOOTFILE; - options[1] = strlen((char *) opt_struct -> bootfile) + 1; - memcpy(options + 2, opt_struct -> bootfile, options[1]); - options += options[1] + 2; - } - - if (opt_struct -> flag[DHCP_CLIENT_ARCH]) { - options[0] = DHCP_CLIENT_ARCH; - options[1] = 2; - options[2] = (DHCPARCH >> 8); - options[3] = DHCPARCH & 0xff; - options += 4; - } - - // end options - options[0] = 0xFF; - options++; - - return 1; -} - -/** - * DHCP: Extracts encoded options from DHCP-message into the structure. - * For more information about option coding see dhcp_options_t. - * - * @param opt_field Points to the "options" field of DHCP-message - * (source). - * @param opt_len Length of "options" field. - * @param opt_struct this structure stores info about the options which - * was extracted from DHCP-message (destination). - * @return TRUE - options extracted; - * FALSE - error condition occurs. - * @see dhcp_options_t - */ -static int32_t dhcp_decode_options(uint8_t opt_field[], uint32_t opt_len, - dhcp_options_t * opt_struct) -{ - uint32_t offset = 0; - - memset(opt_struct, 0, sizeof(dhcp_options_t)); - - // magic - if (memcmp(opt_field, dhcp_magic, 4)) { - return 0; - } - - offset += 4; - while (offset < opt_len) { - opt_struct -> flag[opt_field[offset]] = 1; - switch(opt_field[offset]) { - case DHCP_OVERLOAD : - opt_struct -> overload = opt_field[offset + 2]; - offset += 2 + opt_field[offset + 1]; - break; - - case DHCP_REQUESTED_IP : - opt_struct -> requested_IP = htonl(* (uint32_t *) (opt_field + offset + 2)); - offset += 2 + opt_field[offset + 1]; - break; - - case DHCP_MASK : - opt_struct -> flag[DHCP_MASK] = 1; - opt_struct -> subnet_mask = htonl(* (uint32_t *) (opt_field + offset + 2)); - offset += 2 + opt_field[offset + 1]; - break; - - case DHCP_DNS : - opt_struct -> flag[DHCP_DNS] = 1; - opt_struct -> dns_IP = htonl(* (uint32_t *) (opt_field + offset + 2)); - offset += 2 + opt_field[offset + 1]; - break; - - case DHCP_ROUTER : - opt_struct -> flag[DHCP_ROUTER] = 1; - opt_struct -> router_IP = htonl(* (uint32_t *) (opt_field + offset + 2)); - offset += 2 + opt_field[offset + 1]; - break; - - case DHCP_MSG_TYPE : - if ((opt_field[offset + 2] > 0) && (opt_field[offset + 2] < 9)) - opt_struct -> msg_type = opt_field[offset + 2]; - else - return 0; - offset += 2 + opt_field[offset + 1]; - break; - - case DHCP_SERVER_ID : - opt_struct -> server_ID = htonl(* (uint32_t *) (opt_field + offset + 2)); - offset += 2 + opt_field[offset + 1]; - break; - - case DHCP_TFTP_SERVER : - memcpy(opt_struct -> tftp_server, opt_field + offset + 2, opt_field[offset + 1]); - (opt_struct -> tftp_server)[opt_field[offset + 1]] = 0; - offset += 2 + opt_field[offset + 1]; - break; - - case DHCP_BOOTFILE : - memcpy(opt_struct -> bootfile, opt_field + offset + 2, opt_field[offset + 1]); - (opt_struct -> bootfile)[opt_field[offset + 1]] = 0; - offset += 2 + opt_field[offset + 1]; - break; - - case DHCP_CLIENT_ARCH : - opt_struct -> client_arch = ((opt_field[offset + 2] << 8) & 0xFF00) | (opt_field[offset + 3] & 0xFF); - offset += 4; - break; - - case DHCP_PADOPT : - offset++; - break; - - case DHCP_ENDOPT : // End of options - return 1; - - default : - offset += 2 + opt_field[offset + 1]; // Unsupported opt. - do nothing - } - } - if (offset == opt_len) - return 1; // options finished without 0xFF - - return 0; -} - -/** - * DHCP: Appends information from source "options" into dest "options". - * This function is used to support "file/sname" overloading. - * - * @param dst_options destanation "options" field - * @param dst_len size of dst_options (modified by this function) - * @param src_options source "options" field - * @param src_len size of src_options - * @return TRUE - options merged; - * FALSE - error condition occurs. - */ -static int8_t dhcp_merge_options(uint8_t dst_options[], uint32_t * dst_len, - uint8_t src_options[], uint32_t src_len) -{ - uint32_t dst_offset, src_offset = 0; - - // remove ENDOPT if presented - if (dhcp_find_option(dst_options, * dst_len, DHCP_ENDOPT, &dst_offset)) - * dst_len = dst_offset; - - while (src_offset < src_len) { - switch(src_options[src_offset]) { - case DHCP_PADOPT: - src_offset++; - break; - case DHCP_ENDOPT: - return 1; - default: - if (dhcp_find_option(dst_options, * dst_len, - src_options[src_offset], - &dst_offset)) { - dhcp_combine_option(dst_options, dst_len, - dst_offset, - (uint8_t *) src_options + - src_offset); - } - else { - dhcp_append_option(dst_options, dst_len, src_options + src_offset); - } - src_offset += 2 + src_options[src_offset + 1]; - } - } - - if (src_offset == src_len) - return 1; - return 0; -} - -/** - * DHCP: Finds given occurrence of the option with the given code (op_code) - * in "options" field of DHCP-message. - * - * @param options "options" field of DHCP-message - * @param len length of the "options" field - * @param op_code code of the option to find - * @param op_offset SUCCESS - offset to an option occurrence; - * FAULT - offset is set to zero. - * @return TRUE - option was find; - * FALSE - option wasn't find. - */ -static int8_t dhcp_find_option(uint8_t options[], uint32_t len, - uint8_t op_code, uint32_t * op_offset) -{ - uint32_t srch_offset = 0; - * op_offset = 0; - - while (srch_offset < len) { - if (options[srch_offset] == op_code) { - * op_offset = srch_offset; - return 1; - } - if (options[srch_offset] == DHCP_ENDOPT) - return 0; - - if (options[srch_offset] == DHCP_PADOPT) - srch_offset++; - else - srch_offset += 2 + options[srch_offset + 1]; - } - return 0; -} - -/** - * DHCP: Appends new option from one list (src) into the tail - * of another option list (dst) - * - * @param dst_options "options" field of DHCP-message - * @param dst_len length of the "options" field (modified) - * @param new_option points to an option in another list (src) - */ -static void dhcp_append_option(uint8_t dst_options[], uint32_t * dst_len, - uint8_t * new_option) -{ - memcpy(dst_options + ( * dst_len), new_option, 2 + (* (new_option + 1))); - * dst_len += 2 + *(new_option + 1); -} - -/** - * DHCP: This function is used when options with the same code are - * presented in both merged lists. In this case information - * about the option from one list (src) is combined (complemented) - * with information about the option in another list (dst). - * - * @param dst_options "options" field of DHCP-message - * @param dst_len length of the "options" field (modified) - * @param dst_offset offset of the option from beginning of the list - * @param new_option points to an option in another list (src) - */ -static void dhcp_combine_option(uint8_t dst_options[], uint32_t * dst_len, - uint32_t dst_offset, uint8_t * new_option) -{ - uint8_t tmp_buffer[1024]; // use to provide safe memcpy - uint32_t tail_len; - - // move all subsequent options (allocate size for additional info) - tail_len = (* dst_len) - dst_offset - 2 - dst_options[dst_offset + 1]; - - memcpy(tmp_buffer, dst_options + (* dst_len) - tail_len, tail_len); - memcpy(dst_options + (* dst_len) - tail_len + (* (new_option + 1)), - tmp_buffer, tail_len); - - // add new_content to option - memcpy(dst_options + (* dst_len) - tail_len, new_option + 2, - * (new_option + 1)); - dst_options[dst_offset + 1] += * (new_option + 1); - - // correct dst_len - * dst_len += * (new_option + 1); -} - -/** - * DHCP: Sends DHCP-Discover message. Looks for DHCP servers. - */ -static void dhcp_send_discover(int fd) -{ - uint32_t packetsize = sizeof(struct iphdr) + - sizeof(struct udphdr) + sizeof(struct btphdr); - struct btphdr *btph; - dhcp_options_t opt; - - memset(ether_packet, 0, packetsize); - - btph = (struct btphdr *) (ðer_packet[ - sizeof(struct iphdr) + sizeof(struct udphdr)]); - - btph -> op = 1; - btph -> htype = 1; - btph -> hlen = 6; - btph -> xid = dhcp_xid; - memcpy(btph -> chaddr, get_mac_address(), 6); - - memset(&opt, 0, sizeof(dhcp_options_t)); - - opt.msg_type = DHCPDISCOVER; - - opt.request_list[DHCP_MASK] = 1; - opt.request_list[DHCP_DNS] = 1; - opt.request_list[DHCP_ROUTER] = 1; - opt.request_list[DHCP_TFTP_SERVER] = 1; - opt.request_list[DHCP_BOOTFILE] = 1; - opt.request_list[DHCP_CLIENT_ARCH] = USE_DHCPARCH; - - dhcp_encode_options(btph -> vend, &opt); - - fill_udphdr(ðer_packet[sizeof(struct iphdr)], - sizeof(struct btphdr) + sizeof(struct udphdr), - UDPPORT_BOOTPC, UDPPORT_BOOTPS); - fill_iphdr(ether_packet, sizeof(struct btphdr) + - sizeof(struct udphdr) + sizeof(struct iphdr), - IPTYPE_UDP, dhcp_own_ip, 0xFFFFFFFF); - - send_ipv4(fd, ether_packet, packetsize); -} - -/** - * DHCP: Sends DHCP-Request message. Asks for acknowledgment to occupy IP. - */ -static void dhcp_send_request(int fd) -{ - uint32_t packetsize = sizeof(struct iphdr) + - sizeof(struct udphdr) + sizeof(struct btphdr); - struct btphdr *btph; - dhcp_options_t opt; - - memset(ether_packet, 0, packetsize); - - btph = (struct btphdr *) (ðer_packet[ - sizeof(struct iphdr) + sizeof(struct udphdr)]); - - btph -> op = 1; - btph -> htype = 1; - btph -> hlen = 6; - btph -> xid = dhcp_xid; - memcpy(btph -> chaddr, get_mac_address(), 6); - - memset(&opt, 0, sizeof(dhcp_options_t)); - - opt.msg_type = DHCPREQUEST; - memcpy(&(opt.requested_IP), &dhcp_own_ip, 4); - opt.flag[DHCP_REQUESTED_IP] = 1; - memcpy(&(opt.server_ID), &dhcp_server_ip, 4); - opt.flag[DHCP_SERVER_ID] = 1; - - opt.request_list[DHCP_MASK] = 1; - opt.request_list[DHCP_DNS] = 1; - opt.request_list[DHCP_ROUTER] = 1; - opt.request_list[DHCP_TFTP_SERVER] = 1; - opt.request_list[DHCP_BOOTFILE] = 1; - opt.request_list[DHCP_CLIENT_ARCH] = USE_DHCPARCH; - opt.flag[DHCP_CLIENT_ARCH] = USE_DHCPARCH; - - dhcp_encode_options(btph -> vend, &opt); - - fill_udphdr(ðer_packet[sizeof(struct iphdr)], - sizeof(struct btphdr) + sizeof(struct udphdr), - UDPPORT_BOOTPC, UDPPORT_BOOTPS); - fill_iphdr(ether_packet, sizeof(struct btphdr) + - sizeof(struct udphdr) + sizeof(struct iphdr), - IPTYPE_UDP, 0, 0xFFFFFFFF); - - send_ipv4(fd, ether_packet, packetsize); -} - - -/** - * DHCP: Sends DHCP-Release message. Releases occupied IP. - */ -void dhcp_send_release(int fd) -{ - uint32_t packetsize = sizeof(struct iphdr) + - sizeof(struct udphdr) + sizeof(struct btphdr); - struct btphdr *btph; - dhcp_options_t opt; - - btph = (struct btphdr *) (ðer_packet[ - sizeof(struct iphdr) + sizeof(struct udphdr)]); - - memset(ether_packet, 0, packetsize); - - btph -> op = 1; - btph -> htype = 1; - btph -> hlen = 6; - btph -> xid = dhcp_xid; - strcpy((char *) btph -> file, ""); - memcpy(btph -> chaddr, get_mac_address(), 6); - btph -> ciaddr = htonl(dhcp_own_ip); - - memset(&opt, 0, sizeof(dhcp_options_t)); - - opt.msg_type = DHCPRELEASE; - opt.server_ID = dhcp_server_ip; - opt.flag[DHCP_SERVER_ID] = 1; - - dhcp_encode_options(btph -> vend, &opt); - - fill_udphdr(ðer_packet[sizeof(struct iphdr)], - sizeof(struct btphdr) + sizeof(struct udphdr), - UDPPORT_BOOTPC, UDPPORT_BOOTPS); - fill_iphdr(ether_packet, sizeof(struct btphdr) + - sizeof(struct udphdr) + sizeof(struct iphdr), IPTYPE_UDP, - dhcp_own_ip, dhcp_server_ip); - - send_ipv4(fd, ether_packet, packetsize); -} - -/** - * DHCP: Handles DHCP-messages according to Receive-handle diagram. - * Changes the state of DHCP-client. - * - * @param fd socket descriptor - * @param packet BootP/DHCP-packet to be handled - * @param packetsize length of the packet - * @return ZERO - packet handled successfully; - * NON ZERO - packet was not handled (e.g. bad format) - * @see receive_ether - * @see btphdr - */ - -int8_t handle_dhcp(int fd, uint8_t * packet, int32_t packetsize) -{ - struct btphdr * btph; - struct iphdr * iph; - dhcp_options_t opt; - - memset(&opt, 0, sizeof(dhcp_options_t)); - btph = (struct btphdr *) packet; - iph = (struct iphdr *) packet - sizeof(struct udphdr) - - sizeof(struct iphdr); - - if (btph->op != 2) - return -1; /* It is not a Bootp/DHCP reply */ - if (btph->xid != dhcp_xid) - return -1; /* The transaction ID does not match */ - - if (memcmp(btph -> vend, dhcp_magic, 4)) { - // It is BootP - RFC 951 - dhcp_own_ip = htonl(btph -> yiaddr); - dhcp_siaddr_ip = htonl(btph -> siaddr); - dhcp_server_ip = htonl(iph -> ip_src); - - if (strlen((char *) btph -> sname) && !dhcp_siaddr_ip) { - strncpy((char *) dhcp_tftp_name, (char *) btph -> sname, - sizeof(btph -> sname)); - dhcp_tftp_name[sizeof(btph -> sname)] = 0; - } - - if (strlen((char *) btph -> file)) { - strncpy((char *) dhcp_filename, (char *) btph -> file, sizeof(btph -> file)); - dhcp_filename[sizeof(btph -> file)] = 0; - } - - dhcp_state = DHCP_STATE_SUCCESS; - return 0; - } - - - // decode options - if (!dhcp_decode_options(btph -> vend, packetsize - - sizeof(struct btphdr) + sizeof(btph -> vend), - &opt)) { - return -1; // can't decode options - } - - if (opt.overload) { - int16_t decode_res = 0; - uint8_t options[1024]; // buffer for merged options - uint32_t opt_len; - - // move 1-st part of options from vend field into buffer - opt_len = packetsize - sizeof(struct btphdr) + - sizeof(btph -> vend) - 4; - memcpy(options, btph -> vend, opt_len + 4); - - // add other parts - switch (opt.overload) { - case DHCP_OVERLOAD_FILE: - decode_res = dhcp_merge_options(options + 4, &opt_len, - btph -> file, - sizeof(btph -> file)); - break; - case DHCP_OVERLOAD_SNAME: - decode_res = dhcp_merge_options(options + 4, &opt_len, - btph -> sname, - sizeof(btph -> sname)); - break; - case DHCP_OVERLOAD_BOTH: - decode_res = dhcp_merge_options(options + 4, &opt_len, - btph -> file, - sizeof(btph -> file)); - if (!decode_res) - break; - decode_res = dhcp_merge_options(options + 4, &opt_len, - btph -> sname, - sizeof(btph -> sname)); - break; - } - - if (!decode_res) - return -1; // bad options in sname/file fields - - // decode merged options - if (!dhcp_decode_options(options, opt_len + 4, &opt)) { - return -1; // can't decode options - } - } - - if (!opt.msg_type) { - // It is BootP with Extensions - RFC 1497 - // retrieve conf. settings from BootP - reply - dhcp_own_ip = htonl(btph -> yiaddr); - dhcp_siaddr_ip = htonl(btph -> siaddr); - if (strlen((char *) btph -> sname) && !dhcp_siaddr_ip) { - strncpy((char *) dhcp_tftp_name, (char *) btph -> sname, sizeof(btph -> sname)); - dhcp_tftp_name[sizeof(btph -> sname)] = 0; - } - - if (strlen((char *) btph -> file)) { - strncpy((char *) dhcp_filename, (char *) btph -> file, sizeof(btph -> file)); - dhcp_filename[sizeof(btph -> file)] = 0; - } - - // retrieve DHCP-server IP from IP-header - dhcp_server_ip = iph -> htonl(ip_src); - - dhcp_state = DHCP_STATE_SUCCESS; - } - else { - // It is DHCP - RFC 2131 & RFC 2132 - // opt contains parameters from server - switch (dhcp_state) { - case DHCP_STATE_SELECT : - if (opt.msg_type == DHCPOFFER) { - dhcp_own_ip = htonl(btph -> yiaddr); - dhcp_server_ip = opt.server_ID; - dhcp_send_request(fd); - dhcp_state = DHCP_STATE_REQUEST; - } - return 0; - case DHCP_STATE_REQUEST : - switch (opt.msg_type) { - case DHCPNACK : - dhcp_own_ip = 0; - dhcp_server_ip = 0; - dhcp_state = DHCP_STATE_FAULT; - break; - case DHCPACK : - dhcp_own_ip = htonl(btph -> yiaddr); - dhcp_server_ip = opt.server_ID; - dhcp_siaddr_ip = htonl(btph -> siaddr); - if (opt.flag[DHCP_TFTP_SERVER]) { - strcpy((char *) dhcp_tftp_name, (char *) opt.tftp_server); - } - else { - strcpy((char *) dhcp_tftp_name, ""); - if ((opt.overload != DHCP_OVERLOAD_SNAME && - opt.overload != DHCP_OVERLOAD_BOTH) && - !dhcp_siaddr_ip) { - strncpy((char *) dhcp_tftp_name, - (char *) btph->sname, - sizeof(btph -> sname)); - dhcp_tftp_name[sizeof(btph->sname)] = 0; - } - } - - if (opt.flag[DHCP_BOOTFILE]) { - strcpy((char *) dhcp_filename, (char *) opt.bootfile); - } - else { - strcpy((char *) dhcp_filename, ""); - if (opt.overload != DHCP_OVERLOAD_FILE && - opt.overload != DHCP_OVERLOAD_BOTH && - strlen((char *) btph -> file)) { - strncpy((char *) dhcp_filename, - (char *) btph->file, - sizeof(btph->file)); - dhcp_filename[sizeof(btph -> file)] = 0; - } - } - - dhcp_state = DHCP_STATE_SUCCESS; - break; - default: - break; // Unused DHCP-message - do nothing - } - break; - default : - return -1; // Illegal DHCP-client state - } - } - - if (dhcp_state == DHCP_STATE_SUCCESS) { - - // initialize network entity with real own_ip - // to be able to answer for foreign requests - set_ipv4_address(dhcp_own_ip); - - if(response_buffer) { - if(packetsize <= 1720) - memcpy(response_buffer, packet, packetsize); - else - memcpy(response_buffer, packet, 1720); - } - - /* Subnet mask */ - if (opt.flag[DHCP_MASK]) { - /* Router */ - if (opt.flag[DHCP_ROUTER]) { - set_ipv4_router(opt.router_IP); - set_ipv4_netmask(opt.subnet_mask); - } - } - - /* DNS-server */ - if (opt.flag[DHCP_DNS]) { - dns_init(opt.dns_IP, 0, 4); - } - } - - return 0; -} diff --git a/qemu/roms/SLOF/clients/net-snk/app/netlib/dhcp.h b/qemu/roms/SLOF/clients/net-snk/app/netlib/dhcp.h deleted file mode 100644 index 54fb1eed3..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/netlib/dhcp.h +++ /dev/null @@ -1,54 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2008 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -#ifndef _DHCP_H_ -#define _DHCP_H_ - -#include <stdint.h> - -#ifdef USE_MTFTP -#include <netlib/mtftp.h> -#else -#include <netlib/tftp.h> -#endif - -/** \struct btphdr - * A header for BootP/DHCP-messages. - * For more information see RFC 951 / RFC 2131. - */ -struct btphdr { - uint8_t op; /**< Identifies is it request (1) or reply (2) */ - uint8_t htype; /**< HW address type (ethernet usually) */ - uint8_t hlen; /**< HW address length */ - uint8_t hops; /**< This info used by relay agents (not used) */ - uint32_t xid; /**< This ID is used to match queries and replies */ - uint16_t secs; /**< Unused */ - uint16_t unused; /**< Unused */ - uint32_t ciaddr; /**< Client IP address (if client knows it) */ - uint32_t yiaddr; /**< "Your" (client) IP address */ - uint32_t siaddr; /**< Next server IP address (TFTP server IP) */ - uint32_t giaddr; /**< Gateway IP address (used by relay agents) */ - uint8_t chaddr[16]; /**< Client HW address */ - uint8_t sname[64]; /**< Server host name (TFTP server name) */ - uint8_t file[128]; /**< Boot file name */ - uint8_t vend[64]; /**< Optional parameters field (DHCP-options) */ -}; - -void dhcpv4_generate_transaction_id(void); -int bootp(char *ret_buffer, filename_ip_t *, unsigned int); -int dhcpv4(char *ret_buffer, filename_ip_t *); -void dhcp_send_release(int fd); - -/* Handles DHCP-packets, which are detected by receive_ether. */ -extern int8_t handle_dhcp(int fd, uint8_t * packet, int32_t packetsize); - -#endif diff --git a/qemu/roms/SLOF/clients/net-snk/app/netlib/dhcpv6.c b/qemu/roms/SLOF/clients/net-snk/app/netlib/dhcpv6.c deleted file mode 100644 index d0a22d555..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/netlib/dhcpv6.c +++ /dev/null @@ -1,212 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2013 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -#include <string.h> -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <sys/socket.h> -#include <time.h> -#include <netlib/ethernet.h> -#include <netlib/ipv6.h> -#include <netlib/udp.h> -#include <netlib/dhcpv6.h> -#include <netlib/tftp.h> -#include <netlib/dns.h> - -static uint8_t tid[3]; -static uint32_t dhcpv6_state = -1; -static filename_ip_t *my_fn_ip; - -static struct ip6addr_list_entry all_dhcpv6_ll; /* All DHCPv6 servers address */ - -void -dhcpv6_generate_transaction_id(void) -{ - /* As per RFC 3315 transaction IDs should be generated randomly */ - tid[0] = rand(); - tid[1] = rand(); - tid[2] = rand(); -} - -static void -send_info_request(int fd) -{ - uint8_t ether_packet[ETH_MTU_SIZE]; - uint32_t payload_length; - struct dhcp_message_header *dhcph; - - memset(ether_packet, 0, ETH_MTU_SIZE); - - /* Get an IPv6 packet */ - payload_length = sizeof(struct udphdr) + sizeof(struct dhcp_message_header); - fill_ip6hdr (ether_packet + sizeof(struct ethhdr), - payload_length, IPTYPE_UDP, - get_ipv6_address(), &(all_dhcpv6_ll.addr)); - fill_udphdr ( ether_packet + sizeof(struct ethhdr) + sizeof(struct ip6hdr), - payload_length, DHCP_CLIENT_PORT, DHCP_SERVER_PORT); - dhcph = (struct dhcp_message_header *) (ether_packet + - sizeof(struct ethhdr) + - sizeof(struct ip6hdr) + - sizeof(struct udphdr)); - - /* Fill in DHCPv6 data */ - dhcph->type = DHCP_INFORMATION_REQUEST; - memcpy( &(dhcph->transaction_id), &tid, 3); - dhcph->option.client_id.code = DHCPV6_OPTION_CLIENTID; - dhcph->option.client_id.length = 10; - dhcph->option.client_id.duid_type = DUID_LL; - dhcph->option.client_id.hardware_type = 1; - memcpy( &(dhcph->option.client_id.mac), - get_mac_address(), 6); - dhcph->option.el_time.code = DHCPV6_OPTION_ELAPSED_TIME; - dhcph->option.el_time.length = 2; - dhcph->option.el_time.time = 0x190; /* 4000 ms */ - dhcph->option.option_request_option.code = DHCPV6_OPTION_ORO; - dhcph->option.option_request_option.length = DHCPV6_OPTREQUEST_NUMOPTS * 2; - dhcph->option.option_request_option.option_code[0] = DHCPV6_OPTION_DNS_SERVERS; - dhcph->option.option_request_option.option_code[1] = DHCPV6_OPTION_DOMAIN_LIST; - dhcph->option.option_request_option.option_code[2] = DHCPV6_OPTION_BOOT_URL; - - send_ipv6(fd, ether_packet + sizeof(struct ethhdr), - sizeof(struct ip6hdr) + sizeof(struct udphdr) - + sizeof(struct dhcp_message_header)); -} - -static int32_t -dhcpv6_attempt(int fd) -{ - int sec; - - // Send information request - send_info_request(fd); - - dhcpv6_state = DHCPV6_STATE_SELECT; - - // setting up a timer with a timeout of two seconds - for (sec = 0; sec < 2; sec++) { - set_timer(TICKS_SEC); - do { - receive_ether(fd); - - // Wait until client will switch to Final state or Timeout occurs - switch (dhcpv6_state) { - case DHCP_STATUSCODE_SUCCESS: - return 1; - case DHCP_STATUSCODE_UNSPECFAIL: //FIXME - return 0; - } - } while (get_timer() > 0); - } - - // timeout - return 0; -} - -int32_t -dhcpv6 ( char *ret_buffer, void *fn_ip) -{ - int fd; - - all_dhcpv6_ll.addr.part.prefix = 0xff02000000000000ULL; - all_dhcpv6_ll.addr.part.interface_id = 0x10002ULL; - - my_fn_ip = (filename_ip_t *) fn_ip; - fd = my_fn_ip->fd; - - if( !dhcpv6_attempt(fd)) { - return -1; - } - - return 0; -} - -static void dhcp6_process_options (uint8_t *option, int32_t option_length) -{ - struct dhcp_boot_url *option_boot_url; - struct client_identifier *option_clientid; - struct server_identifier *option_serverid; - struct dhcp_dns *option_dns; - struct dhcp_dns_list *option_dns_list; - struct dhcp6_gen_option *option_gen; - char buffer[256]; - - while (option_length > 0) { - switch ((uint16_t) *(option+1)) { - case DHCPV6_OPTION_CLIENTID: - option_clientid = (struct client_identifier *) option; - option = option + option_clientid->length + 4; - option_length = option_length - option_clientid->length - 4; - break; - case DHCPV6_OPTION_SERVERID: - option_serverid = (struct server_identifier *) option; - option = option + option_serverid->length + 4; - option_length = option_length - option_serverid->length - 4; - break; - case DHCPV6_OPTION_DNS_SERVERS: - option_dns = (struct dhcp_dns *) option; - option = option + option_dns->length + 4; - option_length = option_length - option_dns->length - 4; - memcpy( &(my_fn_ip->dns_ip6), - option_dns->p_ip6, - IPV6_ADDR_LENGTH); - dns_init(0, option_dns->p_ip6, 6); - break; - case DHCPV6_OPTION_DOMAIN_LIST: - option_dns_list = (struct dhcp_dns_list *) option; - option = option + option_dns_list->length + 4; - option_length = option_length - option_dns_list->length - 4; - break; - case DHCPV6_OPTION_BOOT_URL: - option_boot_url = (struct dhcp_boot_url *) option; - option = option + option_boot_url->length + 4; - option_length = option_length - option_boot_url->length - 4; - strncpy((char *)buffer, - (const char *)option_boot_url->url, - (size_t)option_boot_url->length); - buffer[option_boot_url->length] = 0; - if (parse_tftp_args(buffer, - (char *)my_fn_ip->server_ip6.addr, - (char *)my_fn_ip->filename, - (int)my_fn_ip->fd, - option_boot_url->length) == -1) - return; - break; - default: - option_gen = (struct dhcp6_gen_option *) option; - option = option + option_gen->length + 4; - option_length = option_length - option_gen->length - 4; - } - } -} - -uint32_t -handle_dhcpv6(uint8_t * packet, int32_t packetsize) -{ - - uint8_t *first_option; - int32_t option_length; - struct dhcp_message_reply *reply; - reply = (struct dhcp_message_reply *) packet; - - if (memcmp(reply->transaction_id, tid, 3)) - return -1; /* Wrong transaction ID */ - - if (reply->type == 7) - dhcpv6_state = DHCP_STATUSCODE_SUCCESS; - - first_option = packet + 4; - option_length = packet + packetsize - first_option; - dhcp6_process_options(first_option, option_length); - - return 0; -} diff --git a/qemu/roms/SLOF/clients/net-snk/app/netlib/dhcpv6.h b/qemu/roms/SLOF/clients/net-snk/app/netlib/dhcpv6.h deleted file mode 100644 index fb77da648..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/netlib/dhcpv6.h +++ /dev/null @@ -1,154 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2013 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -#ifndef _DHCPV6_H_ -#define _DHCPV6_H_ - -#include <stdint.h> -#include <netlib/ethernet.h> - -#define DHCPV6_STATELESS 0 -#define DHCPV6_STATEFUL 1 - -/* DHCP port numbers */ -#define DHCP_CLIENT_PORT 546 -#define DHCP_SERVER_PORT 547 - -/* DHCPv6 message types */ -#define DHCP_SOLICIT 1 -#define DHCP_ADVERTISE 2 -#define DHCP_REQUEST 3 -#define DHCP_CONFIRM 4 -#define DHCP_RENEW 5 -#define DHCP_REBIND 6 -#define DHCP_REPLY 7 -#define DHCP_RELEASE 8 -#define DHCP_DECLINE 9 -#define DHCP_RECONFIGURE 10 -#define DHCP_INFORMATION_REQUEST 11 -#define RELAY_FORW 12 -#define RELAY_REPL 13 - -/* DHCPv6 option types */ -#define DHCPV6_OPTION_CLIENTID 0x0001 -#define DHCPV6_OPTION_SERVERID 0x0002 -#define DHCPV6_OPTION_IA_NA 3 -#define DHCPV6_OPTION_IA_TA 4 -#define DHCPV6_OPTION_IAADDR 5 -#define DHCPV6_OPTION_ORO 6 -#define DHCPV6_OPTION_PREFEREN 7 -#define DHCPV6_OPTION_ELAPSED_TIME 8 -#define DHCPV6_OPTION_RELAY_MS 9 -#define DHCPV6_OPTION_AUTH 11 -#define DHCPV6_OPTION_UNICAST 12 -#define DHCPV6_OPTION_STATUS_C 13 -#define DHCPV6_OPTION_RAPID_CO 14 -#define DHCPV6_OPTION_USER_CLA 15 -#define DHCPV6_OPTION_VENDOR_C 16 -#define DHCPV6_OPTION_VENDOR_O 17 -#define DHCPV6_OPTION_INTERFAC 18 -#define DHCPV6_OPTION_RECONF_M 19 -#define DHCPV6_OPTION_RECONF_A 20 -#define DHCPV6_OPTION_DNS_SERVERS 23 -#define DHCPV6_OPTION_DOMAIN_LIST 24 -#define DHCPV6_OPTION_BOOT_URL 59 - -/* DHCPv6 status codes */ -#define DHCP_STATUSCODE_SUCCESS 0 -#define DHCP_STATUSCODE_UNSPECFAIL 1 -#define DHCP_STATUSCODE_NOADDRAVAIL 2 -#define DHCP_STATUSCODE_NOBINDING 3 -#define DHCP_STATUSCODE_NOTONLINK 4 -#define DHCP_STATUSCODE_USEMULTICAST 5 -#define DHCPV6_STATE_SELECT 6 - -/* DUID types */ -#define DUID_LLT 1 /* DUID based on Link-layer Address Plus Time */ -#define DUID_EN 2 /* DUID based on Assigned by Vendor Based on Enterprise Number */ -#define DUID_LL 3 /* DUID based on Link-layer Address */ - -/* Prototypes */ -void dhcpv6_generate_transaction_id(void); -int32_t dhcpv6 ( char *ret_buffer, void *fn_ip); -uint32_t handle_dhcpv6(uint8_t * , int32_t); - -struct dhcp6_gen_option { - uint16_t code; - uint16_t length; -}; - -struct client_identifier { - uint16_t code; - uint16_t length; - uint16_t duid_type; - uint16_t hardware_type; - uint8_t mac[6]; -}; - -struct server_identifier { - uint16_t code; - uint16_t length; - uint16_t duid_type; - uint16_t hardware_type; - uint32_t time; - uint8_t mac[6]; -}; - -#define DHCPV6_OPTREQUEST_NUMOPTS 3 - -struct dhcp_info_request { - struct client_identifier client_id; - struct elapsed_time { - uint16_t code; - uint16_t length; - uint16_t time; - } el_time; - struct option_request { - uint16_t code; - uint16_t length; - uint16_t option_code[DHCPV6_OPTREQUEST_NUMOPTS]; - } option_request_option; -}; - -struct dhcp_message_header { - uint8_t type; /* Message type */ - uint8_t transaction_id[3]; /* Transaction id */ - struct dhcp_info_request option; -}; - -struct dhcp_dns { - uint16_t code; - uint16_t length; - uint8_t p_ip6[16]; - uint8_t s_ip6[16]; -}__attribute((packed)); - -struct dhcp_dns_list { - uint16_t code; - uint16_t length; - uint8_t domain[256]; -}__attribute((packed)); - -struct dhcp_boot_url { - uint16_t type; - uint16_t length; - uint8_t url[256]; -}; - -struct dhcp_message_reply { - uint8_t type; /* Message type */ - uint8_t transaction_id[3]; /* Transaction id */ - struct client_identifier client_id; - struct server_identifier server_id; -}; - -#endif diff --git a/qemu/roms/SLOF/clients/net-snk/app/netlib/dns.c b/qemu/roms/SLOF/clients/net-snk/app/netlib/dns.c deleted file mode 100644 index a5a36a18e..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/netlib/dns.c +++ /dev/null @@ -1,527 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2008 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -/********************** DEFINITIONS & DECLARATIONS ***********************/ - -#include <dns.h> -#include <stdio.h> -#include <string.h> -#include <time.h> -#include <sys/socket.h> - -#include <ethernet.h> -#include <ipv4.h> -#include <ipv6.h> -#include <udp.h> - -#define DNS_FLAG_MSGTYPE 0xF800 /**< Message type mask (opcode) */ -#define DNS_FLAG_SQUERY 0x0000 /**< Standard query type */ -#define DNS_FLAG_SRESPONSE 0x8000 /**< Standard response type */ -#define DNS_FLAG_RD 0x0100 /**< Recursion desired flag */ -#define DNS_FLAG_RCODE 0x000F /**< Response code mask - (stores err.cond.) code */ -#define DNS_RCODE_NERROR 0 /**< "No errors" code */ - -#define DNS_QTYPE_A 1 /**< A 32-bit IP record type */ -#define DNS_QTYPE_AAAA 0x1c /**< 128-bit IPv6 record type */ -#define DNS_QTYPE_CNAME 5 /**< Canonical name record type */ - -#define DNS_QCLASS_IN 1 /**< Query class for internet msgs */ - -/** \struct dnshdr - * A header for DNS-messages (see RFC 1035, paragraph 4.1.1). - * <p> - * DNS-message consist of DNS-header and 4 optional sections, - * arranged in the following order:<ul> - * <li> DNS-header - * <li> question section - * <li> answer section - * <li> authority section - * <li> additional section - * </ul> - */ -struct dnshdr { - uint16_t id; /**< an identifier used to match up replies */ - uint16_t flags; /**< contains op_code, err_code, etc. */ - uint16_t qdcount; /**< specifies the number of entries in the - question section */ - uint16_t ancount; /**< specifies the number of entries in the - answer section */ - uint16_t nscount; /**< specifies the number of entries in the - authority section */ - uint16_t arcount; /**< specifies the number of entries in the - additional section */ -}; - - -/***************************** PROTOTYPES ********************************/ - -static void -dns_send_query(int fd, int8_t * domain_name, uint8_t ip_version); - -static void -fill_dnshdr(uint8_t * packet, int8_t * domain_name, uint8_t ip_version); - -static uint8_t * -dns_extract_name(uint8_t * dnsh, int8_t * head, int8_t * domain_name); - -static int8_t -urltohost(char * url, char * host_name); - -static int8_t -hosttodomain(char * host_name, char * domain_name); - -/**************************** LOCAL VARIABLES ****************************/ - -static uint8_t ether_packet[ETH_MTU_SIZE]; -static int32_t dns_server_ip = 0; -static uint8_t dns_server_ipv6[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -static int32_t dns_result_ip = 0; -static uint8_t dns_result_ipv6[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -static int8_t dns_error = 0; /**< Stores error code or 0 */ -static int8_t dns_domain_name[0x100]; /**< Raw domain name */ -static int8_t dns_domain_cname[0x100]; /**< Canonical domain name */ - -/**************************** IMPLEMENTATION *****************************/ - -/** - * DNS: Initialize the environment for DNS client. - * To perfrom DNS-queries use the function dns_get_ip. - * - * @param device_socket a socket number used to send and receive packets - * @param server_ip DNS-server IPv4 address (e.g. 127.0.0.1) - * @return TRUE in case of successful initialization; - * FALSE in case of fault (e.g. can't obtain MAC). - * @see dns_get_ip - */ -int8_t -dns_init(uint32_t _dns_server_ip, uint8_t _dns_server_ipv6[16], uint8_t ip_version) -{ - if(ip_version == 6) - memcpy(dns_server_ipv6, _dns_server_ipv6, 16); - else - dns_server_ip = _dns_server_ip; - return 0; -} - -/** - * DNS: For given URL retrieves IPv4/IPv6 from DNS-server. - * <p> - * URL can be given in one of the following form: <ul> - * <li> scheme with full path with (without) user and password - * <br>(e.g. "http://user:pass@www.host.org/url-path"); - * <li> host name with url-path - * <br>(e.g. "www.host.org/url-path"); - * <li> nothing but host name - * <br>(e.g. "www.host.org"); - * </ul> - * - * @param fd socket descriptor - * @param url the URL to be resolved - * @param domain_ip In case of SUCCESS stores extracted IP. - * In case of FAULT stores zeros (0.0.0.0). - * @return TRUE - IP successfuly retrieved; - * FALSE - error condition occurs. - */ -int8_t -dns_get_ip(int fd, char* url, uint8_t * domain_ip, uint8_t ip_version) -{ - /* this counter is used so that we abort after 30 DNS request */ - int32_t i; - /* this buffer stores host name retrieved from url */ - static int8_t host_name[0x100]; - - (* domain_ip) = 0; - - // Retrieve host name from URL - if (!urltohost(url, (char *) host_name)) { - printf("\nERROR:\t\t\tBad URL!\n"); - return 0; - } - - // Reformat host name into a series of labels - if (!hosttodomain((char *) host_name, (char *) dns_domain_name)) { - printf("\nERROR:\t\t\tBad host name!\n"); - return 0; - } - - // Check if DNS server is presented and accessible - if (dns_server_ip == 0) { - printf("\nERROR:\t\t\tCan't resolve domain name " - "(DNS server is not presented)!\n"); - return 0; - } - - // Use DNS-server to obtain IP - if (ip_version == 6) - memset(dns_result_ipv6, 0, 16); - else - dns_result_ip = 0; - dns_error = 0; - strcpy((char *) dns_domain_cname, ""); - - for(i = 0; i < 30; ++i) { - // Use canonical name in case we obtained it - if (strlen((char *) dns_domain_cname)) - dns_send_query(fd, dns_domain_cname, ip_version); - else - dns_send_query(fd, dns_domain_name, ip_version); - - // setting up a timer with a timeout of one seconds - set_timer(TICKS_SEC); - do { - receive_ether(fd); - if (dns_error) - return 0; // FALSE - error - if ((dns_result_ip != 0) && (ip_version == 4)) { - memcpy(domain_ip, &dns_result_ip, 4); - return 1; // TRUE - success (domain IP retrieved) - } - else if ((dns_result_ipv6[0] != 0) && (ip_version == 6)) { - memcpy(domain_ip, dns_result_ipv6, 16); - return 1; // TRUE - success (domain IP retrieved) - } - } while (get_timer() > 0); - } - - printf("\nGiving up after %d DNS requests\n", i); - return 0; // FALSE - domain name wasn't retrieved -} - -/** - * DNS: Handles DNS-messages according to Receive-handle diagram. - * Sets dns_result_ip for given dns_domain_name (see dns_get_ip) - * or signals error condition occurs during DNS-resolving process - * by setting dns_error flag. - * - * @param packet DNS-packet to be handled - * @param packetsize length of the packet - * @return ZERO - packet handled successfully; - * NON ZERO - packet was not handled (e.g. bad format) - * @see dns_get_ip - * @see receive_ether - * @see dnshdr - */ -int32_t -handle_dns(uint8_t * packet, int32_t packetsize) -{ - struct dnshdr * dnsh = (struct dnshdr *) packet; - uint8_t * resp_section = packet + sizeof(struct dnshdr); - /* This string stores domain name from DNS-packets */ - static int8_t handle_domain_name[0x100]; - int i; - - // verify ID - is it response for our query? - if (dnsh -> id != htons(0x1234)) - return 0; - - // Is it DNS response? - if ((dnsh -> flags & htons(DNS_FLAG_MSGTYPE)) != htons(DNS_FLAG_SRESPONSE)) - return 0; - - // Is error condition occurs? (check error field in incoming packet) - if ((dnsh -> flags & htons(DNS_FLAG_RCODE)) != DNS_RCODE_NERROR) { - dns_error = 1; - return 0; - } - - /* Pass all (qdcount) records in question section */ - - for (i = 0; i < htons(dnsh -> qdcount); i++) { - // pass QNAME - resp_section = dns_extract_name((uint8_t *) dnsh, (int8_t *) resp_section, - handle_domain_name); - if (resp_section == NULL) { - return -1; // incorrect domain name (bad packet) - } - // pass QTYPE & QCLASS - resp_section += 4; - } - - /* Handle all (ancount) records in answer section */ - - for (i = 0; i < htons(dnsh -> ancount); i++) { - // retrieve domain name from the packet - resp_section = dns_extract_name((uint8_t *) dnsh, (int8_t *) resp_section, - handle_domain_name); - - if (resp_section == NULL) { - return -1; // incorrect domain name (bad packet) - } - - // Check the class of the query (should be IN for Internet) - if (* (uint16_t *) (resp_section + 2) == htons(DNS_QCLASS_IN)) { - // check if retrieved name fit raw or canonical domain name - if (!strcmp((char *) handle_domain_name, (char *) dns_domain_name) || - !strcmp((char *) handle_domain_name, (char *) dns_domain_cname)) { - switch (htons(* (uint16_t *) resp_section)) { - - case DNS_QTYPE_A : - // rdata contains IP - dns_result_ip = htonl(* (uint32_t *) (resp_section + 10)); - return 0; // IP successfully obtained - - case DNS_QTYPE_CNAME : - // rdata contains canonical name, store it for further requests - if (dns_extract_name((uint8_t *) dnsh, (int8_t *) resp_section + 10, - dns_domain_cname) == NULL) { - // incorrect domain name (bad packet) - return -1; - } - break; - case DNS_QTYPE_AAAA : - memcpy(dns_result_ipv6, (resp_section + 10), 16); - return 0; // IP successfully obtained - break; - } - } - // continue with next record in answer section - resp_section += htons(* (uint16_t *) (resp_section + 8)) + 10; - } - } - return 0; // Packet successfully handled but IP wasn't obtained -} - -/** - * DNS: Sends a standard DNS-query (read request package) to a DNS-server. - * DNS-server respones with host IP or signals some error condition. - * Responses from the server are handled by handle_dns function. - * - * @param fd socket descriptor - * @param domain_name the domain name given as series of labels preceded - * with length(label) and terminated with 0 - * <br>(e.g. "\3,w,w,w,\4,h,o,s,t,\3,o,r,g,\0") - * @see handle_dns - */ -static void -dns_send_query(int fd, int8_t * domain_name, uint8_t ip_version) -{ - int qry_len = strlen((char *) domain_name) + 5; - int iphdr_len = (ip_version == 4) ? sizeof(struct iphdr) : sizeof(struct ip6hdr); - ip6_addr_t server_ipv6; - - uint32_t packetsize = iphdr_len + - sizeof(struct udphdr) + sizeof(struct dnshdr) + - qry_len; - - memset(ether_packet, 0, packetsize); - fill_dnshdr(ðer_packet[ - iphdr_len + sizeof(struct udphdr)], - domain_name, - ip_version); - fill_udphdr(ðer_packet[iphdr_len], - sizeof(struct dnshdr) + - sizeof(struct udphdr) + qry_len, - UDPPORT_DNSC, UDPPORT_DNSS); - if (ip_version == 4) { - fill_iphdr(ether_packet, - sizeof(struct dnshdr) + sizeof(struct udphdr) + - iphdr_len + qry_len, - IPTYPE_UDP, 0, dns_server_ip); - } else { - memcpy(server_ipv6.addr, dns_server_ipv6, 16); - fill_ip6hdr(ether_packet, - sizeof(struct dnshdr) + sizeof(struct udphdr) + qry_len, - IPTYPE_UDP, get_ipv6_address(), - &server_ipv6); - } - - send_ip(fd, ether_packet, packetsize); -} - -/** - * DNS: Creates standard DNS-query package. Places DNS-header - * and question section in a packet and fills it with - * corresponding information. - * <p> - * Use this function with similar functions for other network layers - * (fill_udphdr, fill_iphdr, fill_ethhdr). - * - * @param packet Points to the place where ARP-header must be placed. - * @param domain_name the domain name given as series of labels preceded - * with length(label) and terminated with 0 - * <br>(e.g. "\3,w,w,w,\4,h,o,s,t,\3,o,r,g,\0") - * @see fill_udphdr - * @see fill_iphdr - * @see fill_ethhdr - */ -static void -fill_dnshdr(uint8_t * packet, int8_t * domain_name, uint8_t ip_version) -{ - struct dnshdr * dnsh = (struct dnshdr *) packet; - uint8_t * qry_section = packet + sizeof(struct dnshdr); - - dnsh -> id = htons(0x1234); - dnsh -> flags = htons(DNS_FLAG_SQUERY) | htons(DNS_FLAG_RD); - dnsh -> qdcount = htons(1); - - strcpy((char *) qry_section, (char *) domain_name); - qry_section += strlen((char *) domain_name) + 1; - - // fill QTYPE (ask for IP) - if (ip_version == 4) - * (uint16_t *) qry_section = htons(DNS_QTYPE_A); - else - * (uint16_t *) qry_section = htons(DNS_QTYPE_AAAA); - qry_section += 2; - // fill QCLASS (IN is a standard class for Internet) - * (uint16_t *) qry_section = htons(DNS_QCLASS_IN); -} - -/** - * DNS: Extracts domain name from the question or answer section of - * the DNS-message. This function is need to support message - * compression requirement (see RFC 1035, paragraph 4.1.4). - * - * @param dnsh Points at the DNS-header. - * @param head Points at the beginning of the domain_name - * which has to be extracted. - * @param domain_name In case of SUCCESS this string stores extracted name. - * In case of FAULT this string is empty. - * @return NULL in case of FAULT (domain name > 255 octets); - * otherwise pointer to the data following the name. - * @see dnshdr - */ -static uint8_t * -dns_extract_name(uint8_t * dnsh, int8_t * head, int8_t * domain_name) -{ - int8_t * tail = domain_name; - int8_t * ptr = head; - int8_t * next_section = NULL; - - while (1) { - if ((ptr[0] & 0xC0) == 0xC0) { - // message compressed (reference is used) - next_section = ptr + 2; - ptr = (int8_t *) dnsh + (htons(* (uint16_t *) ptr) & 0x3FFF); - continue; - } - if (ptr[0] == 0) { - // message termination - tail[0] = 0; - ptr += 1; - break; - } - // maximum length for domain name is 255 octets w/o termination sym - if (tail - domain_name + ptr[0] + 1 > 255) { - strcpy((char *) domain_name, ""); - return NULL; - } - memcpy(tail, ptr, ptr[0] + 1); - tail += ptr[0] + 1; - ptr += ptr[0] + 1; - } - - if (next_section == NULL) - next_section = ptr; - - return (uint8_t *) next_section; -} - -/** - * DNS: Parses URL and returns host name. - * Input string can be given as: <ul> - * <li> scheme with full path with (without) user and password - * <br>(e.g. "http://user:pass@www.host.org/url-path"); - * <li> host name with url-path - * <br>(e.g. "www.host.org/url-path"); - * <li> nothing but host name - * <br>(e.g. "www.host.org"); - * </ul> - * - * @param url string that stores incoming URL - * @param host_name In case of SUCCESS this string stores the host name, - * In case of FAULT this string is empty. - * @return TRUE - host name retrieved, - * FALSE - host name > 255 octets or empty. - */ -static int8_t -urltohost(char * url, char * host_name) -{ - uint16_t length1; - uint16_t length2; - - strcpy(host_name, ""); - - if (strstr(url, "://") != NULL) - url = strstr(url, "//") + 2; // URL - - if (strstr(url, "@") != NULL) // truncate user & password - url = strstr(url, "@") + 1; - - if (strstr(url, "/") != NULL) // truncate url path - length1 = strstr(url, "/") - url; - else - length1 = strlen(url); - - if (strstr(url, ":") != NULL) // truncate port path - length2 = strstr(url, ":") - url; - else - length2 = strlen(url); - - if(length1 > length2) - length1 = length2; - - if (length1 == 0) - return 0; // string is empty - if(length1 >= 256) - return 0; // host name is too big - - strncpy(host_name, url, length1); - host_name[length1] = 0; - - return 1; // Host name is retrieved -} - -/** - * DNS: Transforms host name string into a series of labels - * each of them preceded with length(label). 0 is a terminator. - * "www.domain.dom" -> "\3,w,w,w,\6,d,o,m,a,i,n,\3,c,o,m,\0" - * <p> - * This format is used in DNS-messages. - * - * @param host_name incoming string with the host name - * @param domain_name resulting string with series of labels - * or empty string in case of FAULT - * @return TRUE - host name transformed, - * FALSE - host name > 255 octets or label > 63 octets. - */ -static int8_t -hosttodomain(char * host_name, char * domain_name) -{ - char * domain_iter = domain_name; - char * host_iter = host_name; - - strcpy(domain_name, ""); - - if(strlen(host_name) > 255) - return 0; // invalid host name (refer to RFC 1035) - - for(; 1; ++host_iter) { - if(*host_iter != '.' && *host_iter != 0) - continue; - *domain_iter = host_iter - host_name; - if (*domain_iter > 63) { - strcpy(domain_name, ""); - return 0; // invalid host name (refer to RFC 1035) - } - ++domain_iter; - strncpy(domain_iter, host_name, host_iter - host_name); - domain_iter += (host_iter - host_name); - if(*host_iter == 0) { - *domain_iter = 0; - break; - } - host_name = host_iter + 1; - } - return 1; // ok -} diff --git a/qemu/roms/SLOF/clients/net-snk/app/netlib/dns.h b/qemu/roms/SLOF/clients/net-snk/app/netlib/dns.h deleted file mode 100644 index b8756afca..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/netlib/dns.h +++ /dev/null @@ -1,28 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2008 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - - -#ifndef _DNS_H_ -#define _DNS_H_ - -#include <stdint.h> - -/* Initialize the environment for DNS client. */ -extern int8_t dns_init(uint32_t _dns_server_ip, uint8_t _dns_server_ipv6[16], uint8_t ip_version); - -/* For given URL retrieves IPv4 from DNS-server. */ -extern int8_t dns_get_ip(int fd, char * url, uint8_t * domain_ip, uint8_t ip_version); - -/* Handles DNS-packets, which are detected by receive_ether. */ -extern int32_t handle_dns(uint8_t * packet, int32_t packetsize); - -#endif diff --git a/qemu/roms/SLOF/clients/net-snk/app/netlib/ethernet.c b/qemu/roms/SLOF/clients/net-snk/app/netlib/ethernet.c deleted file mode 100644 index 1e03a0bf3..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/netlib/ethernet.c +++ /dev/null @@ -1,189 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2008 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - - -/******************************* ALGORITHMS ******************************/ - -/** \file netbase.c <pre> - * *********************** Receive-handle diagram ************************* - * - * Note: Every layer calls out required upper layer - * - * lower - * | MAC/LLC Receive packet (receive_ether) - * | | - * | NETWORK +-----------+---------+ - * | | | - * | IPv4 (handle_ipv4) IPv6 (handle_ipv4) - * | ARP (handle_arp) ICMP & NDP - * | ICMP | - * | | | - * | +---------+---------+ - * | | - * | TRANSPORT +---------+---------+ - * | | | - * | TCP (handle_tcp) UDP (handle_udp) - * | | - * | APPLICATION +----------------+-----------+ - * V | | - * upper DNS (handle_dns) BootP / DHCP (handle_bootp_client) - * - * ************************************************************************ - * </pre> */ - - -/************************ DEFINITIONS & DECLARATIONS *********************/ - -#include <ethernet.h> -#include <string.h> -#include <sys/socket.h> -#include <ipv4.h> -#include <ipv6.h> - - -/****************************** LOCAL VARIABLES **************************/ - -static uint8_t ether_packet[ETH_MTU_SIZE]; -static uint8_t own_mac[6] = {0, 0, 0, 0, 0, 0}; -static uint8_t multicast_mac[] = {0x01, 0x00, 0x5E}; -static const uint8_t broadcast_mac[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; - -/****************************** IMPLEMENTATION ***************************/ - -/** - * Ethernet: Set the own MAC address to initializes ethernet layer. - * - * @param own_mac own hardware-address (MAC) - */ -void set_mac_address(const uint8_t * _own_mac) -{ - if (_own_mac) - memcpy(own_mac, _own_mac, 6); - else - memset(own_mac, 0, 6); -} - -/** - * Ethernet: Set the own MAC address to initializes ethernet layer. - * - * @return own hardware-address (MAC) - */ -const uint8_t *get_mac_address(void) -{ - return own_mac; -} - -/** - * Ethernet: Check if given multicast address is a multicast MAC address - * starting with 0x3333 - * - * @return true or false - */ -static uint8_t is_multicast_mac(uint8_t * mac) -{ - - uint16_t mc = 0x3333; - if (memcmp(mac, &mc, 2) == 0) - return 1; - - return 0; -} - -/** - * Ethernet: Receives an ethernet-packet and handles it according to - * Receive-handle diagram. - * - * @param fd socket fd - * @return ZERO - packet was handled or no packets received; - * NON ZERO - error condition occurs. - */ -int32_t receive_ether(int fd) -{ - int32_t bytes_received; - struct ethhdr * ethh; - - memset(ether_packet, 0, ETH_MTU_SIZE); - bytes_received = recv(fd, ether_packet, ETH_MTU_SIZE, 0); - - if (!bytes_received) // No messages - return 0; - - if (bytes_received < 0) - return -1; /* recv() failed */ - - if ((size_t) bytes_received < sizeof(struct ethhdr)) - return -1; // packet is too small - - ethh = (struct ethhdr *) ether_packet; - - if(memcmp(ethh->dest_mac, broadcast_mac, 6) != 0 - && memcmp(ethh->dest_mac, multicast_mac, 3) != 0 - && memcmp(ethh->dest_mac, own_mac, 6 ) != 0 - && !is_multicast_mac(ethh->dest_mac)) - return -1; // packet is too small - - switch (htons(ethh -> type)) { - case ETHERTYPE_IP: - return handle_ipv4(fd, (uint8_t*) (ethh + 1), - bytes_received - sizeof(struct ethhdr)); - - case ETHERTYPE_IPv6: - return handle_ipv6(fd, ether_packet + sizeof(struct ethhdr), - bytes_received - sizeof(struct ethhdr)); - - case ETHERTYPE_ARP: - return handle_arp(fd, (uint8_t*) (ethh + 1), - bytes_received - sizeof(struct ethhdr)); - default: - break; - } - return -1; // unknown protocol -} - -/** - * Ethernet: Sends an ethernet frame via the initialized file descriptor. - * - * @return number of transmitted bytes - */ -int -send_ether(int fd, void* buffer, int len) -{ - return send(fd, buffer, len, 0); -} - -/** - * Ethernet: Creates Ethernet-packet. Places Ethernet-header in a packet and - * fills it with corresponding information. - * <p> - * Use this function with similar functions for other network layers - * (fill_arphdr, fill_iphdr, fill_udphdr, fill_dnshdr, fill_btphdr). - * - * @param packet Points to the place where eth-header must be placed. - * @param eth_type Type of the next level protocol (e.g. IP or ARP). - * @param src_mac Sender MAC address - * @param dest_mac Receiver MAC address - * @see ethhdr - * @see fill_arphdr - * @see fill_iphdr - * @see fill_udphdr - * @see fill_dnshdr - * @see fill_btphdr - */ -void fill_ethhdr(uint8_t * packet, uint16_t eth_type, - const uint8_t * src_mac, const uint8_t * dest_mac) -{ - struct ethhdr * ethh = (struct ethhdr *) packet; - - ethh -> type = htons(eth_type); - memcpy(ethh -> src_mac, src_mac, 6); - memcpy(ethh -> dest_mac, dest_mac, 6); -} diff --git a/qemu/roms/SLOF/clients/net-snk/app/netlib/ethernet.h b/qemu/roms/SLOF/clients/net-snk/app/netlib/ethernet.h deleted file mode 100644 index e541c8f8e..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/netlib/ethernet.h +++ /dev/null @@ -1,47 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2008 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -#ifndef _ETHERNET_H -#define _ETHERNET_H - -#include <stdint.h> - -#define ETH_MTU_SIZE 1518 /**< Maximum Transfer Unit */ -#define ETH_ALEN 6 /**< HW address length */ -#define ETHERTYPE_IP 0x0800 -#define ETHERTYPE_IPv6 0x86DD -#define ETHERTYPE_ARP 0x0806 - -/** \struct ethhdr - * A header for Ethernet-packets. - */ -struct ethhdr { - uint8_t dest_mac[ETH_ALEN]; /**< Destination HW address */ - uint8_t src_mac[ETH_ALEN]; /**< Source HW address */ - uint16_t type; /**< Next level protocol type */ -}; - -/* Initializes ethernet layer */ -extern void set_mac_address(const uint8_t * own_mac); -extern const uint8_t * get_mac_address(void); - -/* Receives and handles packets, according to Receive-handle diagram */ -extern int32_t receive_ether(int fd); - -/* Sends an ethernet frame. */ -extern int send_ether(int fd, void* buffer, int len); - -/* fills ethernet header */ -extern void fill_ethhdr(uint8_t * packet, uint16_t eth_type, - const uint8_t * src_mac, const uint8_t * dest_mac); - -#endif diff --git a/qemu/roms/SLOF/clients/net-snk/app/netlib/icmpv6.c b/qemu/roms/SLOF/clients/net-snk/app/netlib/icmpv6.c deleted file mode 100644 index c104f7015..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/netlib/icmpv6.c +++ /dev/null @@ -1,390 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2013 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -#include <stdint.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <sys/socket.h> -#include <netlib/ethernet.h> -#include <netlib/ipv6.h> -#include <netlib/icmpv6.h> -#include <netlib/ndp.h> -#include <netlib/dhcpv6.h> - -static int ra_received = 0; - -/** - * NET: - * @param fd socket fd - */ -void -send_router_solicitation (int fd) -{ - ip6_addr_t dest_addr; - uint8_t ether_packet[ETH_MTU_SIZE]; - struct packeth headers; - - headers.ip6h = (struct ip6hdr *) (ether_packet + sizeof(struct ethhdr)); - headers.icmp6h = (struct icmp6hdr *) (ether_packet + - sizeof(struct ethhdr) + - sizeof(struct ip6hdr)); - - /* Destination is "All routers multicast address" (link-local) */ - dest_addr.part.prefix = 0xff02000000000000ULL; - dest_addr.part.interface_id = 2; - - /* Fill IPv6 header */ - fill_ip6hdr (ether_packet + sizeof(struct ethhdr), - ICMPv6_HEADER_SIZE + sizeof(struct router_solicitation), - 0x3a, //ICMPV6 - get_ipv6_address(), &dest_addr); - - /* Fill ICMPv6 message */ - headers.icmp6h->type = ICMPV6_ROUTER_SOLICITATION; - headers.icmp6h->code = 0; - headers.icmp6h->icmp6body.router_solicit.lladdr.type = 1; - headers.icmp6h->icmp6body.router_solicit.lladdr.length = 1; - memcpy( &(headers.icmp6h->icmp6body.router_solicit.lladdr.mac), - get_mac_address(), 6); - - send_ip (fd, headers.ip6h, sizeof(struct ip6hdr) + - ICMPv6_HEADER_SIZE + sizeof(struct router_solicitation)); -} - -/** - * NET: Process prefix option in Router Advertisements - * - * @param ip6_packet pointer to an IPv6 packet - */ -static void -handle_prefixoption (uint8_t *option) -{ - ip6_addr_t prefix; - struct ip6addr_list_entry *new_address; - struct option_prefix *prefix_option; - struct prefix_info *prfx_info; - - prefix_option = (struct option_prefix *) option; - memcpy( &(prefix.addr), &(prefix_option->prefix.addr), IPV6_ADDR_LENGTH); - - /* Link-local adresses in RAs are nonsense */ - if (ip6_is_linklocal(&prefix)) - return; - - if (prefix_option->preferred_lifetime > prefix_option->valid_lifetime) - return; - - /* Add address created from prefix to IPv6 address list */ - new_address = ip6_prefix2addr (prefix); - if (!new_address) - return; - - /* Process only prefixes we don't already have an adress from */ - if (!unknown_prefix (&new_address->addr)) { - return; - } - - /* Fill struct prefix_info from data in RA and store it in new_address */ - prfx_info = ip6_create_prefix_info(); - if (!prfx_info) - return; - memcpy (&(new_address->prfx_info), prfx_info, sizeof(struct prefix_info)); - - /* Add prefix received in RA to list of known prefixes */ - ip6addr_add (new_address); -} - -/** - * NET: Process source link layer addresses in Router Advertisements - * - * @param ip6_packet pointer to an IPv6 packet - */ -static void -handle_source_lladdr ( struct option_ll_address *option, struct router *rtr) -{ - memcpy (&(rtr->mac), &(option->mac), 6); -} - -/** - * NET: Process ICMPv6 options in Router Advertisements - * - * @param ip6_packet pointer to an IPv6 packet - */ -static void -process_ra_options (uint8_t *option, int32_t option_length, struct router *r) -{ - while (option_length > 0) { - switch (*option) { - case ND_OPTION_SOURCE_LL_ADDR: - handle_source_lladdr ((struct option_ll_address *) option, r); - break; - case ND_OPTION_PREFIX_INFO: - handle_prefixoption(option); - break; - default: - break; - } - //option+1 is the length field. length is in units of 8 bytes - option_length = option_length - (*(option+1) * 8); - option = option + (*(option+1) * 8); - } - - return; -} - -/** - * NET: Process Router Advertisements - * - * @param ip6_packet pointer to an IPv6 packet - */ -static void -handle_ra (struct icmp6hdr *icmp6h, uint8_t *ip6_packet) -{ - uint8_t *first_option; - int32_t option_length; - struct ip6hdr *ip6h; - struct router_advertisement *ra; - struct router *rtr; - ip6_addr_t *rtr_ip; - uint8_t rtr_mac[] = {0, 0, 0, 0, 0, 0}; - - ip6h = (struct ip6hdr *) ip6_packet; - ra = (struct router_advertisement *) &icmp6h->icmp6body.ra; - rtr_ip = (ip6_addr_t *) &ip6h->src; - - rtr = find_router (&(ip6h->src)); - if (!rtr) { - rtr = router_create (rtr_mac, rtr_ip); - router_add (rtr); - } - - /* store info from router advertisement in router struct */ - rtr->lifetime = ra->router_lifetime; - rtr->reachable_time = ra->reachable_time; - rtr->retrans_timer = ra->retrans_timer; - - /* save flags concerning address (auto-) configuration */ - ip6_state.managed_mode = ra->flags.managed; - ip6_state.other_config = ra->flags.other; - - /* Process ICMPv6 options in Router Advertisement */ - first_option = (uint8_t *) icmp6h + ICMPv6_HEADER_SIZE + 12; - option_length = (uint8_t *) icmp6h + ip6h->pl - first_option; - process_ra_options( (uint8_t *) first_option, option_length, rtr); - - ra_received = 1; -} - -int is_ra_received(void) -{ - return ra_received; -} - -/** - * NET: - * - * @param fd socket fd - * @param ip6_addr_t *dest_ip6 - */ -void -send_neighbour_solicitation (int fd, ip6_addr_t *dest_ip6) -{ - ip6_addr_t snma; - - uint8_t ether_packet[ETH_MTU_SIZE]; - struct packeth headers; - - memset(ether_packet, 0, ETH_MTU_SIZE); - headers.ethh = (struct ethhdr *) ether_packet; - headers.ip6h = (struct ip6hdr *) (ether_packet + sizeof(struct ethhdr)); - headers.icmp6h = (struct icmp6hdr *) (ether_packet + - sizeof(struct ethhdr) + - sizeof(struct ip6hdr)); - - /* Fill IPv6 header */ - snma.part.prefix = IPV6_SOLIC_NODE_PREFIX; - snma.part.interface_id = IPV6_SOLIC_NODE_IFACE_ID; - snma.addr[13] = dest_ip6->addr[13]; - snma.addr[14] = dest_ip6->addr[14]; - snma.addr[15] = dest_ip6->addr[15]; - fill_ip6hdr((uint8_t *) headers.ip6h, - ICMPv6_HEADER_SIZE + - sizeof(struct neighbour_solicitation), - 0x3a, //ICMPv6 - get_ipv6_address(), &snma); - - /* Fill ICMPv6 message */ - headers.icmp6h->type = ICMPV6_NEIGHBOUR_SOLICITATION; - headers.icmp6h->code = 0; - memcpy( &(headers.icmp6h->icmp6body.nghb_solicit.target), - dest_ip6, IPV6_ADDR_LENGTH ); - headers.icmp6h->icmp6body.nghb_solicit.lladdr.type = 1; - headers.icmp6h->icmp6body.nghb_solicit.lladdr.length = 1; - memcpy( &(headers.icmp6h->icmp6body.nghb_solicit.lladdr.mac), - get_mac_address(), 6); - - send_ip (fd, ether_packet + sizeof(struct ethhdr), - sizeof(struct ip6hdr) + ICMPv6_HEADER_SIZE + - sizeof(struct neighbour_solicitation)); -} - -/** - * NET: - * - * @param fd socket fd - * @param ip6_packet pointer to an IPv6 packet - * @param icmp6hdr pointer to the icmp6 header in ip6_packet - * @param na_flags Neighbour advertisment flags - */ -static void -send_neighbour_advertisement (int fd, struct neighbor *target) -{ - struct na_flags na_adv_flags; - uint8_t ether_packet[ETH_MTU_SIZE]; - struct packeth headers; - - - headers.ip6h = (struct ip6hdr *) (ether_packet + sizeof(struct ethhdr)); - headers.icmp6h = (struct icmp6hdr *) (ether_packet + - sizeof(struct ethhdr) + - sizeof(struct ip6hdr)); - - /* Fill IPv6 header */ - fill_ip6hdr(ether_packet + sizeof(struct ethhdr), - ICMPv6_HEADER_SIZE + - sizeof(struct neighbour_advertisement), - 0x3a, //ICMPv6 - get_ipv6_address(), (ip6_addr_t *) &(target->ip.addr)); - - /* Fill ICMPv6 message */ - memcpy( &(headers.icmp6h->icmp6body.nghb_adv.target), - &(target->ip.addr), IPV6_ADDR_LENGTH ); - headers.icmp6h->icmp6body.nghb_adv.lladdr.type = 1; - headers.icmp6h->icmp6body.nghb_adv.lladdr.length = 1; - memcpy( &(headers.icmp6h->icmp6body.nghb_adv.lladdr.mac), - get_mac_address(), 6); - - na_adv_flags.is_router = 0; - na_adv_flags.na_is_solicited = 1; - na_adv_flags.override = 1; - - headers.icmp6h->type = ICMPV6_NEIGHBOUR_ADVERTISEMENT; - headers.icmp6h->code = 0; - headers.icmp6h->icmp6body.nghb_adv.router = na_adv_flags.is_router; - - headers.icmp6h->icmp6body.nghb_adv.solicited = na_adv_flags.na_is_solicited; - headers.icmp6h->icmp6body.nghb_adv.override = na_adv_flags.override; - headers.icmp6h->icmp6body.nghb_adv.lladdr.type = 2; - headers.icmp6h->icmp6body.nghb_adv.lladdr.length = 1; - - memset( &(headers.icmp6h->icmp6body.nghb_adv.target), 0, - IPV6_ADDR_LENGTH ); - - if( na_adv_flags.na_is_solicited ) { - memcpy( &(headers.icmp6h->icmp6body.nghb_adv.target), - get_ipv6_address(), IPV6_ADDR_LENGTH); - } - - memcpy( &(headers.icmp6h->icmp6body.nghb_adv.lladdr.mac), - get_mac_address(), 6); - - send_ip (fd, ether_packet + sizeof(struct ethhdr), - sizeof(struct ip6hdr) + ICMPv6_HEADER_SIZE + - sizeof(struct neighbour_advertisement)); -} - -/** - * NET: - * - * @param fd socket fd - * @param ip6_packet pointer to an IPv6 packet - */ -static int8_t -handle_na (int fd, uint8_t *packet) -{ - struct neighbor *n = NULL; - struct packeth headers; - ip6_addr_t ip; - - headers.ethh = (struct ethhdr *) packet; - headers.ip6h = (struct ip6hdr *) ((unsigned char *) headers.ethh + - sizeof(struct ethhdr)); - headers.icmp6h = (struct icmp6hdr *) (packet + - sizeof(struct ethhdr) + - sizeof(struct ip6hdr)); - - memcpy(&(ip.addr), &(headers.ip6h->src), IPV6_ADDR_LENGTH); - - n = find_neighbor (&ip); - - if (!n) { - n= (struct neighbor *) - neighbor_create( packet, &headers ); - if (!n) - return 0; - if (!neighbor_add(n)) - return 0; - } else { - memcpy (&(n->mac), &(headers.ethh->src_mac[0]), 6); - - if (n->eth_len > 0) { - struct ethhdr * ethh = (struct ethhdr *) &(n->eth_frame); - memcpy(ethh->dest_mac, &(n->mac), 6); - send_ether (fd, &(n->eth_frame), n->eth_len + sizeof(struct ethhdr)); - n->eth_len = 0; - } - } - - return 1; -} - -/** - * NET: Handles ICMPv6 messages - * - * @param fd socket fd - * @param ip6_packet pointer to an IPv6 packet - * @param packetsize size of ipv6_packet - */ -int8_t -handle_icmpv6 (int fd, struct ethhdr *etherhdr, - uint8_t *ip6_packet) -{ - - struct icmp6hdr *received_icmp6 = NULL; - struct ip6hdr *received_ip6 = NULL; - struct neighbor target; - - received_ip6 = (struct ip6hdr *) ip6_packet; - received_icmp6 = (struct icmp6hdr *) (ip6_packet + - sizeof(struct ip6hdr)); - memcpy( &(target.ip.addr), &(received_ip6->src), - IPV6_ADDR_LENGTH ); - memcpy( &(target.mac), etherhdr->src_mac, 6); - - /* process ICMPv6 types */ - switch(received_icmp6->type) { - case ICMPV6_NEIGHBOUR_SOLICITATION: - send_neighbour_advertisement(fd, &target); - break; - case ICMPV6_NEIGHBOUR_ADVERTISEMENT: - handle_na(fd, (uint8_t *) ip6_packet - sizeof(struct ethhdr)); - break; - case ICMPV6_ROUTER_ADVERTISEMENT: - handle_ra(received_icmp6, (uint8_t *) received_ip6); - break; - default: - return -1; - } - - return 1; -} diff --git a/qemu/roms/SLOF/clients/net-snk/app/netlib/icmpv6.h b/qemu/roms/SLOF/clients/net-snk/app/netlib/icmpv6.h deleted file mode 100644 index 32797973d..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/netlib/icmpv6.h +++ /dev/null @@ -1,135 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2013 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -#ifndef _ICMPV6_H_ -#define _ICMPV6_H_ - -#include <stdint.h> -#include <netlib/ethernet.h> -#include <netlib/ipv6.h> - -#define __ICMPV6_DEBUG__ - -#ifdef __ICMPV6_DEBUG__ -#define ICMPV6_DEBUG_PRINT(format, ...) printf(format, ## __VA_ARGS__) -#else -#define ICMPV6_DEBUG_PRINT(format, ...) -#endif - -#define ICMPv6_HEADER_SIZE 4 /* Size of common fields */ -#define IPTYPE_ICMPV6 0x3a - -/* Error message types */ -#define ICMPV6_DEST_UNREACHABLE 1 /* Destination unreachable */ -#define ICMPV6_PACKET_TOO_BIG 2 /* Packet too big */ -#define ICMPV6_TIME_EXCEEDED 3 /* Time exceeded */ -#define ICMPV6_PARAM_PROBLEM 4 /* Parameter problem */ - -/* Informational message types */ -#define ICMPV6_ECHO_REQUEST 128 /* Echo request */ -#define ICMPV6_ECHO_REPLY 129 /* Echo reply */ -#define ICMPV6_MCAST_LISTENER_QUERY 130 /* Multicast listener query */ -#define ICMPV6_MCAST_LISTENER_REPORT 131 /* Multicast listener report */ -#define ICMPv6 MCAST_LISTENER_DONE 132 /* Multicast listener done */ -#define ICMPV6_ROUTER_SOLICITATION 133 /* Router solicitation */ -#define ICMPV6_ROUTER_ADVERTISEMENT 134 /* Router advertisement */ -#define ICMPV6_NEIGHBOUR_SOLICITATION 135 /* Neighbor solicitation */ -#define ICMPV6_NEIGHBOUR_ADVERTISEMENT 136 /* Neighbor advertisement */ -#define ICMPV6_REDIRECT_MSG 137 /* Redirect message */ - -/******** Functions *******************/ -int8_t handle_icmpv6 (int fd, struct ethhdr *etherhdr, uint8_t *ip6_packet); -void send_neighbour_solicitation(int fd, ip6_addr_t *target_ip6); -void send_router_solicitation(int fd); -int is_ra_received(void); - -/* Prefix information */ -struct option_prefix { - uint8_t type; - uint8_t length; - uint8_t prefix_length; - uint8_t onlink:1, - autom:1, - not_router:1, - not_site_prefix:1, - reserved:4; - uint32_t valid_lifetime; - uint32_t preferred_lifetime; - uint32_t reserved2; - ip6_addr_t prefix; -} __attribute((packed)); - -/* Neighbour advertisement/solicitation flags */ -struct na_flags { - uint8_t is_router:1, /* sender (we) is a router */ - na_is_solicited:1, /* this NA was solicited (asked for) */ - override:1, /* receiver shall override its cache entries */ - unused:5; -}__attribute((packed)); - -/* Source/Target Link-layer address */ -struct option_ll_address{ - uint8_t type; - uint8_t length; - uint8_t mac[ETH_ALEN]; -} __attribute((packed)); - -struct neighbour_solicitation { - uint32_t router:1, - solicited:1, - override:1, - reserved:29; - ip6_addr_t target; - struct option_ll_address lladdr; -} __attribute((packed)); - -struct neighbour_advertisement { - uint32_t router:1, - solicited:1, - override:1, - reserved:29; - ip6_addr_t target; - struct option_ll_address lladdr; -} __attribute((packed)); - -struct router_solicitation { - uint32_t reserved; - struct option_ll_address lladdr; -} __attribute((packed)); - -struct router_advertisement { - uint8_t curr_hop_limit; - struct raflags { - uint8_t managed:1, - other:1, - reserved:6; - } flags; - uint16_t router_lifetime; - uint32_t reachable_time; - uint32_t retrans_timer; - struct option_prefix prefix; - struct option_ll_address ll_addr; -} __attribute((packed)); - -struct icmp6hdr { - uint8_t type; - uint8_t code; - uint16_t checksum; - union { - struct neighbour_solicitation nghb_solicit; - struct neighbour_advertisement nghb_adv; - struct router_solicitation router_solicit; - struct router_advertisement ra; - } icmp6body; -} __attribute((packed)); - -#endif diff --git a/qemu/roms/SLOF/clients/net-snk/app/netlib/ipv4.c b/qemu/roms/SLOF/clients/net-snk/app/netlib/ipv4.c deleted file mode 100644 index 2b92c77c4..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/netlib/ipv4.c +++ /dev/null @@ -1,877 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2008 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - - -/********************** DEFINITIONS & DECLARATIONS ***********************/ - -#include <ipv4.h> -#include <udp.h> -#include <tcp.h> -#include <ethernet.h> -#include <time.h> -#include <sys/socket.h> -#include <string.h> - -/* ARP Message types */ -#define ARP_REQUEST 1 -#define ARP_REPLY 2 - -/* ARP talbe size (+1) */ -#define ARP_ENTRIES 10 - -/* ICMP Message types */ -#define ICMP_ECHO_REPLY 0 -#define ICMP_DST_UNREACHABLE 3 -#define ICMP_SRC_QUENCH 4 -#define ICMP_REDIRECT 5 -#define ICMP_ECHO_REQUEST 8 -#define ICMP_TIME_EXCEEDED 11 -#define ICMP_PARAMETER_PROBLEM 12 -#define ICMP_TIMESTAMP_REQUEST 13 -#define ICMP_TIMESTAMP_REPLY 14 -#define ICMP_INFORMATION_REQUEST 15 -#define ICMP_INFORMATION_REPLY 16 - -/** \struct arp_entry - * A entry that describes a mapping between IPv4- and MAC-address. - */ -typedef struct arp_entry arp_entry_t; -struct arp_entry { - uint32_t ipv4_addr; - uint8_t mac_addr[6]; - uint8_t eth_frame[ETH_MTU_SIZE]; - int eth_len; - int pkt_pending; -}; - -/** \struct icmphdr - * ICMP packet - */ -struct icmphdr { - unsigned char type; - unsigned char code; - unsigned short int checksum; - union { - /* for type 3 "Destination Unreachable" */ - unsigned int unused; - /* for type 0 and 8 */ - struct echo { - unsigned short int id; - unsigned short int seq; - } echo; - } options; - union { - /* payload for destination unreachable */ - struct dun { - unsigned char iphdr[20]; - unsigned char data[64]; - } dun; - /* payload for echo or echo reply */ - /* maximum size supported is 84 */ - unsigned char data[84]; - } payload; -}; - -/****************************** PROTOTYPES *******************************/ - -static unsigned short checksum(unsigned short *packet, int words); - -static void arp_send_request(int fd, uint32_t dest_ip); - -static void arp_send_reply(int fd, uint32_t src_ip, uint8_t * src_mac); - -static void fill_arphdr(uint8_t * packet, uint8_t opcode, - const uint8_t * src_mac, uint32_t src_ip, - const uint8_t * dest_mac, uint32_t dest_ip); - -static arp_entry_t *lookup_mac_addr(uint32_t ipv4_addr); - -static void fill_udp_checksum(struct iphdr *ipv4_hdr); - -static int8_t handle_icmp(int fd, struct iphdr * iph, uint8_t * packet, - int32_t packetsize); - -/****************************** LOCAL VARIABLES **************************/ - -/* Routing parameters */ -static uint32_t own_ip = 0; -static uint32_t multicast_ip = 0; -static uint32_t router_ip = 0; -static uint32_t subnet_mask = 0; - -/* helper variables */ -static uint32_t ping_dst_ip; -static const uint8_t null_mac_addr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; -static const uint8_t broadcast_mac[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; -static uint8_t multicast_mac[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; - -/* There are only (ARP_ENTRIES-1) effective entries because - * the entry that is pointed by arp_producer is never used. - */ -static unsigned int arp_consumer = 0; -static unsigned int arp_producer = 0; -static arp_entry_t arp_table[ARP_ENTRIES]; - -static uint8_t pending_pkt_frame[ETH_MTU_SIZE]; -static int pending_pkt_len; - -/* Function pointer send_ip. Points either to send_ipv4() or send_ipv6() */ -int (*send_ip) (int fd, void *, int); - -/***************************** IMPLEMENTATION ****************************/ - -/** - * IPv4: Initialize the environment for the IPv4 layer. - */ -static void ipv4_init(void) -{ - int i; - - ping_dst_ip = 0; - - // clear ARP table - arp_consumer = 0; - arp_producer = 0; - for(i=0; i<ARP_ENTRIES; ++i) { - arp_table[i].ipv4_addr = 0; - memset(arp_table[i].mac_addr, 0, 6); - arp_table[i].eth_len = 0; - arp_table[i].pkt_pending = 0; - } - - /* Set IP send function to send_ipv4() */ - send_ip = &send_ipv4; -} - -/** - * IPv4: Set the own IPv4 address. - * - * @param _own_ip client IPv4 address (e.g. 127.0.0.1) - */ -void set_ipv4_address(uint32_t _own_ip) -{ - own_ip = _own_ip; - ipv4_init(); -} - -/** - * IPv4: Get the own IPv4 address. - * - * @return client IPv4 address (e.g. 127.0.0.1) - */ -uint32_t get_ipv4_address(void) -{ - return own_ip; -} - -/** - * IPv4: Set the IPv4 multicast address. - * - * @param _own_ip multicast IPv4 address (224.0.0.0 - 239.255.255.255) - */ -void set_ipv4_multicast(uint32_t _multicast_ip) -{ - // is this IP Multicast out of range (224.0.0.0 - 239.255.255.255) - if((htonl(_multicast_ip) < 0xE0000000) - || (htonl(_multicast_ip) > 0xEFFFFFFF)) { - multicast_ip = 0; - memset(multicast_mac, 0xFF, 6); - return; - } - - multicast_ip = _multicast_ip; - multicast_mac[0] = 0x01; - multicast_mac[1] = 0x00; - multicast_mac[2] = 0x5E; - multicast_mac[3] = (uint8_t) 0x7F & (multicast_ip >> 16); - multicast_mac[4] = (uint8_t) 0xFF & (multicast_ip >> 8); - multicast_mac[5] = (uint8_t) 0xFF & (multicast_ip >> 0); -} - -/** - * IPv4: Get the IPv4 multicast address. - * - * @return multicast IPv4 address (224.0.0.0 - 239.255.255.255 or 0 if not set) - */ -uint32_t get_ipv4_multicast(void) -{ - return multicast_ip; -} - -/** - * IPv4: Set the routers IPv4 address. - * - * @param _router_ip router IPv4 address - */ -void set_ipv4_router(uint32_t _router_ip) -{ - router_ip = _router_ip; - ipv4_init(); -} - -/** - * IPv4: Get the routers IPv4 address. - * - * @return router IPv4 address - */ -uint32_t get_ipv4_router(void) -{ - return router_ip; -} - -/** - * IPv4: Set the subnet mask. - * - * @param _subnet_mask netmask of the own IPv4 address - */ -void set_ipv4_netmask(uint32_t _subnet_mask) -{ - subnet_mask = _subnet_mask; - ipv4_init(); -} - -/** - * IPv4: Get the subnet mask. - * - * @return netmask of the own IPv4 address - */ -uint32_t get_ipv4_netmask(void) -{ - return subnet_mask; -} - -/** - * IPv4: Creates IP-packet. Places IP-header in a packet and fills it - * with corresponding information. - * <p> - * Use this function with similar functions for other network layers - * (fill_ethhdr, fill_udphdr, fill_dnshdr, fill_btphdr). - * - * @param packet Points to the place where IP-header must be placed. - * @param packetsize Size of the packet in bytes incl. this hdr and data. - * @param ip_proto Type of the next level protocol (e.g. UDP). - * @param ip_src Sender IP address - * @param ip_dst Receiver IP address - * @see iphdr - * @see fill_ethhdr - * @see fill_udphdr - * @see fill_dnshdr - * @see fill_btphdr - */ -void fill_iphdr(uint8_t * packet, uint16_t packetsize, - uint8_t ip_proto, uint32_t ip_src, uint32_t ip_dst) -{ - struct iphdr * iph = (struct iphdr *) packet; - - iph -> ip_hlv = 0x45; - iph -> ip_tos = 0x10; - iph -> ip_len = htons(packetsize); - iph -> ip_id = htons(0); - iph -> ip_off = 0; - iph -> ip_ttl = 0xFF; - iph -> ip_p = ip_proto; - iph -> ip_src = htonl(ip_src); - iph -> ip_dst = htonl(ip_dst); - iph -> ip_sum = 0; -} - -/** - * IPv4: Handles IPv4-packets according to Receive-handle diagram. - * - * @param fd socket fd - * @param ip_packet IP-packet to be handled - * @param packetsize Length of the packet - * @return ZERO - packet handled successfully; - * NON ZERO - packet was not handled (e.g. bad format) - * @see receive_ether - * @see iphdr - */ -int8_t handle_ipv4(int fd, uint8_t * ip_packet, uint32_t packetsize) -{ - struct iphdr * iph; - int32_t old_sum; - static uint8_t ip_heap[65536 + ETH_MTU_SIZE]; - - if (packetsize < sizeof(struct iphdr)) - return -1; // packet is too small - - iph = (struct iphdr * ) ip_packet; - - /* Drop it if destination IPv4 address is no IPv4 Broadcast, no - * registered IPv4 Multicast and not our Unicast address - */ - if((multicast_ip == 0 && iph->ip_dst >= 0xE0000000 && iph->ip_dst <= 0xEFFFFFFF) - || (multicast_ip != iph->ip_dst && iph->ip_dst != 0xFFFFFFFF && - own_ip != 0 && iph->ip_dst != own_ip)) { - return -1; - } - - old_sum = iph -> ip_sum; - iph -> ip_sum = 0; - if (old_sum != checksum((uint16_t *) iph, sizeof (struct iphdr) >> 1)) - return -1; // Wrong IP checksum - - // is it the first fragment in a packet? - if (((iph -> ip_off) & 0x1FFF) == 0) { - // is it part of more fragments? - if (((iph -> ip_off) & 0x2000) == 0x2000) { - memcpy(ip_heap, ip_packet, iph->ip_len); - return 0; - } - } - // it's not the first fragment - else { - // get the first fragment - struct iphdr * iph_first = (struct iphdr * ) ip_heap; - - // is this fragment not part of the first one, then exit - if ((iph_first->ip_id != iph->ip_id ) || - (iph_first->ip_p != iph->ip_p ) || - (iph_first->ip_src != iph->ip_src) || - (iph_first->ip_dst != iph->ip_dst)) { - return 0; - } - - // this fragment is part of the first one! - memcpy(ip_heap + sizeof(struct iphdr) + - ((iph -> ip_off) & 0x1FFF) * 8, - ip_packet + sizeof(struct iphdr), - iph -> ip_len - sizeof(struct iphdr)); - - // is it part of more fragments? Then return. - if (((iph -> ip_off) & 0x2000) == 0x2000) { - return 0; - } - - // packet is completly reassambled now! - - // recalculate ip_len and set iph and ip_packet to the - iph_first->ip_len = iph->ip_len + ((iph->ip_off) & 0x1FFF) * 8; - - // set iph and ip_packet to the resulting packet. - ip_packet = ip_heap; - iph = (struct iphdr * ) ip_packet; - } - - switch (iph -> ip_p) { - case IPTYPE_ICMP: - return handle_icmp(fd, iph, ip_packet + sizeof(struct iphdr), - iph -> ip_len - sizeof(struct iphdr)); - case IPTYPE_UDP: - return handle_udp(fd, ip_packet + sizeof(struct iphdr), - iph -> ip_len - sizeof(struct iphdr)); - case IPTYPE_TCP: - return handle_tcp(ip_packet + sizeof(struct iphdr), - iph -> ip_len - sizeof(struct iphdr)); - default: - break; - } - return -1; // Unknown protocol -} - -/** - * IPv4: Send IPv4-packets. - * - * Before the packet is sent there are some patcches performed: - * - IPv4 source address is replaced by our unicast IPV4 address - * if it is set to 0 or 1 - * - IPv4 destination address is replaced by our multicast IPV4 address - * if it is set to 1 - * - IPv4 checksum is calculaded. - * - If payload type is UDP, then the UDP checksum is calculated also. - * - * We send an ARP request first, if this is the first packet sent to - * the declared IPv4 destination address. In this case we store the - * the packet and send it later if we receive the ARP response. - * If the MAC address is known already, then we send the packet immediately. - * If there is already an ARP request pending, then we drop this packet - * and send again an ARP request. - * - * @param fd socket fd - * @param ip_packet IP-packet to be handled - * @param packetsize Length of the packet - * @return -2 - packet dropped (MAC address not resolved - ARP request pending) - * -1 - packet dropped (bad format) - * 0 - packet stored (ARP request sent - packet will be sent if - * ARP response is received) - * >0 - packet send (number of transmitted bytes is returned) - * - * @see receive_ether - * @see iphdr - */ -int send_ipv4(int fd, void* buffer, int len) -{ - arp_entry_t *arp_entry = 0; - struct iphdr *ip; - const uint8_t *mac_addr = 0; - uint32_t ip_dst = 0; - - if(len + sizeof(struct ethhdr) > ETH_MTU_SIZE) - return -1; - - ip = (struct iphdr *) buffer; - - /* Replace source IPv4 address with our own unicast IPv4 address - * if it's 0 (= own unicast source address not specified). - */ - if(ip->ip_src == 0) { - ip->ip_src = htonl( own_ip ); - } - /* Replace source IPv4 address with our unicast IPv4 address and - * replace destination IPv4 address with our multicast IPv4 address - * if source address is set to 1. - */ - else if(ip->ip_src == 1) { - ip->ip_src = htonl( own_ip ); - ip->ip_dst = htonl( multicast_ip ); - } - - // Calculate the IPv4 checksum - ip->ip_sum = 0; - ip->ip_sum = checksum((uint16_t *) ip, sizeof (struct iphdr) >> 1); - - // if payload type is UDP, then we need to calculate the - // UDP checksum that depends on the IP header - if(ip->ip_p == IPTYPE_UDP) { - fill_udp_checksum(ip); - } - - ip_dst = ip->ip_dst; - // Check if the MAC address is already cached - if(~ip->ip_dst == 0 - || ( ((~subnet_mask) & ip->ip_dst) == ~subnet_mask && - ( subnet_mask & ip->ip_dst) == (subnet_mask & own_ip))) { - arp_entry = &arp_table[arp_producer]; - mac_addr = broadcast_mac; - } - else if(ip->ip_dst == multicast_ip) { - arp_entry = &arp_table[arp_producer]; - mac_addr = multicast_mac; - } - else { - // Check if IP address is in the same subnet as we are - if((subnet_mask & own_ip) == (subnet_mask & ip->ip_dst)) - arp_entry = lookup_mac_addr(ip->ip_dst); - // if not then we need to know the router's IP address - else { - ip_dst = router_ip; - arp_entry = lookup_mac_addr(router_ip); - } - if(arp_entry && memcmp(arp_entry->mac_addr, null_mac_addr, 6) != 0) - mac_addr = arp_entry->mac_addr; - } - - // If we could not resolv the MAC address by our own... - if(!mac_addr) { - // send the ARP request - arp_send_request(fd, ip_dst); - - // drop the current packet if there is already a ARP request pending - if(arp_entry) - return -2; - - // take the next entry in the ARP table to prepare a the new ARP entry. - arp_entry = &arp_table[arp_producer]; - arp_producer = (arp_producer+1)%ARP_ENTRIES; - - // if ARP table is full then we must drop the oldes entry. - if(arp_consumer == arp_producer) - arp_consumer = (arp_consumer+1)%ARP_ENTRIES; - - // store the packet to be send if the ARP reply is received - arp_entry->pkt_pending = 1; - arp_entry->ipv4_addr = ip_dst; - memset(arp_entry->mac_addr, 0, 6); - fill_ethhdr (pending_pkt_frame, htons(ETHERTYPE_IP), - get_mac_address(), null_mac_addr); - memcpy(&pending_pkt_frame[sizeof(struct ethhdr)], - buffer, len); - pending_pkt_len = len + sizeof(struct ethhdr); - - set_timer(TICKS_SEC); - do { - receive_ether(fd); - if (!arp_entry->eth_len) - break; - } while (get_timer() > 0); - - return 0; - } - - // Send the packet with the known MAC address - fill_ethhdr(arp_entry->eth_frame, htons(ETHERTYPE_IP), - get_mac_address(), mac_addr); - memcpy(&arp_entry->eth_frame[sizeof(struct ethhdr)], buffer, len); - return send_ether(fd, arp_entry->eth_frame, len + sizeof(struct ethhdr)); -} - -/** - * IPv4: Calculate UDP checksum. Places the result into the UDP-header. - * <p> - * Use this function after filling the UDP payload. - * - * @param ipv4_hdr Points to the place where IPv4-header starts. - */ -static void fill_udp_checksum(struct iphdr *ipv4_hdr) -{ - unsigned i; - unsigned long checksum = 0; - struct iphdr ip_hdr; - char *ptr; - udp_hdr_t *udp_hdr; - - udp_hdr = (udp_hdr_t *) (ipv4_hdr + 1); - udp_hdr->uh_sum = 0; - - memset(&ip_hdr, 0, sizeof(struct iphdr)); - ip_hdr.ip_src = ipv4_hdr->ip_src; - ip_hdr.ip_dst = ipv4_hdr->ip_dst; - ip_hdr.ip_len = udp_hdr->uh_ulen; - ip_hdr.ip_p = ipv4_hdr->ip_p; - - ptr = (char*) udp_hdr; - for (i = 0; i < udp_hdr->uh_ulen; i+=2) - checksum += *((uint16_t*) &ptr[i]); - - ptr = (char*) &ip_hdr; - for (i = 0; i < sizeof(struct iphdr); i+=2) - checksum += *((uint16_t*) &ptr[i]); - - checksum = (checksum >> 16) + (checksum & 0xffff); - checksum += (checksum >> 16); - udp_hdr->uh_sum = ~checksum; - - /* As per RFC 768, if the computed checksum is zero, - * it is transmitted as all ones (the equivalent in - * one's complement arithmetic). - */ - if (udp_hdr->uh_sum == 0) - udp_hdr->uh_sum = ~udp_hdr->uh_sum; -} - -/** - * IPv4: Calculates checksum for IP header. - * - * @param packet Points to the IP-header - * @param words Size of the packet in words incl. IP-header and data. - * @return Checksum - * @see iphdr - */ -static unsigned short checksum(unsigned short * packet, int words) -{ - unsigned long checksum; - - for (checksum = 0; words > 0; words--) - checksum += *packet++; - checksum = (checksum >> 16) + (checksum & 0xffff); - checksum += (checksum >> 16); - - return ~checksum; -} - -static arp_entry_t* lookup_mac_addr(uint32_t ipv4_addr) -{ - unsigned int i; - - for(i=arp_consumer; i != arp_producer; i = ((i+1)%ARP_ENTRIES) ) { - if(arp_table[i].ipv4_addr == ipv4_addr) - return &arp_table[i]; - } - return 0; -} - - -/** - * ARP: Sends an ARP-request package. - * For given IPv4 retrieves MAC via ARP (makes several attempts) - * - * @param fd socket fd - * @param dest_ip IP of the host which MAC should be obtained - */ -static void arp_send_request(int fd, uint32_t dest_ip) -{ - arp_entry_t *arp_entry = &arp_table[arp_producer]; - - memset(arp_entry->eth_frame, 0, sizeof(struct ethhdr) + sizeof(struct arphdr)); - fill_arphdr(&arp_entry->eth_frame[sizeof(struct ethhdr)], ARP_REQUEST, - get_mac_address(), own_ip, broadcast_mac, dest_ip); - fill_ethhdr(arp_entry->eth_frame, ETHERTYPE_ARP, - get_mac_address(), broadcast_mac); - - send_ether(fd, arp_entry->eth_frame, - sizeof(struct ethhdr) + sizeof(struct arphdr)); -} - -/** - * ARP: Sends an ARP-reply package. - * This package is used to serve foreign requests (in case IP in - * foreign request matches our host IP). - * - * @param fd socket fd - * @param src_ip requester IP address (foreign IP) - * @param src_mac requester MAC address (foreign MAC) - */ -static void arp_send_reply(int fd, uint32_t src_ip, uint8_t * src_mac) -{ - arp_entry_t *arp_entry = &arp_table[arp_producer]; - - memset(arp_entry->eth_frame, 0, sizeof(struct ethhdr) + sizeof(struct arphdr)); - fill_ethhdr(arp_entry->eth_frame, ETHERTYPE_ARP, - get_mac_address(), src_mac); - fill_arphdr(&arp_entry->eth_frame[sizeof(struct ethhdr)], ARP_REPLY, - get_mac_address(), own_ip, src_mac, src_ip); - - send_ether(fd, arp_entry->eth_frame, - sizeof(struct ethhdr) + sizeof(struct arphdr)); -} - -/** - * ARP: Creates ARP package. Places ARP-header in a packet and fills it - * with corresponding information. - * <p> - * Use this function with similar functions for other network layers - * (fill_ethhdr). - * - * @param packet Points to the place where ARP-header must be placed. - * @param opcode Identifies is it request (ARP_REQUEST) - * or reply (ARP_REPLY) package. - * @param src_mac sender MAC address - * @param src_ip sender IP address - * @param dest_mac receiver MAC address - * @param dest_ip receiver IP address - * @see arphdr - * @see fill_ethhdr - */ -static void fill_arphdr(uint8_t * packet, uint8_t opcode, - const uint8_t * src_mac, uint32_t src_ip, - const uint8_t * dest_mac, uint32_t dest_ip) -{ - struct arphdr * arph = (struct arphdr *) packet; - - arph -> hw_type = htons(1); - arph -> proto_type = htons(ETHERTYPE_IP); - arph -> hw_len = 6; - arph -> proto_len = 4; - arph -> opcode = htons(opcode); - - memcpy(arph->src_mac, src_mac, 6); - arph->src_ip = htonl(src_ip); - memcpy(arph->dest_mac, dest_mac, 6); - arph->dest_ip = htonl(dest_ip); -} - -/** - * ARP: Handles ARP-messages according to Receive-handle diagram. - * Updates arp_table for outstanding ARP requests (see arp_getmac). - * - * @param fd socket fd - * @param packet ARP-packet to be handled - * @param packetsize length of the packet - * @return ZERO - packet handled successfully; - * NON ZERO - packet was not handled (e.g. bad format) - * @see arp_getmac - * @see receive_ether - * @see arphdr - */ -int8_t handle_arp(int fd, uint8_t * packet, uint32_t packetsize) -{ - struct arphdr * arph = (struct arphdr *) packet; - - if (packetsize < sizeof(struct arphdr)) - return -1; // Packet is too small - - if (arph -> hw_type != htons(1) || arph -> proto_type != htons(ETHERTYPE_IP)) - return -1; // Unknown hardware or unsupported protocol - - if (arph -> dest_ip != htonl(own_ip)) - return -1; // receiver IP doesn't match our IP - - switch(htons(arph -> opcode)) { - case ARP_REQUEST: - // foreign request - if(own_ip != 0) - arp_send_reply(fd, htonl(arph->src_ip), arph -> src_mac); - return 0; // no error - case ARP_REPLY: { - unsigned int i; - // if it is not for us -> return immediately - if(memcmp(get_mac_address(), arph->dest_mac, 6)) { - return 0; // no error - } - - if(arph->src_ip == 0) { - // we are not interested for a MAC address if - // the IPv4 address is 0.0.0.0 or ff.ff.ff.ff - return -1; - } - - // now let's find the corresponding entry in the ARP table - - for(i=arp_consumer; i != arp_producer; i = ((i+1)%ARP_ENTRIES) ) { - if(arp_table[i].ipv4_addr == arph->src_ip) - break; - } - if(i == arp_producer || memcmp(arp_table[i].mac_addr, null_mac_addr, 6) != 0) { - // we have not asked to resolve this IPv4 address ! - return -1; - } - - memcpy(arp_table[i].mac_addr, arph->src_mac, 6); - - // do we have something to send - if (arp_table[i].pkt_pending) { - struct ethhdr * ethh = (struct ethhdr *) pending_pkt_frame; - memcpy(ethh -> dest_mac, arp_table[i].mac_addr, 6); - - send_ether(fd, pending_pkt_frame, pending_pkt_len); - arp_table[i].pkt_pending = 0; - arp_table[i].eth_len = 0; - } - return 0; // no error - } - default: - break; - } - return -1; // Invalid message type -} - -/** - * ICMP: Send an ICMP Echo request to destination IPv4 address. - * This function does also set a global variable to the - * destination IPv4 address. If there is an ICMP Echo Reply - * received later then the variable is set back to 0. - * In other words, reading a value of 0 form this variable - * means that an answer to the request has been arrived. - * - * @param fd socket descriptor - * @param _ping_dst_ip destination IPv4 address - */ -void ping_ipv4(int fd, uint32_t _ping_dst_ip) -{ - unsigned char packet[sizeof(struct iphdr) + sizeof(struct icmphdr)]; - struct icmphdr *icmp; - - ping_dst_ip = _ping_dst_ip; - - if(ping_dst_ip == 0) - return; - - fill_iphdr(packet, sizeof(struct iphdr) + sizeof(struct icmphdr), IPTYPE_ICMP, - 0, ping_dst_ip); - icmp = (struct icmphdr *) (packet + sizeof(struct iphdr)); - icmp->type = ICMP_ECHO_REQUEST; - icmp->code = 0; - icmp->checksum = 0; - icmp->options.echo.id = 0xd476; - icmp->options.echo.seq = 1; - - memset(icmp->payload.data, '*', sizeof(icmp->payload.data)); - - icmp->checksum = - checksum((unsigned short *) icmp, sizeof(struct icmphdr) >> 1); - send_ipv4(fd, packet, sizeof(struct iphdr) + sizeof(struct icmphdr)); -} - -/** - * ICMP: Return host IPv4 address that we are waiting for a - * ICMP Echo reply message. If this value is 0 then we have - * received an reply. - * - * @return ping_dst_ip host IPv4 address - */ -uint32_t pong_ipv4(void) -{ - return ping_dst_ip; -} - -/** - * ICMP: Handles ICMP-packets according to Receive-handle diagram. - * - * @param fd socket fd - * @param icmp_packet ICMP-packet to be handled - * @param packetsize Length of the packet - * @return ZERO - packet handled successfully; - * NON ZERO - packet was not handled (e.g. bad format) - * @see handle_ipv4 - */ -static int8_t handle_icmp(int fd, struct iphdr * iph, uint8_t * packet, - int32_t packetsize) -{ - struct icmphdr *icmp = (struct icmphdr *) packet; - - switch(icmp->type) { - case ICMP_ECHO_REPLY: - if (icmp->options.echo.id != 0xd476) - return -1; - if (icmp->options.echo.seq != 1) - return -1; - if(ping_dst_ip != iph->ip_src - || ping_dst_ip == 0) - return -1; - ping_dst_ip = 0; - break; - case ICMP_DST_UNREACHABLE: { - // We've got Destination Unreachable msg - // Inform corresponding upper network layers - struct iphdr * bad_iph = (struct iphdr * ) &icmp->payload; - - switch(bad_iph->ip_p) { - case IPTYPE_TCP: - handle_tcp_dun((uint8_t *) (bad_iph + 1), packetsize - - sizeof(struct icmphdr) - - sizeof(struct iphdr), icmp->code); - break; - case IPTYPE_UDP: - handle_udp_dun((uint8_t *) (bad_iph + 1), packetsize - - sizeof(struct icmphdr) - - sizeof(struct iphdr), icmp->code); - break; - } - break; - } - case ICMP_SRC_QUENCH: - break; - case ICMP_REDIRECT: - break; - case ICMP_ECHO_REQUEST: { - // We've got an Echo Request - answer with Echo Replay msg - unsigned char reply_packet[sizeof(struct iphdr) + packetsize]; - struct icmphdr *reply_icmph; - - fill_iphdr(reply_packet, sizeof(struct iphdr) + packetsize, - IPTYPE_ICMP, 0, iph->ip_src); - - reply_icmph = (struct icmphdr *) &reply_packet[sizeof(struct iphdr)]; - memcpy(reply_icmph, packet, packetsize); - reply_icmph -> type = ICMP_ECHO_REPLY; - reply_icmph -> checksum = 0; - reply_icmph->checksum = checksum((unsigned short *) reply_icmph, - sizeof(struct icmphdr) >> 1); - - send_ipv4(fd, reply_packet, sizeof(struct iphdr) + packetsize); - break; - } - case ICMP_TIME_EXCEEDED: - break; - case ICMP_PARAMETER_PROBLEM: - break; - case ICMP_TIMESTAMP_REQUEST: - break; - case ICMP_TIMESTAMP_REPLY: - break; - case ICMP_INFORMATION_REQUEST: - break; - case ICMP_INFORMATION_REPLY: - break; - } - return 0; -} diff --git a/qemu/roms/SLOF/clients/net-snk/app/netlib/ipv4.h b/qemu/roms/SLOF/clients/net-snk/app/netlib/ipv4.h deleted file mode 100644 index 18821ea74..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/netlib/ipv4.h +++ /dev/null @@ -1,96 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2008 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - - -#ifndef _IPV4_H_ -#define _IPV4_H_ - -#include <stdint.h> - -#define IPTYPE_ICMP 1 - -/** \struct iphdr - * A header for IP-packets. - * For more information see RFC 791. - */ -struct iphdr { - uint8_t ip_hlv; /**< Header length and version of the header */ - uint8_t ip_tos; /**< Type of Service */ - uint16_t ip_len; /**< Length in octets, inlc. this header and data */ - uint16_t ip_id; /**< ID is used to aid in assembling framents */ - uint16_t ip_off; /**< Info about fragmentation (control, offset) */ - uint8_t ip_ttl; /**< Time to Live */ - uint8_t ip_p; /**< Next level protocol type */ - uint16_t ip_sum; /**< Header checksum */ - uint32_t ip_src; /**< Source IP address */ - uint32_t ip_dst; /**< Destination IP address */ -}; -typedef struct iphdr ipv4_hdr_t; - -/* ICMP Error Codes */ -#define ICMP_NET_UNREACHABLE 0 -#define ICMP_HOST_UNREACHABLE 1 -#define ICMP_PROTOCOL_UNREACHABLE 2 -#define ICMP_PORT_UNREACHABLE 3 -#define ICMP_FRAGMENTATION_NEEDED 4 -#define ICMP_SOURCE_ROUTE_FAILED 5 - -/** \struct arphdr - * A header for ARP-messages, retains info about HW and proto addresses. - * For more information see RFC 826. - */ -struct arphdr { - uint16_t hw_type; /**< HW address space (1 for Ethernet) */ - uint16_t proto_type; /**< Protocol address space */ - uint8_t hw_len; /**< Byte length of each HW address */ - uint8_t proto_len; /**< Byte length of each proto address */ - uint16_t opcode; /**< Identifies is it request (1) or reply (2) */ - uint8_t src_mac[6]; /**< HW address of sender of this packet */ - uint32_t src_ip; /**< Proto address of sender of this packet */ - uint8_t dest_mac[6]; /**< HW address of target of this packet */ - uint32_t dest_ip; /**< Proto address of target of this packet */ -} __attribute((packed)); - -/************** Initialization of the IPv4 network layer. **************/ -extern void set_ipv4_address(uint32_t own_ip); -extern uint32_t get_ipv4_address(void); -extern void set_ipv4_multicast(uint32_t multicast_ip); -extern uint32_t get_ipv4_multicast(void); -extern void set_ipv4_router(uint32_t router_ip); -extern uint32_t get_ipv4_router(void); -extern void set_ipv4_netmask(uint32_t subnet_mask); -extern uint32_t get_ipv4_netmask(void); - -extern int (*send_ip) (int fd, void *, int); - -/* fills ip header */ -extern void fill_iphdr(uint8_t * packet, uint16_t packetsize, - uint8_t ip_proto, uint32_t ip_src, uint32_t ip_dst); - -/* Send a IPv4 packet. Adding the Ethernet-Header and resolving the - * MAC address is done transparent in the background if necessary. - */ -extern int send_ipv4(int fd, void* buffer, int len); - -/* Sends an ICMP Echo request to destination IPv4 address */ -extern void ping_ipv4(int fd, uint32_t _ping_dst_ip); - -/* Returns host IPv4 address that we are waiting for a response */ -extern uint32_t pong_ipv4(void); - -/* Handles IPv4-packets that are detected by receive_ether. */ -extern int8_t handle_ipv4(int fd, uint8_t * packet, uint32_t packetsize); - -/* Handles ARP-packets that are detected by receive_ether. */ -extern int8_t handle_arp(int fd, uint8_t * packet, uint32_t packetsize); - -#endif diff --git a/qemu/roms/SLOF/clients/net-snk/app/netlib/ipv6.c b/qemu/roms/SLOF/clients/net-snk/app/netlib/ipv6.c deleted file mode 100644 index 62d29ea86..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/netlib/ipv6.c +++ /dev/null @@ -1,747 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2013 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -#include <string.h> -#include <stdlib.h> -#include <stdio.h> -#include <time.h> -#include <ctype.h> -#include <sys/socket.h> -#include <netlib/ethernet.h> -#include <netlib/ipv6.h> -#include <netlib/icmpv6.h> -#include <netlib/ndp.h> -#include <netlib/udp.h> - -#undef IPV6_DEBUG -//#define IPV6_DEBUG -#ifdef IPV6_DEBUG -#define dprintf(_x ...) do { printf(_x); } while (0) -#else -#define dprintf(_x ...) -#endif - -/****************************** PROTOTYPES *******************************/ -int8_t ip6addr_add (struct ip6addr_list_entry *new_address); -static void ipv6_init(int fd); -static int ip6_is_multicast (ip6_addr_t * ip); - -/****************************** LOCAL VARIABLES **************************/ - -/* List of Ipv6 Addresses */ -static struct ip6addr_list_entry *first_ip6; -static struct ip6addr_list_entry *last_ip6; - -/* Own IPv6 address */ -static struct ip6addr_list_entry *own_ip6; - -/* All nodes link-local address */ -struct ip6addr_list_entry all_nodes_ll; - -/* Null IPv6 address */ -static ip6_addr_t null_ip6; - -/* helper variables */ -static uint8_t null_mac[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - -struct ip6_config ip6_state; - -/****************************** IMPLEMENTATION ***************************/ - -/** - * IPv6: Set the own IPv6 address. - * - * @param fd Socket descriptor - * @param _own_ip client IPv6 address (e.g. ::1) - */ -void set_ipv6_address(int fd, ip6_addr_t *_own_ip6) -{ - struct ip6addr_list_entry *ile; - - own_ip6 = malloc (sizeof(struct ip6addr_list_entry)); - - /* If no address was passed as a parameter generate a link-local - * address from our MAC address.*/ - if (_own_ip6 == NULL) - memcpy(&(own_ip6->addr.addr), - ip6_create_ll_address(get_mac_address()), - IPV6_ADDR_LENGTH); - else - memcpy (&(own_ip6->addr.addr), _own_ip6, 16); - - /* Add to our list of IPv6 addresses */ - ip6addr_add (own_ip6); - - ipv6_init(fd); - - /* - * Check whether we've got a non-link-local address during - * ipv6_init() and use that as preferred address if possible - */ - if (_own_ip6 == NULL) { - for (ile = first_ip6; ile != NULL ; ile = ile->next) { - if (!ip6_is_multicast(&ile->addr) && - !ip6_is_linklocal(&ile->addr)) { - own_ip6 = ile; - break; - } - } - } -} - -/** - * IPv6: Get pointer to own IPv6 address. - * - * @return pointer to client IPv6 address (e.g. ::1) - */ -ip6_addr_t *get_ipv6_address(void) -{ - return (ip6_addr_t *) &(own_ip6->addr); -} - -/** - * IPv6: Search for IPv6 address in list - * - * @return 0 - IPv6 address is not in list - * 1 - IPv6 address is in list - */ -static int8_t find_ip6addr(ip6_addr_t *ip) -{ - struct ip6addr_list_entry *n = NULL; - - if (ip == NULL) - return 0; - - for (n = first_ip6; n != NULL ; n=n->next) - if (ip6_cmp (&(n->addr), ip)) - return 1; /* IPv6 address is in our list*/ - - return 0; /* not one of our IPv6 addresses*/ -} - -/** - * NET: Handles IPv6-packets - * - * @param fd - Socket descriptor - * @param ip6_packet - Pointer to IPv6 header - * @param packetsize - Size of Ipv6 packet - * @return ERROR - -1 if packet is too small or unknown protocol - * return value of handle_udp - * - * @see handle_udp - * @see ip6hdr - */ -int8_t handle_ipv6(int fd, uint8_t * ip6_packet, uint32_t packetsize) -{ - - struct ip6hdr *ip6 = NULL; - ip6 = (struct ip6hdr *) ip6_packet; - - /* Only handle packets which are for us */ - if (! find_ip6addr(&(ip6->dst))) - return -1; - - if (packetsize < sizeof(struct ip6hdr)) - return -1; // packet is too small - - switch (ip6->nh) { - case IPTYPE_UDP: - return handle_udp (fd, ip6_packet + sizeof (struct ip6hdr), - ip6->pl); - case IPTYPE_ICMPV6: - return handle_icmpv6 (fd, (struct ethhdr *) ip6_packet - sizeof(struct ethhdr), - ip6_packet); - } - - return -1; // unknown protocol -} - - /** - * NET: Creates IPv6-packet. Places IPv6-header in a packet and fills it - * with corresponding information. - * <p> - * Use this function with similar functions for other network layers - * (fill_ethhdr, fill_udphdr, fill_dnshdr, fill_btphdr). - * - * @param packet Points to the place where IPv6-header must be placed. - * @param packetsize Size of payload (i.e. excluding ethhdr and ip6hdr) - * @param ip_proto Type of the next level protocol (e.g. UDP). - * @param ip6_src Sender IPv6 address - * @param ip6_dst Receiver IPv6 address - * @see ip6hdr - * @see fill_iphdr - * @see fill_ethhdr - * @see fill_udphdr - * @see fill_dnshdr - * @see fill_btphdr - */ -void fill_ip6hdr(uint8_t * packet, uint16_t packetsize, - uint8_t ip_proto, ip6_addr_t *ip6_src, ip6_addr_t *ip6_dst) -{ - struct ip6hdr * ip6h = (struct ip6hdr *) packet; - - ip6h->ver_tc_fl = 6 << 28; // set version to 6 - ip6h->pl = packetsize; // IPv6 payload size - ip6h->nh = ip_proto; - ip6h->hl = 255; - memcpy (&(ip6h->src), ip6_src, IPV6_ADDR_LENGTH); - memcpy (&(ip6h->dst), ip6_dst, IPV6_ADDR_LENGTH); -} - -/** - * NET: For a given MAC calculates EUI64-Identifier. - * See RFC 4291 "IP Version 6 Addressing Architecture" - * - */ -uint64_t mac2eui64(const uint8_t *mac) -{ - uint8_t eui64id[8]; - uint64_t retid; - - memcpy (eui64id, mac, 3); - memcpy (eui64id + 5, mac + 3, 3); - eui64id[3] = 0xff; - eui64id[4] = 0xfe; - - memcpy(&retid, eui64id, 8); - return retid; -} - -/** - * NET: create link-local IPv6 address - * - * @param own_mac MAC of NIC - * @return ll_addr pointer to newly created link-local address - */ -ip6_addr_t *ip6_create_ll_address(const uint8_t *own_mac) -{ - ip6_addr_t *ll_addr; - - ll_addr = malloc (sizeof (struct ip6addr_list_entry)); - memset (ll_addr, 0, IPV6_ADDR_LENGTH); - ll_addr->part.prefix |= IPV6_LL_PREFIX; - ll_addr->part.interface_id |= mac2eui64((uint8_t *) own_mac); - - return ll_addr; -} - -/* - * NET: check if we already have an address with the same prefix. - * @param struct ip6_addr_list_entry *ip6 - * @return true or false - */ -int8_t unknown_prefix(ip6_addr_t *ip) -{ - struct ip6addr_list_entry *node; - - for( node = first_ip6; node != NULL; node=node->next ) - if( node->addr.part.prefix == ip->part.prefix ) - return 0; /* address is one of ours */ - - return 1; /* prefix not yet in our list */ -} - -/* - * NET: Create empty element for prefix list and return a pointer to it; - * @return NULL - malloc failed - * ! NULL - pointer to new prefix_info - */ -struct prefix_info *ip6_create_prefix_info() -{ - struct prefix_info *prfx_info; - - prfx_info = malloc (sizeof(struct prefix_info)); - if (!prfx_info) - return NULL; - - return prfx_info; -} - -/* - * NET: create a new IPv6 address with a given network prefix - * and add it to our IPv6 address list - * - * @param ip6_addr prefix (as received in RA) - * @return NULL - pointer to new ip6addr_list entry - */ -void *ip6_prefix2addr(ip6_addr_t prefix) -{ - struct ip6addr_list_entry *new_address; - uint64_t interface_id; - - new_address = malloc (sizeof(struct ip6addr_list_entry)); - if( !new_address ) - return NULL; - - /* fill new addr struct */ - /* extract prefix from Router Advertisement */ - memcpy (&(new_address->addr.part.prefix), &prefix, 8 ); - - /* interface id is generated from MAC address */ - interface_id = mac2eui64 (get_mac_address()); - memcpy (&(new_address->addr.part.interface_id), &interface_id, 8); - - return new_address; -} - -/** - * NET: add new IPv6 adress to list - * - * @param ip6_addr *new_address - * @return 0 - passed pointer = NULL; - * 1 - ok - */ -int8_t ip6addr_add(struct ip6addr_list_entry *new_address) -{ - struct ip6addr_list_entry *solicited_node; - - - if (new_address == NULL) - return 0; - - /* Don't add the same address twice */ - if (find_ip6addr (&(new_address->addr))) - return 0; - - /* If address is a unicast address, we also have to process packets - * for its solicited-node multicast address. - * See RFC 2373 - IP Version 6 Adressing Architecture */ - if (! ip6_is_multicast(&(new_address->addr))) { - - - solicited_node = malloc(sizeof(struct ip6addr_list_entry)); - if (! solicited_node) - return 0; - - solicited_node->addr.part.prefix = IPV6_SOLIC_NODE_PREFIX; - solicited_node->addr.part.interface_id = IPV6_SOLIC_NODE_IFACE_ID; - solicited_node->addr.addr[13] = new_address->addr.addr[13]; - solicited_node->addr.addr[14] = new_address->addr.addr[14]; - solicited_node->addr.addr[15] = new_address->addr.addr[15]; - ip6addr_add (solicited_node); - } - - if (NULL == first_ip6) - first_ip6 = new_address; - last_ip6->next = new_address; - last_ip6 = new_address; - last_ip6->next = NULL; - - return 1; /* no error */ -} - -/** - * NET: Initialize IPv6 - * - * @param fd socket fd - */ -static void ipv6_init(int fd) -{ - int i = 0; - - send_ip = &send_ipv6; - - /* Address configuration parameters */ - ip6_state.managed_mode = 0; - - /* Null IPv6 address */ - null_ip6.part.prefix = 0; - null_ip6.part.interface_id = 0; - - /* Multicast addresses */ - all_nodes_ll.addr.part.prefix = 0xff02000000000000; - all_nodes_ll.addr.part.interface_id = 1; - ip6addr_add(&all_nodes_ll); - - ndp_init(); - - send_router_solicitation (fd); - for(i=0; i < 4 && !is_ra_received(); i++) { - set_timer(TICKS_SEC); - do { - receive_ether(fd); - if (is_ra_received()) - break; - } while (get_timer() > 0); - } -} - -/** - * NET: compare IPv6 adresses - * - * @param ip6_addr ip_1 - * @param ip6_addr ip_2 - */ -int8_t ip6_cmp(ip6_addr_t *ip_1, ip6_addr_t *ip_2) -{ - return ((int8_t) !memcmp( &(ip_1->addr[0]), &(ip_2->addr[0]), - IPV6_ADDR_LENGTH )); -} - -/** - * NET: Calculate checksum over IPv6 header and upper-layer protocol - * (e.g. UDP or ICMPv6) - * - * @param *ip - pointer to IPv6 address - * @return true or false - */ -int ip6_is_multicast(ip6_addr_t * ip) -{ - return ip->addr[0] == 0xFF; -} - -/** - * NET: Generate multicast MAC address from IPv6 address - * (e.g. UDP or ICMPv6) - * - * @param *ip - pointer to IPv6 address - * @param *mc_mac pointer to an array with 6 bytes (for the MAC address) - * @return pointer to Multicast MAC address - */ -static uint8_t *ip6_to_multicast_mac(ip6_addr_t * ip, uint8_t *mc_mac) -{ - mc_mac[0] = 0x33; - mc_mac[1] = 0x33; - memcpy (mc_mac+2, (uint8_t *) &(ip->addr)+12, 4); - - return mc_mac; -} - -/** - * NET: calculate checksum over IPv6 header and upper-layer protocol - * (e.g. UDP or ICMPv6) - * - * @param struct ip6hdr *ip6h - pointer to IPv6 header - * @param unsigned short *packet - pointer to header of upper-layer - * protocol - * @param int words - number of words (as in 2 bytes) - * starting from *packet - * @return checksum - */ -static unsigned short ip6_checksum(struct ip6hdr *ip6h, unsigned short *packet, - int words) -{ - int i=0; - unsigned long checksum; - struct ip6hdr pseudo_ip6h; - unsigned short *pip6h; - - memcpy (&pseudo_ip6h, ip6h, sizeof(struct ip6hdr)); - pseudo_ip6h.hl = ip6h->nh; - pseudo_ip6h.ver_tc_fl = 0; - pseudo_ip6h.nh = 0; - pip6h = (unsigned short *) &pseudo_ip6h; - - for (checksum = 0; words > 0; words--) { - checksum += *packet++; - i++; - } - - for (i = 0; i < 20; i++) { - checksum += *pip6h++; - } - - checksum = (checksum >> 16) + (checksum & 0xffff); - checksum += (checksum >> 16); - - return ~checksum; -} - -/** - * NET: Handles IPv6-packets - * - * @param fd socket fd - * @param ip6_packet Pointer to IPv6 header in packet - * @param packetsize Size of IPv6 packet - * @return -1 == ERRROR - * return of handle_udp() or handle_icmp6() - * - * @see receive_ether - * @see ip6hdr - */ -int send_ipv6(int fd, void* buffer, int len) -{ - struct neighbor *n; - struct ip6hdr *ip6h; - struct udphdr *udph; - struct icmp6hdr *icmp6h; - ip6_addr_t ip_dst; - uint8_t *mac_addr, mac[6]; - - mac_addr = mac; - - ip6h = (struct ip6hdr *) buffer; - udph = (struct udphdr *) ((uint8_t *) ip6h + sizeof (struct ip6hdr)); - icmp6h = (struct icmp6hdr *) ((uint8_t *) ip6h + sizeof (struct ip6hdr)); - - memcpy(&ip_dst, &ip6h->dst, 16); - - if(len + sizeof(struct ethhdr) > 1500) - return -1; - - if ( ip6_cmp (&ip6h->src, &null_ip6)) - memcpy (&(ip6h->src), get_ipv6_address(), IPV6_ADDR_LENGTH); - - if (ip6h->nh == 17) {//UDP - udph->uh_sum = ip6_checksum (ip6h, (unsigned short *) udph , - ip6h->pl >> 1); - /* As per RFC 768, if the computed checksum is zero, - * it is transmitted as all ones (the equivalent in - * one's complement arithmetic). - */ - if (udph->uh_sum == 0) - udph->uh_sum = ~udph->uh_sum; - } - else if (ip6h->nh == 0x3a) //ICMPv6 - icmp6h->checksum = ip6_checksum (ip6h, - (unsigned short *) icmp6h, - ip6h->pl >> 1); - - n = find_neighbor (&ip_dst); - - // If address is a multicast address, create a proper mac address - if (ip6_is_multicast (&ip_dst)) { - mac_addr = ip6_to_multicast_mac (&ip_dst, mac); - } - else { - // Check if the MAC address is already cached - if (n) { - if (memcmp(n->mac, null_mac, ETH_ALEN) != 0) - memcpy (mac_addr, &(n->mac), ETH_ALEN); /* found it */ - } else { - mac_addr = null_mac; - n = malloc(sizeof(struct neighbor)); - memcpy(&(n->ip.addr[0]), &ip_dst, 16); - n->status = NB_PROBE; - n->times_asked += 1; - neighbor_add(n); - } - - if (! memcmp (mac_addr, &null_mac, 6)) { - if (n->eth_len == 0) { - send_neighbour_solicitation (fd, &ip_dst); - - // Store the packet until we know the MAC address - memset(n->eth_frame, 0, 1500); - fill_ethhdr (n->eth_frame, - htons(ETHERTYPE_IPv6), - get_mac_address(), - mac_addr); - memcpy (&(n->eth_frame[sizeof(struct ethhdr)]), - buffer, len); - n->eth_len = len; - set_timer(TICKS_SEC); - do { - receive_ether(fd); - } while (get_timer() > 0); - } - } - } - - fill_ethhdr (n->eth_frame, htons(ETHERTYPE_IPv6), get_mac_address(), - mac_addr); - memcpy (&(n->eth_frame[sizeof(struct ethhdr)]), buffer, len); - return send_ether (fd, n->eth_frame, len + sizeof(struct ethhdr)); -} - -static int check_colons(const char *str) -{ - char *pch, *prv; - int col = 0; - int dcol = 0; - - dprintf("str : %s\n",str); - pch = strchr(str, ':'); - while(pch != NULL){ - prv = pch; - pch = strchr(pch+1, ':'); - if((pch-prv) != 1) { - col++; - } else { - col--; /* Its part of double colon */ - dcol++; - } - } - - dprintf("The number of col : %d \n",col); - dprintf("The number of dcol : %d \n",dcol); - - if((dcol > 1) || /* Cannot have 2 "::" */ - ((dcol == 1) && (col > 5)) || /* Too many ':'s */ - ((dcol == 0) && (col != 7)) ) { /* Too few ':'s */ - dprintf(" exiting for check_colons \n"); - return 0; - } - - return (col+dcol); -} - -static int ipv6str_to_bytes(const char *str, char *ip) -{ - char block[5]; - int res; - char *pos; - uint32_t cnt = 0, len; - - dprintf("str : %s \n",str); - - while (*str != 0) { - if (cnt > 15 || !isxdigit(*str)){ - return 0; - } - if ((pos = strchr(str, ':')) != NULL) { - len = (int16_t) (pos - str); - dprintf("\t len is : %d \n",len); - if (len > 4) - return 0; - strncpy(block, str, len); - block[len] = 0; - dprintf("\t str : %s \n",str); - dprintf("\t block : %s \n",block); - str += len; - } else { - strncpy(block, str, 4); - block[4] = 0; - dprintf("\t str : %s \n",str); - dprintf("\t block : %s \n",block); - str += strlen(block); - } - res = strtol(block, NULL, 16); - dprintf("\t res : %x \n",res); - if ((res > 0xFFFF) || (res < 0)) - return 0; - ip[cnt++] = (res & 0xFF00) >> 8; - ip[cnt++] = (res & 0x00FF); - if (*str == ':'){ - str++; - } - } - - dprintf("cnt : %d\n",cnt); - return cnt; -} - -int str_to_ipv6(const char *str, uint8_t *ip) -{ - int i, k; - uint16_t len; - char *ptr; - char tmp[30], buf[16]; - - memset(ip,0,16); - - if(!check_colons(str)) - return 0; - - if ((ptr = strstr(str, "::")) != NULL) { - /* Handle the ::1 IPv6 loopback */ - if(!strcmp(str,"::1")) { - ip[15] = 1; - return 16; - } - len = (ptr-str); - dprintf(" len : %d \n",len); - if (len >= sizeof(tmp)) - return 0; - strncpy(tmp, str, len); - tmp[len] = 0; - ptr += 2; - - i = ipv6str_to_bytes(ptr, buf); - if(i == 0) - return i; - - #if defined(ARGS_DEBUG) - int j; - dprintf("=========== bottom part i : %d \n",i); - for(j=0; j<i; j++) - dprintf("%02x \t",buf[j]); - #endif - - /* Copy the bottom part i.e bytes following "::" */ - memcpy(ip+(16-i), buf, i); - - k = ipv6str_to_bytes(tmp, buf); - if(k == 0) - return k; - - #if defined(ARGS_DEBUG) - dprintf("=========== top part k : %d \n",k); - for(j=0; j<k; j++) - printf("%02x \t",buf[j]); - #endif - - /* Copy the top part i.e bytes before "::" */ - memcpy(ip, buf, k); - #if defined(ARGS_DEBUG) - dprintf("\n"); - for(j=0; j<16; j++) - dprintf("%02x \t",ip[j]); - #endif - - } else { - i = ipv6str_to_bytes(str, (char *)ip); - } - return i; -} - -void ipv6_to_str(const uint8_t *ip, char *str) -{ - int i, len; - uint8_t byte_even, byte_odd; - char *consec_zero, *strptr; - - *str = 0; - for (i = 0; i < 16; i+=2) { - byte_even = ip[i]; - byte_odd = ip[i+1]; - if (byte_even) - sprintf(str, "%s%x%02x", str, byte_even, byte_odd); - else if (byte_odd) - sprintf(str, "%s%x", str, byte_odd); - else - strcat(str, "0"); - if (i != 14) - strcat(str, ":"); - } - strptr = str; - do { - consec_zero = strstr(strptr, "0:0:"); - if (consec_zero) { - len = consec_zero - strptr; - if (!len) - break; - else if (strptr[len-1] == ':') - break; - else - strptr = consec_zero + 2; - } - } while (consec_zero); - if (consec_zero) { - len = consec_zero - str; - str[len] = 0; - if (len) - strcat(str, ":"); - else - strcat(str, "::"); - strptr = consec_zero + 4; - while (*strptr) { - if (!strncmp(strptr, "0:", 2)) - strptr += 2; - else - break; - } - strcat(str, strptr); - if (!strcmp(str, "::0")) - strcpy(str, "::"); - } -} diff --git a/qemu/roms/SLOF/clients/net-snk/app/netlib/ipv6.h b/qemu/roms/SLOF/clients/net-snk/app/netlib/ipv6.h deleted file mode 100644 index 72c6ee22f..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/netlib/ipv6.h +++ /dev/null @@ -1,188 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2013 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -#ifndef _IPV6_H_ -#define _IPV6_H_ - -#include <stdint.h> -#include <netlib/ethernet.h> - -#define __IPV6_DEBUG__ - -#ifdef __IPV6_DEBUG__ -#define IPV6_DEBUG_PRINT(format, ...) do { printf(format, ## __VA_ARGS__); } while (0) -#else -#define IPV6_DEBUG_PRINT(format, ...) -#endif - -#define IPV6_ADDR_LENGTH 16 /* Size of IPv6 adress in bytes */ -#define IPV6_LL_PREFIX 0xFE80000000000000ULL -#define IPV6_LL_PREFIX_MASK 0xFFC0000000000000ULL -#define IPV6_SOLIC_NODE_PREFIX 0xFF02000000000000ULL -#define IPV6_SOLIC_NODE_IFACE_ID 0x00000001FF000000ULL - -/** - * An IPv6 Address - */ -typedef union { - uint8_t addr[IPV6_ADDR_LENGTH]; - struct { - uint64_t prefix; - uint64_t interface_id; - } part; -} ip6_addr_t; - -typedef struct { - uint8_t type; - uint8_t pad[7]; - union { - ip6_addr_t v6; - char v4[4]; - } addr; -} netaddr_t; - -/** \struct prefix_info - * - * List of Prefixes we have adresses from - * Used for internal purposes, information derived from prefix option - * in Router Advertisements - * See RFC 4861 section 4.6.2 - */ -struct prefix_info { - uint64_t prefix; - uint8_t on_link:1, /* When set prefix can be used for on-link - * determination */ - autoconf:1, /* Prefix can be used for stateless address - * configuration */ - reserved1:6; - uint32_t valid_lifetime; /* Time until prefix expires */ - uint32_t preferred_lifetime; /* Time until prefix becomes deprecated */ - uint32_t start_time; /* Time when received */ - uint32_t reserved2; - struct prefix_info *next; -}; - - -/* List of IPv6 addresses */ -struct ip6addr_list_entry { - ip6_addr_t addr; - struct prefix_info prfx_info; - struct ip6addr_list_entry *next; -}; - -/** \struct ip6hdr - * A header for IPv6 packets. - * For more information see RFC 2460 - */ -struct ip6hdr { - uint32_t ver_tc_fl; /**< Version, Traffic class, Flow label */ - uint16_t pl; /**< Payload length */ - uint8_t nh; /**< Next header */ - uint8_t hl; /**< Hop limit */ - ip6_addr_t src; /**< IPv6 source address */ - ip6_addr_t dst; /**< IPv6 destination address */ -} __attribute((packed)); - -/** \struct packeth - * Struct with pointers to headers within a packet - */ -struct packeth { - struct ethhdr *ethh; - struct ip6hdr *ip6h; - struct icmp6hdr *icmp6h; - struct udphdr *udph; - /* ... */ -}; - -/** \struct parseip6_state - * Stores information about state of IPv6 address parser - */ -struct parseip6_state { - char *lookahead; - char *ptr; - const char *addr; - int state; - int s1ctr; - int s2ctr; - int blocknr; - int zeroblocks; - int i; - int done; - int errorcode; -}; - -/** \struct ip6_config - * Stores flags wheter we use Stateless- or Stateful Autoconfiguration or DHCPv6 - */ -struct ip6_config { - uint8_t managed_mode:1, - other_config:1, - reserved:6; -}; - -/******************** VARIABLES **********************************************/ -/* Function pointer send_ip. Points either to send_ipv4() or send_ipv6() */ -extern int (*send_ip) (int fd, void *, int); - -extern struct ip6_config ip6_state; - -/******************** FUNCTIONS *********************************************/ -/* Handles IPv6-packets that are detected by receive_ether. */ -int8_t handle_ipv6(int fd, uint8_t * ip6_packet, uint32_t packetsize); - -/* Fill IPv6 header */ -void fill_ip6hdr(uint8_t * packet, uint16_t packetsize, - uint8_t ip_proto, ip6_addr_t *ip6_src, ip6_addr_t *ip6_dst); - -/* Set own IPv6 address */ -void set_ipv6_address(int fd, ip6_addr_t *own_ip6); - -/* Get own IPv6 address */ -ip6_addr_t *get_ipv6_address(void); - -/* Create link-local address from a given Mac Address */ -ip6_addr_t * ip6_create_ll_address (const uint8_t *own_mac); - -/* For a given MAC calculates EUI64-Identifier.*/ -uint64_t mac2eui64 (const uint8_t *mac); - -/* Create empty element for prefix list and return a pointer to it */ -struct prefix_info * ip6_create_prefix_info(void); - -/* Create a new IPv6 address with a given network prefix - * and add it to our IPv6 address list */ -void * ip6_prefix2addr (ip6_addr_t prefix); - -/* Compare IPv6 adresses */ -int8_t ip6_cmp( ip6_addr_t *ip_1, ip6_addr_t *ip_2 ); - -/* Check if it is a link-local address */ -static inline int ip6_is_linklocal(ip6_addr_t *ip) -{ - return (ip->part.prefix & IPV6_LL_PREFIX_MASK) == IPV6_LL_PREFIX; -} - -/* Check if prefix is already in our list */ -int8_t unknown_prefix (ip6_addr_t *ip); - -/* Send IPv6 packet */ -int send_ipv6 (int fd, void* buffer, int len); - -/* Add IPv6 address to list */ -int8_t ip6addr_add (struct ip6addr_list_entry *new_address); - -/* Parse an IPv6 address */ -int parseip6(const char *addr, uint8_t *parsedaddr); -int str_to_ipv6(const char *str, uint8_t *ip); -void ipv6_to_str(const uint8_t *ip, char *str); - -#endif diff --git a/qemu/roms/SLOF/clients/net-snk/app/netlib/ndp.c b/qemu/roms/SLOF/clients/net-snk/app/netlib/ndp.c deleted file mode 100644 index 96faa8716..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/netlib/ndp.c +++ /dev/null @@ -1,166 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2013 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -#include <netlib/ipv6.h> -#include <netlib/icmpv6.h> -#include <netlib/ndp.h> - -/* Neighbor cache */ -static struct neighbor *first_neighbor; -static struct neighbor *last_neighbor; - -/* Router list */ -static struct router *first_router; -static struct router *last_router; - -/* - * NET: add new router to list - * @param struct router nghb - new router - * @return true or false - */ -int8_t -router_add (struct router *nghb ) -{ - if (nghb == NULL) - return -1; - - if (first_router == NULL) { - first_router= nghb; - last_router = first_router; - last_router->next = NULL; - } else { - last_router->next = nghb; - last_router = nghb; - last_router->next = NULL; - } - return 1; /* no error */ -} - -/* - * NET: create a new router - * @param uint8_t *packet - received packet (Ethernet/IPv6/ICMPv6/ND_NghSlct) - * @param struct packeth - pointers to headers in packet - * @return pointer to new router - */ -void * -router_create (uint8_t *mac, ip6_addr_t *ip) -{ - struct router *new_router; - - new_router = malloc (sizeof(struct router)); - if( !new_router) { - return 0; - } - memset (new_router, 0, sizeof(struct router)); - - /* fill neighbor struct */ - memcpy (new_router->mac, mac, 6); - memcpy (&(new_router->ip.addr[0]), &(ip->addr[0]), IPV6_ADDR_LENGTH); - - return new_router; -} - -struct router * -find_router( ip6_addr_t *ip ) -{ - struct router *n = NULL; - - for (n = first_router; n != NULL ; n=n->next) - if (ip6_cmp (&(n->ip), ip)) - return n; /* router is already in list*/ - - return NULL; /* router is unknown */ -} - -/* - * NET: add new neighbor to list - * @param struct neighbor nghb - new neighbor - * @return true or false - */ -int8_t -neighbor_add (struct neighbor *nghb) -{ - if (nghb == NULL) - return -1; - - if (first_neighbor == NULL) { - first_neighbor = nghb; - last_neighbor = first_neighbor; - last_neighbor->next = NULL; - } else { - last_neighbor->next = nghb; - last_neighbor = nghb; - last_neighbor->next = NULL; - } - - return 1; /* no error */ -} - -/* - * NET: create a new neighbor - * @param uint8_t *packet - received packet (Ethernet/IPv6/ICMPv6/ND_NghSlct) - * @param struct packeth - pointers to headers in packet - * @return pointer - pointer to new neighbor - * NULL - malloc failed - */ -void * -neighbor_create (uint8_t *packet, struct packeth *headers) -{ - struct neighbor *new_neighbor; - - new_neighbor = malloc (sizeof(struct neighbor)); - if( !new_neighbor ) - return NULL; - - /* fill neighbor struct */ - memcpy (&(new_neighbor->mac), - &(headers->ethh->src_mac[0]), 6); - memcpy (&(new_neighbor->ip.addr), &(headers->ip6h->src), IPV6_ADDR_LENGTH); - new_neighbor->status = NB_INCOMPLETE; - - return new_neighbor; -} - -/** - * NET: Find neighbor with given IPv6 address in Neighbor Cache - * - * @param ip - Pointer to IPv6 address - * @return pointer - pointer to client IPv6 address (e.g. ::1) - * NULL - Neighbor not found - */ -struct neighbor * -find_neighbor (ip6_addr_t *ip) -{ - struct neighbor *n = NULL; - - for (n = first_neighbor; n != NULL ; n=n->next) { - if (ip6_cmp (&(n->ip), ip)) { - return n; /* neighbor is already in cache */ - } - } - - return NULL; /* neighbor is unknown */ -} - -void ndp_init(void) -{ - /* Router list */ - first_router = NULL; - last_router = first_router; - - /* Init Neighbour cache */ - first_neighbor = NULL; - last_neighbor = first_neighbor; -} diff --git a/qemu/roms/SLOF/clients/net-snk/app/netlib/ndp.h b/qemu/roms/SLOF/clients/net-snk/app/netlib/ndp.h deleted file mode 100644 index c785c4897..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/netlib/ndp.h +++ /dev/null @@ -1,71 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2013 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -#ifndef _NDP_H_ -#define _NDP_H_ - -#include <netlib/ipv6.h> - -#define __NDP_DEBUG__ - -#ifdef __NDP_DEBUG__ -#define NDP_DEBUG_PRINT(format, ...) do { printf(format, ## __VA_ARGS__); } while (0) -#else -#define NDP_DEBUG_PRINT(format, ...) -#endif - -#define ND_OPTION_SOURCE_LL_ADDR 1 -#define ND_OPTION_TARGET_LL_ADDR 2 -#define ND_OPTION_PREFIX_INFO 3 -#define ND_OPTION_REDIRECT_HDR 4 -#define ND_OPTION_MTU 5 - -/* Default Router List */ -struct router { - uint8_t mac[6]; - ip6_addr_t ip; - uint32_t lifetime; - uint32_t reachable_time; - uint32_t retrans_timer; - struct router *next; -}; - -/* Neighbor cache */ -struct neighbor { - uint8_t mac[6]; - ip6_addr_t ip; - uint8_t is_router; - uint8_t status; - uint8_t times_asked; - /* ... */ - struct neighbor *next; - uint8_t eth_frame[1500]; //FIXME - uint32_t eth_len; - -#define NB_INCOMPLETE 1 -#define NB_REACHABLE 2 -#define NB_STALE 3 -#define NB_DELAY 4 -#define NB_PROBE 5 -}; - -/******************** FUNCTIONS *********************************************/ -void ndp_init(void); -int8_t neighbor_add (struct neighbor *); -void * neighbor_create (uint8_t *packet, struct packeth *headers); -struct neighbor * find_neighbor (ip6_addr_t *); - -int8_t router_add(struct router*); -void * router_create(uint8_t *mac, ip6_addr_t *ip); -struct router * find_router(ip6_addr_t *); - -#endif //_NDP_H_ diff --git a/qemu/roms/SLOF/clients/net-snk/app/netlib/tcp.c b/qemu/roms/SLOF/clients/net-snk/app/netlib/tcp.c deleted file mode 100644 index faa0b83ac..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/netlib/tcp.c +++ /dev/null @@ -1,46 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2008 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -/************************ DEFINITIONS & DECLARATIONS *********************/ - -#include <tcp.h> -#include <sys/socket.h> - -/****************************** LOCAL VARIABLES **************************/ - -/****************************** IMPLEMENTATION ***************************/ - -/** - * TCP: Handles TCP-packets according to Receive-handle diagram. - * - * @param tcp_packet TCP-packet to be handled - * @param packetsize Length of the packet - * @return ZERO - packet handled successfully; - * NON ZERO - packet was not handled (e.g. bad format) - */ -int8_t handle_tcp(uint8_t * tcp_packet, int32_t packetsize) -{ - return -1; -} - -/** - * NET: This function handles situation when "Destination unreachable" - * ICMP-error occurs during sending TCP-packet. - * - * @param err_code Error Code (e.g. "Host unreachable") - * @param packet original TCP-packet - * @param packetsize length of the packet - * @see handle_icmp - */ -void handle_tcp_dun(uint8_t * tcp_packet, uint32_t packetsize, uint8_t err_code) -{ -} diff --git a/qemu/roms/SLOF/clients/net-snk/app/netlib/tcp.h b/qemu/roms/SLOF/clients/net-snk/app/netlib/tcp.h deleted file mode 100644 index 375afd771..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/netlib/tcp.h +++ /dev/null @@ -1,27 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2008 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -#ifndef _TCP_H -#define _TCP_H - -#include <stdint.h> - -#define IPTYPE_TCP 6 - -/* Handles TCP-packets that are detected by any network layer. */ -extern int8_t handle_tcp(uint8_t * udp_packet, int32_t packetsize); - -/* Handles TCP related ICMP-Dest.Unreachable packets that are detected by - * the network layers. */ -extern void handle_tcp_dun(uint8_t * tcp_packet, uint32_t packetsize, uint8_t err_code); - -#endif diff --git a/qemu/roms/SLOF/clients/net-snk/app/netlib/tftp.c b/qemu/roms/SLOF/clients/net-snk/app/netlib/tftp.c deleted file mode 100644 index c1197cf17..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/netlib/tftp.c +++ /dev/null @@ -1,586 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2008 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -#include <tftp.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <sys/socket.h> - -#include <ethernet.h> -#include <ipv4.h> -#include <ipv6.h> -#include <udp.h> - -//#define __DEBUG__ - -#define MAX_BLOCKSIZE 1428 -#define BUFFER_LEN 256 - -#define ENOTFOUND 1 -#define EACCESS 2 -#define EBADOP 4 -#define EBADID 5 -#define ENOUSER 7 -//#define EUNDEF 0 -//#define ENOSPACE 3 -//#define EEXISTS 6 - -#define RRQ 1 -#define WRQ 2 -#define DATA 3 -#define ACK 4 -#define ERROR 5 -#define OACK 6 - -/* Local variables */ -static unsigned char packet[BUFFER_LEN]; -static unsigned char *buffer = NULL; -static unsigned short block = 0; -static unsigned short blocksize; -static char blocksize_str[6]; /* Blocksize string for read request */ -static int received_len = 0; -static unsigned int retries = 0; -static int huge_load; -static int len; -static int tftp_finished = 0; -static int lost_packets = 0; -static int tftp_errno = 0; -static int ip_version = 0; -static short port_number = -1; -static tftp_err_t *tftp_err; -static filename_ip_t *fn_ip; - -/** - * dump_package - Prints a package. - * - * @package: package which is to print - * @len: length of the package - */ -#ifdef __DEBUG__ - -static void dump_package(unsigned char *buffer, unsigned int len) -{ - int i; - - for (i = 1; i <= len; i++) { - printf("%02x%02x ", buffer[i - 1], buffer[i]); - i++; - if ((i % 16) == 0) - printf("\n"); - } - printf("\n"); -} -#endif - -/** - * send_rrq - Sends a read request package. - * - * @fd: Socket Descriptor - */ -static void send_rrq(int fd) -{ - int ip_len = 0; - int ip6_payload_len = 0; - unsigned short udp_len = 0; - unsigned char mode[] = "octet"; - char *ptr = NULL; - struct iphdr *ip = NULL; - struct ip6hdr *ip6 = NULL; - struct udphdr *udph = NULL; - struct tftphdr *tftp = NULL; - - memset(packet, 0, BUFFER_LEN); - - if (4 == ip_version) { - ip = (struct iphdr *) packet; - udph = (struct udphdr *) (ip + 1); - ip_len = sizeof(struct iphdr) + sizeof(struct udphdr) - + strlen((char *) fn_ip->filename) + strlen((char *) mode) + 4 - + strlen("blksize") + strlen(blocksize_str) + 2; - fill_iphdr ((uint8_t *) ip, ip_len, IPTYPE_UDP, 0, - fn_ip->server_ip); - } - else if (6 == ip_version) { - ip6 = (struct ip6hdr *) packet; - udph = (struct udphdr *) (ip6 + 1); - ip6_payload_len = sizeof(struct udphdr) - + strlen((char *) fn_ip->filename) + strlen((char *) mode) + 4 - + strlen("blksize") + strlen(blocksize_str) + 2; - ip_len = sizeof(struct ip6hdr) + ip6_payload_len; - fill_ip6hdr ((uint8_t *) ip6, ip6_payload_len, IPTYPE_UDP, get_ipv6_address(), - &(fn_ip->server_ip6)); - - } - udp_len = htons(sizeof(struct udphdr) - + strlen((char *) fn_ip->filename) + strlen((char *) mode) + 4 - + strlen("blksize") + strlen(blocksize_str) + 2); - fill_udphdr ((uint8_t *) udph, udp_len, htons(2001), htons(69)); - - tftp = (struct tftphdr *) (udph + 1); - tftp->th_opcode = htons(RRQ); - - ptr = (char *) &tftp->th_data; - memcpy(ptr, fn_ip->filename, strlen((char *) fn_ip->filename) + 1); - - ptr += strlen((char *) fn_ip->filename) + 1; - memcpy(ptr, mode, strlen((char *) mode) + 1); - - ptr += strlen((char *) mode) + 1; - memcpy(ptr, "blksize", strlen("blksize") + 1); - - ptr += strlen("blksize") + 1; - memcpy(ptr, blocksize_str, strlen(blocksize_str) + 1); - - send_ip (fd, packet, ip_len); - -#ifdef __DEBUG__ - printf("tftp RRQ with %d bytes transmitted.\n", ip_len); -#endif - return; -} - -/** - * send_ack - Sends a acknowlege package. - * - * @blckno: block number - * @dport: UDP destination port - */ -static void send_ack(int fd, int blckno, unsigned short dport) -{ - int ip_len = 0; - int ip6_payload_len = 0; - unsigned short udp_len = 0; - struct iphdr *ip = NULL; - struct ip6hdr *ip6 = NULL; - struct udphdr *udph = NULL; - struct tftphdr *tftp = NULL; - - memset(packet, 0, BUFFER_LEN); - - if (4 == ip_version) { - ip = (struct iphdr *) packet; - udph = (struct udphdr *) (ip + 1); - ip_len = sizeof(struct iphdr) + sizeof(struct udphdr) + 4; - fill_iphdr ((uint8_t *) ip, ip_len, IPTYPE_UDP, 0, - fn_ip->server_ip); - } - else if (6 == ip_version) { - ip6 = (struct ip6hdr *) packet; - udph = (struct udphdr *) (ip6 + 1); - ip6_payload_len = sizeof(struct udphdr) + 4; - ip_len = sizeof(struct ip6hdr) + ip6_payload_len; - fill_ip6hdr ((uint8_t *) ip6, ip6_payload_len, IPTYPE_UDP, get_ipv6_address(), - &(fn_ip->server_ip6)); - } - udp_len = htons(sizeof(struct udphdr) + 4); - fill_udphdr ((uint8_t *) udph, udp_len, htons(2001), htons(dport)); - - tftp = (struct tftphdr *) (udph + 1); - tftp->th_opcode = htons(ACK); - tftp->th_data = htons(blckno); - - send_ip(fd, packet, ip_len); - -#ifdef __DEBUG__ - printf("tftp ACK %d bytes transmitted.\n", ip_len); -#endif - - return; -} - -/** - * send_error - Sends an error package. - * - * @fd: Socket Descriptor - * @error_code: Used sub code for error packet - * @dport: UDP destination port - */ -static void send_error(int fd, int error_code, unsigned short dport) -{ - int ip_len = 0; - int ip6_payload_len = 0; - unsigned short udp_len = 0; - struct ip6hdr *ip6 = NULL; - struct iphdr *ip = NULL; - struct udphdr *udph = NULL; - struct tftphdr *tftp = NULL; - - memset(packet, 0, BUFFER_LEN); - - if (4 == ip_version) { - ip = (struct iphdr *) packet; - udph = (struct udphdr *) (ip + 1); - ip_len = sizeof(struct iphdr) + sizeof(struct udphdr) + 5; - fill_iphdr ((uint8_t *) ip, ip_len, IPTYPE_UDP, 0, - fn_ip->server_ip); - } - else if (6 == ip_version) { - ip6 = (struct ip6hdr *) packet; - udph = (struct udphdr *) (ip6 + 1); - ip6_payload_len = sizeof(struct udphdr) + 5; - ip_len = sizeof(struct ip6hdr) + ip6_payload_len; - fill_ip6hdr ((uint8_t *) ip6, ip6_payload_len, IPTYPE_UDP, get_ipv6_address(), - &(fn_ip->server_ip6)); - } - udp_len = htons(sizeof(struct udphdr) + 5); - fill_udphdr ((uint8_t *) udph, udp_len, htons(2001), htons(dport)); - - tftp = (struct tftphdr *) (udph + 1); - tftp->th_opcode = htons(ERROR); - tftp->th_data = htons(error_code); - ((char *) &tftp->th_data)[2] = 0; - - send_ip(fd, packet, ip_len); - -#ifdef __DEBUG__ - printf("tftp ERROR %d bytes transmitted.\n", ip_len); -#endif - - return; -} - -static void print_progress(int urgent, int received_bytes) -{ - static unsigned int i = 1; - static int first = -1; - static int last_bytes = 0; - char buffer[100]; - char *ptr; - - // 1MB steps or 0x400 times or urgent - if(((received_bytes - last_bytes) >> 20) > 0 - || (i & 0x3FF) == 0 || urgent) { - if(!first) { - sprintf(buffer, "%d KBytes", (last_bytes >> 10)); - for(ptr = buffer; *ptr != 0; ++ptr) - *ptr = '\b'; - printf(buffer); - } - printf("%d KBytes", (received_bytes >> 10)); - i = 1; - first = 0; - last_bytes = received_bytes; - } - ++i; -} - -/** - * get_blksize tries to extract the blksize from the OACK package - * the TFTP returned. From RFC 1782 - * The OACK packet has the following format: - * - * +-------+---~~---+---+---~~---+---+---~~---+---+---~~---+---+ - * | opc | opt1 | 0 | value1 | 0 | optN | 0 | valueN | 0 | - * +-------+---~~---+---+---~~---+---+---~~---+---+---~~---+---+ - * - * @param buffer the network packet - * @param len the length of the network packet - * @return the blocksize the server supports or 0 for error - */ -static int get_blksize(unsigned char *buffer, unsigned int len) -{ - unsigned char *orig = buffer; - /* skip all headers until tftp has been reached */ - buffer += sizeof(struct udphdr); - /* skip opc */ - buffer += 2; - while (buffer < orig + len) { - if (!memcmp(buffer, "blksize", strlen("blksize") + 1)) - return (unsigned short) strtoul((char *) (buffer + - strlen("blksize") + 1), - (char **) NULL, 10); - else { - /* skip the option name */ - buffer = (unsigned char *) strchr((char *) buffer, 0); - if (!buffer) - return 0; - buffer++; - /* skip the option value */ - buffer = (unsigned char *) strchr((char *) buffer, 0); - if (!buffer) - return 0; - buffer++; - } - } - return 0; -} - -/** - * Handle incoming tftp packets after read request was sent - * - * this function also prints out some status characters - * \|-/ for each packet received - * A for an arp packet - * I for an ICMP packet - * #+* for different unexpected TFTP packets (not very good) - * - * @param fd socket descriptor - * @param packet points to the UDP header of the packet - * @param len the length of the network packet - * @return ZERO if packet was handled successfully - * ERRORCODE if error occurred - */ -int32_t handle_tftp(int fd, uint8_t *pkt, int32_t packetsize) -{ - struct udphdr *udph; - struct tftphdr *tftp; - - /* buffer is only set if we are handling TFTP */ - if (buffer == NULL ) - return 0; - -#ifndef __DEBUG__ - print_progress(0, received_len); -#endif - udph = (struct udphdr *) pkt; - tftp = (struct tftphdr *) ((void *) udph + sizeof(struct udphdr)); - set_timer(TICKS_SEC); - -#ifdef __DEBUG__ - dump_package(pkt, packetsize); -#endif - - port_number = udph->uh_sport; - if (tftp->th_opcode == htons(OACK)) { - /* an OACK means that the server answers our blocksize request */ - blocksize = get_blksize(pkt, packetsize); - if (!blocksize || blocksize > MAX_BLOCKSIZE) { - send_error(fd, 8, port_number); - tftp_errno = -8; - goto error; - } - send_ack(fd, 0, port_number); - } else if (tftp->th_opcode == htons(ACK)) { - /* an ACK means that the server did not answers - * our blocksize request, therefore we will set the blocksize - * to the default value of 512 */ - blocksize = 512; - send_ack(fd, 0, port_number); - } else if ((unsigned char) tftp->th_opcode == ERROR) { -#ifdef __DEBUG__ - printf("tftp->th_opcode : %x\n", tftp->th_opcode); - printf("tftp->th_data : %x\n", tftp->th_data); -#endif - switch ( (uint8_t) tftp->th_data) { - case ENOTFOUND: - tftp_errno = -3; // ERROR: file not found - break; - case EACCESS: - tftp_errno = -4; // ERROR: access violation - break; - case EBADOP: - tftp_errno = -5; // ERROR: illegal TFTP operation - break; - case EBADID: - tftp_errno = -6; // ERROR: unknown transfer ID - break; - case ENOUSER: - tftp_errno = -7; // ERROR: no such user - break; - default: - tftp_errno = -1; // ERROR: unknown error - } - goto error; - } else if (tftp->th_opcode == DATA) { - /* DATA PACKAGE */ - if (block + 1 == tftp->th_data) { - ++block; - } - else if( block == 0xffff && huge_load != 0 - && (tftp->th_data == 0 || tftp->th_data == 1) ) { - block = tftp->th_data; - } - else if (tftp->th_data == block) { -#ifdef __DEBUG__ - printf - ("\nTFTP: Received block %x, expected block was %x\n", - tftp->th_data, block + 1); - printf("\b+ "); -#endif - send_ack(fd, tftp->th_data, port_number); - lost_packets++; - tftp_err->bad_tftp_packets++; - return 0; - } else if (tftp->th_data < block) { -#ifdef __DEBUG__ - printf - ("\nTFTP: Received block %x, expected block was %x\n", - tftp->th_data, block + 1); - printf("\b* "); -#endif - /* This means that an old data packet appears (again); - * this happens sometimes if we don't answer fast enough - * and a timeout is generated on the server side; - * as we already have this packet we just ignore it */ - tftp_err->bad_tftp_packets++; - return 0; - } else { - tftp_err->blocks_missed = block + 1; - tftp_err->blocks_received = tftp->th_data; - tftp_errno = -42; - goto error; - } - tftp_err->bad_tftp_packets = 0; - /* check if our buffer is large enough */ - if (received_len + udph->uh_ulen - 12 > len) { - tftp_errno = -2; - goto error; - } - memcpy(buffer + received_len, &tftp->th_data + 1, - udph->uh_ulen - 12); - send_ack(fd, tftp->th_data, port_number); - received_len += udph->uh_ulen - 12; - /* Last packet reached if the payload of the UDP packet - * is smaller than blocksize + 12 - * 12 = UDP header (8) + 4 bytes TFTP payload */ - if (udph->uh_ulen < blocksize + 12) { - tftp_finished = 1; - return 0; - } - /* 0xffff is the highest block number possible - * see the TFTP RFCs */ - - if (block >= 0xffff && huge_load == 0) { - tftp_errno = -9; - goto error; - } - } else { -#ifdef __DEBUG__ - printf("Unknown packet %x\n", tftp->th_opcode); - printf("\b# "); -#endif - tftp_err->bad_tftp_packets++; - return 0; - } - - return 0; - -error: -#ifdef __DEBUG__ - printf("\nTFTP errno: %d\n", tftp_errno); -#endif - tftp_finished = 1; - return tftp_errno; -} - -/** - * TFTP: This function handles situation when "Destination unreachable" - * ICMP-error occurs during sending TFTP-packet. - * - * @param err_code Error Code (e.g. "Host unreachable") - */ -void handle_tftp_dun(uint8_t err_code) -{ - tftp_errno = - err_code - 10; - tftp_finished = 1; -} - -/** - * TFTP: Interface function to load files via TFTP. - * - * @param _fn_ip contains the following configuration information: - * client IP, TFTP-server IP, filename to be loaded - * @param _buffer destination buffer for the file - * @param _len size of destination buffer - * @param _retries max number of retries - * @param _tftp_err contains info about TFTP-errors (e.g. lost packets) - * @param _mode NON ZERO - multicast, ZERO - unicast - * @param _blocksize blocksize for DATA-packets - * @return ZERO - error condition occurs - * NON ZERO - size of received file - */ -int tftp(filename_ip_t * _fn_ip, unsigned char *_buffer, int _len, - unsigned int _retries, tftp_err_t * _tftp_err, - int32_t _mode, int32_t _blocksize, int _ip_version) -{ - retries = _retries; - fn_ip = _fn_ip; - len = _len; - huge_load = _mode; - ip_version = _ip_version; - tftp_errno = 0; - tftp_err = _tftp_err; - tftp_err->bad_tftp_packets = 0; - tftp_err->no_packets = 0; - - /* Default blocksize must be 512 for TFTP servers - * which do not support the RRQ blocksize option */ - blocksize = 512; - - /* Preferred blocksize - used as option for the read request */ - if (_blocksize < 8) - _blocksize = 8; - else if (_blocksize > MAX_BLOCKSIZE) - _blocksize = MAX_BLOCKSIZE; - sprintf(blocksize_str, "%d", _blocksize); - - printf(" Receiving data: "); - print_progress(-1, 0); - - // Setting buffer to a non-zero address enabled handling of received TFTP packets. - buffer = _buffer; - - set_timer(TICKS_SEC); - send_rrq(fn_ip->fd); - - while (! tftp_finished) { - /* if timeout (no packet received) */ - if(get_timer() <= 0) { - /* the server doesn't seem to retry let's help out a bit */ - if (tftp_err->no_packets > 4 && port_number != -1 - && block > 1) { - send_ack(fn_ip->fd, block, port_number); - } - else if (port_number == -1 && block == 0 - && (tftp_err->no_packets&3) == 3) { - printf("\nRepeating TFTP read request...\n"); - send_rrq(fn_ip->fd); - } - tftp_err->no_packets++; - set_timer(TICKS_SEC); - } - - /* handle received packets */ - receive_ether(fn_ip->fd); - - /* bad_tftp_packets are counted whenever we receive a TFTP packet - * which was not expected; if this gets larger than 'retries' - * we just exit */ - if (tftp_err->bad_tftp_packets > retries) { - tftp_errno = -40; - break; - } - - /* no_packets counts the times we have returned from receive_ether() - * without any packet received; if this gets larger than 'retries' - * we also just exit */ - if (tftp_err->no_packets > retries) { - tftp_errno = -41; - break; - } - } - - // Setting buffer to NULL disables handling of received TFTP packets. - buffer = NULL; - - if (tftp_errno) - return tftp_errno; - - print_progress(-1, received_len); - printf("\n"); - if (lost_packets) - printf("Lost ACK packets: %d\n", lost_packets); - - return received_len; -} diff --git a/qemu/roms/SLOF/clients/net-snk/app/netlib/tftp.h b/qemu/roms/SLOF/clients/net-snk/app/netlib/tftp.h deleted file mode 100644 index 1cf1266fb..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/netlib/tftp.h +++ /dev/null @@ -1,51 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2008 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - - -#ifndef _TFTP_H_ -#define _TFTP_H_ - -#include <stdint.h> -#include <netlib/ipv6.h> - -struct tftphdr { - int16_t th_opcode; - uint16_t th_data; -}; - -typedef struct { - uint32_t own_ip; - ip6_addr_t own_ip6; - uint32_t server_ip; - ip6_addr_t server_ip6; - ip6_addr_t dns_ip6; - int8_t filename[256]; - int fd; -} __attribute__ ((packed)) filename_ip_t ; - -typedef struct { - uint32_t bad_tftp_packets; - uint32_t no_packets; - uint32_t blocks_missed; - uint32_t blocks_received; -} tftp_err_t; - -int tftp(filename_ip_t *, unsigned char *, int, unsigned int, - tftp_err_t *, int32_t mode, int32_t blocksize, int ip_version); -int tftp_netsave(filename_ip_t *, uint8_t * buffer, int len, - int use_ci, unsigned int retries, tftp_err_t * tftp_err); - -int32_t handle_tftp(int fd, uint8_t *, int32_t); -void handle_tftp_dun(uint8_t err_code); -int parse_tftp_args(char buffer[], char *server_ip, char filename[], int fd, int len); - -#endif diff --git a/qemu/roms/SLOF/clients/net-snk/app/netlib/udp.c b/qemu/roms/SLOF/clients/net-snk/app/netlib/udp.c deleted file mode 100644 index 5d16e52c6..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/netlib/udp.c +++ /dev/null @@ -1,153 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2008 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -/************************ DEFINITIONS & DECLARATIONS *********************/ - -#include <udp.h> -#include <sys/socket.h> -#include <dhcp.h> -#include <dhcpv6.h> -#include <dns.h> -#ifdef USE_MTFTP -#include <mtftp.h> -#else -#include <tftp.h> -#endif - - - -/****************************** LOCAL VARIABLES **************************/ - - -#ifdef USE_MTFTP - -uint16_t net_tftp_uport; -uint16_t net_mtftp_uport; - -void net_set_tftp_port(uint16_t tftp_port) -{ - net_tftp_uport = tftp_port; -} - -void net_set_mtftp_port(uint16_t tftp_port) -{ - net_mtftp_uport = tftp_port; -} - -#endif - -/****************************** IMPLEMENTATION ***************************/ - - -/** - * NET: Handles UDP-packets according to Receive-handle diagram. - * - * @param udp_packet UDP-packet to be handled - * @param packetsize Length of the packet - * @return ZERO - packet handled successfully; - * NON ZERO - packet was not handled (e.g. bad format) - * @see receive_ether - * @see udphdr - */ -int8_t handle_udp(int fd, uint8_t * udp_packet, uint32_t packetsize) -{ - struct udphdr * udph = (struct udphdr *) udp_packet; - - if (packetsize < sizeof(struct udphdr)) - return -1; // packet is too small - - switch (htons(udph -> uh_dport)) { - case UDPPORT_BOOTPC: - if (udph -> uh_sport == htons(UDPPORT_BOOTPS)) - return handle_dhcp(fd, udp_packet + sizeof(struct udphdr), - packetsize - sizeof(struct udphdr)); - else - return -1; - case UDPPORT_DNSC: - if (udph -> uh_sport == htons(UDPPORT_DNSS)) - return handle_dns(udp_packet + sizeof(struct udphdr), - packetsize - sizeof(struct udphdr)); - else - return -1; - case UDPPORT_DHCPV6C: - return handle_dhcpv6(udp_packet+sizeof(struct udphdr), - packetsize - sizeof(struct udphdr)); - case UDPPORT_TFTPC: -#ifdef USE_MTFTP - return handle_tftp(fd, udp_packet + sizeof(struct udphdr), - packetsize - sizeof(struct udphdr)); -#else - return handle_tftp(fd, udp_packet, packetsize); -#endif - default: -#ifdef USE_MTFTP - if (htons(udph -> uh_dport) == net_tftp_uport) - return handle_tftp(fd, udp_packet + sizeof(struct udphdr), - packetsize - sizeof(struct udphdr)); - else if (htons(udph -> uh_dport) == net_mtftp_uport) - return handle_tftp(fd, udp_packet + sizeof(struct udphdr), - packetsize - sizeof(struct udphdr)); -#endif - return -1; - } -} - -/** - * NET: This function handles situation when "Destination unreachable" - * ICMP-error occurs during sending UDP-packet. - * - * @param err_code Error Code (e.g. "Host unreachable") - * @param packet original UDP-packet - * @param packetsize length of the packet - * @see handle_icmp - */ -void handle_udp_dun(uint8_t * udp_packet, uint32_t packetsize, uint8_t err_code) -{ - struct udphdr * udph = (struct udphdr *) udp_packet; - - if (packetsize < sizeof(struct udphdr)) - return; // packet is too small - - switch (htons(udph -> uh_sport)) { - case UDPPORT_TFTPC: - handle_tftp_dun(err_code); - break; - } -} - -/** - * NET: Creates UDP-packet. Places UDP-header in a packet and fills it - * with corresponding information. - * <p> - * Use this function with similar functions for other network layers - * (fill_ethhdr, fill_iphdr, fill_dnshdr, fill_btphdr). - * - * @param packet Points to the place where UDP-header must be placed. - * @param packetsize Size of the packet in bytes incl. this hdr and data. - * @param src_port UDP source port - * @param dest_port UDP destination port - * @see udphdr - * @see fill_ethhdr - * @see fill_iphdr - * @see fill_dnshdr - * @see fill_btphdr - */ -void fill_udphdr(uint8_t * packet, uint16_t packetsize, - uint16_t src_port, uint16_t dest_port) -{ - struct udphdr * udph = (struct udphdr *) packet; - - udph -> uh_sport = htons(src_port); - udph -> uh_dport = htons(dest_port); - udph -> uh_ulen = htons(packetsize); - udph -> uh_sum = htons(0); -} diff --git a/qemu/roms/SLOF/clients/net-snk/app/netlib/udp.h b/qemu/roms/SLOF/clients/net-snk/app/netlib/udp.h deleted file mode 100644 index f154542dd..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/netlib/udp.h +++ /dev/null @@ -1,58 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2008 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -#ifndef _UDP_H -#define _UDP_H - -#include <stdint.h> - -#define IPTYPE_UDP 17 - -#define UDPPORT_BOOTPS 67 /**< UDP port of BootP/DHCP-server */ -#define UDPPORT_BOOTPC 68 /**< UDP port of BootP/DHCP-client */ -#define UDPPORT_DNSS 53 /**< UDP port of DNS-server */ -#define UDPPORT_DNSC 32769 /**< UDP port of DNS-client */ -#define UDPPORT_TFTPC 2001 /**< UDP port of TFTP-client */ -#define UDPPORT_DHCPV6C 546 /**< UDP port of DHCPv6-client */ - -/** \struct udphdr - * A header for UDP-packets. - * For more information see RFC 768. - */ -struct udphdr { - uint16_t uh_sport; /**< Source port */ - uint16_t uh_dport; /**< Destinantion port */ - uint16_t uh_ulen; /**< Length in octets, incl. this header and data */ - uint16_t uh_sum; /**< Checksum */ -}; -typedef struct udphdr udp_hdr_t; - -typedef int32_t *(*handle_upper_udp_t)(uint8_t *, int32_t); -typedef void *(*handle_upper_udp_dun_t)(uint8_t); - -/* Handles UDP-packets that are detected by any network layer. */ -extern int8_t handle_udp(int fd, uint8_t * udp_packet, uint32_t packetsize); - -/* Handles UDP related ICMP-Dest.Unreachable packets that are detected by - * the network layers. */ -extern void handle_udp_dun(uint8_t * udp_packet, uint32_t packetsize, uint8_t err_code); - -/* fills udp header */ -extern void fill_udphdr(uint8_t *packet, uint16_t packetsize, - uint16_t src_port, uint16_t dest_port); - -#ifdef USE_MTFTP -extern void net_set_tftp_port(uint16_t tftp_port); -extern void net_set_mtftp_port(uint16_t tftp_port); -#endif - -#endif |