--- upstream/dynamips-0.2.6-RC2/utils.c 2007/10/06 16:05:34 3 +++ upstream/dynamips-0.2.8-RC1/utils.c 2007/10/06 16:33:40 11 @@ -1,5 +1,5 @@ /* - * Cisco C7200 (Predator) simulation platform. + * Cisco router simulation platform. * Copyright (c) 2005,2006 Christophe Fillot. All rights reserved. * * Utility functions. @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -207,6 +208,7 @@ } fprintf(f_output,"\n"); + fflush(f_output); } /* Logging function */ @@ -255,9 +257,9 @@ } /* Read a file and returns it in a buffer */ -ssize_t m_read_file(char *filename,char **buffer) +ssize_t m_read_file(char *filename,u_char **buffer) { - char tmp[256],*ptr,*nptr; + u_char tmp[256],*ptr,*nptr; size_t len,tot_len; FILE *fd; @@ -295,7 +297,7 @@ { void *p; -#ifdef __linux__ +#if defined(__linux__) || HAS_POSIX_MEMALIGN if (posix_memalign((void *)&p,boundary,size)) #else #if defined(__CYGWIN__) || defined(SUNOS) @@ -338,3 +340,129 @@ return(fcntl(fd,F_SETFL, flags | O_NONBLOCK)); } + +/* Map a memory zone from a file */ +u_char *memzone_map_file(int fd,size_t len) +{ + return(mmap(NULL,len,PROT_READ|PROT_WRITE,MAP_SHARED,fd,(off_t)0)); +} + +/* Map a memory zone from a file, with copy-on-write (COW) */ +u_char *memzone_map_cow_file(int fd,size_t len) +{ + return(mmap(NULL,len,PROT_READ|PROT_WRITE,MAP_PRIVATE,fd,(off_t)0)); +} + +/* Create a file to serve as a memory zone */ +int memzone_create_file(char *filename,size_t len,u_char **ptr) +{ + int fd; + + if ((fd = open(filename,O_CREAT|O_RDWR,S_IRWXU)) == -1) { + perror("memzone_create_file: open"); + return(-1); + } + + if (ftruncate(fd,len) == -1) { + perror("memzone_create_file: ftruncate"); + close(fd); + return(-1); + } + + *ptr = memzone_map_file(fd,len); + + if (!*ptr) { + close(fd); + fd = -1; + } + + return(fd); +} + +/* Open a file to serve as a COW memory zone */ +int memzone_open_cow_file(char *filename,size_t len,u_char **ptr) +{ + int fd; + + if ((fd = open(filename,O_RDWR,S_IRWXU)) == -1) { + perror("memzone_open_file: open"); + return(-1); + } + + *ptr = memzone_map_cow_file(fd,len); + + if (!*ptr) { + close(fd); + fd = -1; + } + + return(fd); +} + +/* Open a file and map it in memory */ +int memzone_open_file(char *filename,u_char **ptr,off_t *fsize) +{ + struct stat fprop; + int fd; + + if ((fd = open(filename,O_RDWR,S_IRWXU)) == -1) + return(-1); + + if (fstat(fd,&fprop) == -1) + goto err_fstat; + + *fsize = fprop.st_size; + if (!(*ptr = memzone_map_file(fd,*fsize))) + goto err_mmap; + + return(fd); + + err_mmap: + err_fstat: + close(fd); + return(-1); +} + +/* Compute NVRAM checksum */ +m_uint16_t nvram_cksum(m_uint16_t *ptr,size_t count) +{ + m_uint32_t sum = 0; + + while(count > 1) { + sum = sum + ntohs(*ptr); + ptr++; + count -= sizeof(m_uint16_t); + } + + if (count > 0) + sum = sum + ((ntohs(*ptr) & 0xFF) << 8); + + while(sum>>16) + sum = (sum & 0xffff) + (sum >> 16); + + return(~sum); +} + +/* Byte-swap a memory block */ +void mem_bswap32(void *ptr,size_t len) +{ + m_uint32_t *p = ptr; + size_t count = len >> 2; + int i; + + for(i=0;i