ÜberWall

UWfirmforce

/* $Id: uboot.c,v 1.1 2011/01/13 21:39:10 khorben Exp $ */
/* Copyright (c) 2011 khorben of Uberwall */
/* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <stdint.h>
#include <time.h>
#include "plugin.h"
/* u-boot */
/* public */
/* types */
#define IH_NMLEN 32
#pragma pack(1)
struct uboot
{
uint32_t ih_magic; /* Image Header Magic Number */
uint32_t ih_hcrc; /* Image Header CRC Checksum */
uint32_t ih_time; /* Image Creation Timestamp */
uint32_t ih_size; /* Image Data Size */
uint32_t ih_load; /* Data Load Address */
uint32_t ih_ep; /* Entry Point Address */
uint32_t ih_dcrc; /* Image Data CRC Checksum */
uint8_t ih_os; /* Operating System */
uint8_t ih_arch; /* CPU architecture */
uint8_t ih_type; /* Image Type */
uint8_t ih_comp; /* Compression Type */
uint8_t ih_name[IH_NMLEN]; /* Image Name */
};
#pragma pack()
/* constants */
#define IH_OS_INVALID 0 /* Invalid OS */
#define IH_OS_OPENBSD 1 /* OpenBSD */
#define IH_OS_NETBSD 2 /* NetBSD */
#define IH_OS_FREEBSD 3 /* FreeBSD */
#define IH_OS_4_4BSD 4 /* 4.4BSD */
#define IH_OS_LINUX 5 /* Linux */
#define IH_OS_SVR4 6 /* SVR4 */
#define IH_OS_ESIX 7 /* Esix */
#define IH_OS_SOLARIS 8 /* Solaris */
#define IH_OS_IRIX 9 /* Irix */
#define IH_OS_SCO 10 /* SCO */
#define IH_OS_DELL 11 /* Dell */
#define IH_OS_NCR 12 /* NCR */
#define IH_OS_LYNXOS 13 /* LynxOS */
#define IH_OS_VXWORKS 14 /* VxWorks */
#define IH_OS_PSOS 15 /* pSOS */
#define IH_OS_QNX 16 /* QNX */
#define IH_OS_U_BOOT 17 /* Firmware */
#define IH_OS_RTEMS 18 /* RTEMS */
#define IH_OS_ARTOS 19 /* ARTOS */
#define IH_OS_UNITY 20 /* Unity OS */
#define IH_CPU_INVALID 0 /* Invalid CPU */
#define IH_CPU_ALPHA 1 /* Alpha */
#define IH_CPU_ARM 2 /* ARM */
#define IH_CPU_I386 3 /* Intel x86 */
#define IH_CPU_IA64 4 /* IA64 */
#define IH_CPU_MIPS 5 /* MIPS */
#define IH_CPU_MIPS64 6 /* MIPS 64 Bit */
#define IH_CPU_PPC 7 /* PowerPC */
#define IH_CPU_S390 8 /* IBM S390 */
#define IH_CPU_SH 9 /* SuperH */
#define IH_CPU_SPARC 10 /* Sparc */
#define IH_CPU_SPARC64 11 /* Sparc 64 Bit */
#define IH_CPU_M68K 12 /* M68K */
#define IH_CPU_NIOS 13 /* Nios-32 */
#define IH_CPU_MICROBLAZE 14 /* MicroBlaze */
#define IH_CPU_NIOS2 15 /* Nios-II */
#define IH_CPU_BLACKFIN 16 /* Blackfin */
#define IH_CPU_AVR32 17 /* AVR32 */
#define IH_TYPE_INVALID 0 /* Invalid Image */
#define IH_TYPE_STANDALONE 1
#define IH_TYPE_KERNEL 2
#define IH_TYPE_RAMDISK 3
#define IH_TYPE_MULTI 4
#define IH_TYPE_FIRMWARE 5
#define IH_TYPE_SCRIPT 6
#define IH_TYPE_FILESYSTEM 7
#define IH_TYPE_FLATDT 8
#define IH_COMP_NONE 0 /* No compression used */
#define IH_COMP_GZIP 1 /* gzip compression used */
#define IH_COMP_BZIP2 2 /* bzip2 compression used */
#define UBOOT_MAGIC 0x27051956
/* variables */
/* magic */
static unsigned char sig1[] = "\x27\x05\x19\x56";
static PluginMagic uboot_magic[] =
{
{ sizeof(struct uboot), 0, sig1, sizeof(sig1)-1 },
{ 0, 0, NULL, 0 }
};
/* functions */
static int uboot_callback(PluginHelper * ph, int signature, FILE * fp);
/* plugin */
Plugin plugin =
{
PT_EXECUTABLE,
"U-BOOT",
uboot_magic,
uboot_callback
};
/* private */
/* functions */
/* uboot_callback */
static int _callback_time(PluginHelper * ph, struct uboot * buf);
static int _callback_size(PluginHelper * ph, struct uboot * buf);
static int _callback_load(PluginHelper * ph, struct uboot * buf);
static int _callback_ep(PluginHelper * ph, struct uboot * buf);
static int _callback_os(PluginHelper * ph, struct uboot * buf);
static int _callback_arch(PluginHelper * ph, struct uboot * buf);
static int _callback_type(PluginHelper * ph, struct uboot * buf);
static int _callback_comp(PluginHelper * ph, struct uboot * buf);
static int _callback_name(PluginHelper * ph, struct uboot * buf);
static int uboot_callback(PluginHelper * ph, int signature, FILE * fp)
{
int score = 0;
struct uboot buf;
if(fread(&buf, sizeof(buf), 1, fp) != 1)
return 0;
score += _callback_time(ph, &buf);
_callback_size(ph, &buf);
_callback_load(ph, &buf);
_callback_ep(ph, &buf);
score += _callback_os(ph, &buf);
score += _callback_arch(ph, &buf);
score += _callback_type(ph, &buf);
score += _callback_comp(ph, &buf);
_callback_name(ph, &buf);
ph->printf(ph, "\n");
return score / 5;
}
static int _callback_time(PluginHelper * ph, struct uboot * buf)
{
time_t t = buf->ih_time;
struct tm tm;
char tmp[20] = "";
/* FIXME what about the endian? */
if(gmtime_r(&t, &tm) == NULL || strftime(tmp, sizeof(tmp),
"%d/%m/%Y %H:%M:%S", &tm) == 0)
{
ph->printf(ph, "%s", "unknown date");
return 0;
}
ph->printf(ph, "%s", tmp);
/* between Wed May 1 00:00:00 CEST 1996 and now */
return t > 830901600 && t < time(NULL) ? 100 : 0;
}
static int _callback_size(PluginHelper * ph, struct uboot * buf)
{
ph->printf(ph, ", size 0x%08x", buf->ih_size);
return buf->ih_size > 0 && buf->ih_size < 2147483648 ? 100 : 0;
}
static int _callback_load(PluginHelper * ph, struct uboot * buf)
{
ph->printf(ph, ", load at 0x%08x", buf->ih_load);
return 100;
}
static int _callback_ep(PluginHelper * ph, struct uboot * buf)
{
ph->printf(ph, ", entrypoint at 0x%08x", buf->ih_ep);
return 100;
}
static int _callback_os(PluginHelper * ph, struct uboot * buf)
{
struct
{
int os;
char * string;
int score;
}
name[] =
{
{ IH_OS_INVALID, "invalid", 0 },
{ IH_OS_OPENBSD, "OpenBSD", 100 },
{ IH_OS_NETBSD, "NetBSD", 100 },
{ IH_OS_FREEBSD, "FreeBSD", 100 },
{ IH_OS_4_4BSD, "4.4BSD", 100 },
{ IH_OS_LINUX, "Linux", 100 },
{ -1, "unknown", 20 }
};
unsigned int i;
for(i = 0; name[i].os != -1 && name[i].os != buf->ih_os; i++);
ph->printf(ph, ", OS %s", name[i].string);
return name[i].score;
}
static int _callback_arch(PluginHelper * ph, struct uboot * buf)
{
struct
{
int arch;
char * string;
int score;
}
name[] =
{
{ IH_CPU_INVALID, "invalid", 0 },
{ IH_CPU_ALPHA, "Alpha", 100 },
{ IH_CPU_ARM, "ARM", 100 },
{ IH_CPU_I386, "Intel x86", 100 },
{ IH_CPU_IA64, "IA64", 100 },
{ IH_CPU_MIPS, "MIPS", 100 },
{ IH_CPU_MIPS64, "MIPS 64 bits", 100 },
{ IH_CPU_PPC, "PowerPC", 100 },
{ IH_CPU_S390, "IBM S390", 100 },
{ IH_CPU_SH, "SuperH", 100 },
{ IH_CPU_SPARC, "Sparc", 100 },
{ IH_CPU_SPARC64, "Sparc 64 bits",100 },
{ IH_CPU_M68K, "M68K", 100 },
{ IH_CPU_NIOS, "Nios-32", 100 },
{ IH_CPU_MICROBLAZE, "MicroBlaze", 100 },
{ IH_CPU_NIOS2, "Nios-II", 100 },
{ IH_CPU_BLACKFIN, "Blackfin", 100 },
{ IH_CPU_AVR32, "AVR32", 100 },
{ -1, "unknown", 20 }
};
unsigned int i;
for(i = 0; name[i].arch != -1 && name[i].arch != buf->ih_arch; i++);
ph->printf(ph, ", CPU %s", name[i].string);
return name[i].score;
}
static int _callback_type(PluginHelper * ph, struct uboot * buf)
{
struct
{
int type;
char * string;
int score;
}
name[] =
{
{ IH_TYPE_INVALID, "invalid", 0 },
{ IH_TYPE_STANDALONE, "Standalone", 100 },
{ IH_TYPE_KERNEL, "OS Kernel", 100 },
{ IH_TYPE_RAMDISK, "RAMDisk" , 100 },
{ IH_TYPE_MULTI, "Multi-File", 100 },
{ IH_TYPE_FIRMWARE, "Firmware", 100 },
{ IH_TYPE_SCRIPT, "Script file", 100 },
{ IH_TYPE_FILESYSTEM, "Filesystem", 100 },
{ IH_TYPE_FLATDT, "Binary File Device Tree", 100 },
{ -1, "unknown", 20 }
};
unsigned int i;
for(i = 0; name[i].type != -1 && name[i].type != buf->ih_type; i++);
ph->printf(ph, ", type %s", name[i].string);
return name[i].score;
}
static int _callback_comp(PluginHelper * ph, struct uboot * buf)
{
struct
{
int comp;
char * string;
int score;
}
name[] =
{
{ IH_COMP_NONE, "none", 100 },
{ IH_COMP_GZIP, "gzip", 100 },
{ IH_COMP_BZIP2, "bzip2", 100 },
{ -1, "unknown", 20 }
};
unsigned int i;
for(i = 0; name[i].comp != -1 && name[i].comp != buf->ih_comp; i++);
ph->printf(ph, ", comp %s", name[i].string);
return name[i].score;
}
static int _callback_name(PluginHelper * ph, struct uboot * buf)
{
ph->printf(ph, ", name \"%32s\"", buf->ih_name);
return 0;
}