X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=dummynet2%2Fbsd_compat.c;fp=dummynet2%2Fbsd_compat.c;h=21d19b6c5e075792acd76bb3b450d96664322d17;hb=40445faa1db58b90083115bc315d095e7eb2fe51;hp=70268bb8ab0e6fdefe8e238044aaebb93c51fc21;hpb=fccf30d4bf6b00b317756a9ff9d2135b361d2599;p=ipfw.git diff --git a/dummynet2/bsd_compat.c b/dummynet2/bsd_compat.c index 70268bb..21d19b6 100644 --- a/dummynet2/bsd_compat.c +++ b/dummynet2/bsd_compat.c @@ -24,7 +24,7 @@ */ /* - * $Id: bsd_compat.c 4665 2010-01-04 12:35:39Z luigi $ + * $Id: bsd_compat.c 5813 2010-03-22 18:05:13Z svn_magno $ * * kernel variables and functions that are not available in linux. */ @@ -32,6 +32,9 @@ #include #include /* do_div on 2.4 */ #include /* get_random_bytes on 2.4 */ +#include +#include +#include /* * gettimeofday would be in sys/time.h but it is not @@ -43,7 +46,6 @@ int ticks; /* kernel ticks counter */ int hz = 1000; /* default clock time */ long tick = 1000; /* XXX is this 100000/hz ? */ int bootverbose = 0; -time_t time_uptime = 0; struct timeval boottime; int ip_defttl; @@ -157,6 +159,7 @@ ip_reass(struct mbuf *clone) /* credentials check */ #include +#ifdef __linux__ int cred_check(void *_insn, int proto, struct ifnet *oif, struct in_addr dst_ip, u_int16_t dst_port, struct in_addr src_ip, @@ -186,6 +189,7 @@ cred_check(void *_insn, int proto, struct ifnet *oif, match = (u->gid == (uid_t)insn->d[0]); return match; } +#endif /* __linux__ */ int jailed(struct ucred *cred) @@ -212,6 +216,7 @@ sooptcopyout(struct sockopt *sopt, const void *buf, size_t len) if (len < valsize) sopt->sopt_valsize = valsize = len; + //printf("copyout buf = %p, sopt = %p, soptval = %p, len = %d \n", buf, sopt, sopt->sopt_val, len); bcopy(buf, sopt->sopt_val, valsize); return 0; } @@ -228,6 +233,7 @@ sooptcopyin(struct sockopt *sopt, void *buf, size_t len, size_t minlen) return EINVAL; if (valsize > len) sopt->sopt_valsize = valsize = len; + //printf("copyin buf = %p, sopt = %p, soptval = %p, len = %d \n", buf, sopt, sopt->sopt_val, len); bcopy(sopt->sopt_val, buf, valsize); return 0; } @@ -235,10 +241,7 @@ sooptcopyin(struct sockopt *sopt, void *buf, size_t len, size_t minlen) void getmicrouptime(struct timeval *tv) { -#ifdef _WIN32 -#else do_gettimeofday(tv); -#endif } @@ -271,7 +274,13 @@ int random(void) { #ifdef _WIN32 - return 0x123456; + static unsigned long seed; + if (seed == 0) { + LARGE_INTEGER tm; + KeQuerySystemTime(&tm); + seed = tm.LowPart; + } + return RtlRandomEx(&seed) & 0x7fffffff; #else int r; get_random_bytes(&r, sizeof(r)); @@ -302,6 +311,34 @@ div64(int64_t a, int64_t b) #endif } +#ifdef __MIPSEL__ +size_t +strlcpy(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0 && --n != 0) { + do { + if ((*d++ = *s++) == 0) + break; + } while (--n != 0); + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } + + return(s - src - 1); /* count does not include NUL */ +} +#endif // __MIPSEL__ + /* * compact version of fnmatch. */ @@ -328,43 +365,182 @@ fnmatch(const char *pattern, const char *string, int flags) return 1; /* no match */ } -#ifdef _WIN32 -/* - * as good as anywhere, place here the missing calls +/* support for sysctl emulation. + * XXX this is actually MI code that should be enabled also on openwrt */ +#ifdef EMULATE_SYSCTL +static struct sysctltable GST; -void * -my_alloc(int size) +int +kesysctl_emu_get(struct sockopt* sopt) { - void *_ret = ExAllocatePoolWithTag(0, size, 'wfpi'); - if (_ret) - memset(_ret, 0, size); - return _ret; + struct dn_id* oid = sopt->sopt_val; + struct sysctlhead* entry; + int sizeneeded = sizeof(struct dn_id) + GST.totalsize + + sizeof(struct sysctlhead); + unsigned char* pstring; + unsigned char* pdata; + int i; + + if (sopt->sopt_valsize < sizeneeded) { + // this is a probe to retrieve the space needed for + // a dump of the sysctl table + oid->id = sizeneeded; + sopt->sopt_valsize = sizeof(struct dn_id); + return 0; + } + + entry = (struct sysctlhead*)(oid+1); + for( i=0; iblocklen = GST.entry[i].head.blocklen; + entry->namelen = GST.entry[i].head.namelen; + entry->flags = GST.entry[i].head.flags; + entry->datalen = GST.entry[i].head.datalen; + pdata = (unsigned char*)(entry+1); + pstring = pdata+GST.entry[i].head.datalen; + bcopy(GST.entry[i].data, pdata, GST.entry[i].head.datalen); + bcopy(GST.entry[i].name, pstring, GST.entry[i].head.namelen); + entry = (struct sysctlhead*) + ((unsigned char*)(entry) + GST.entry[i].head.blocklen); + } + sopt->sopt_valsize = sizeneeded; + return 0; } -void -panic(const char *fmt, ...) +int +kesysctl_emu_set(void* p, int l) +{ + struct sysctlhead* entry; + unsigned char* pdata; + unsigned char* pstring; + int i = 0; + + entry = (struct sysctlhead*)(((struct dn_id*)p)+1); + pdata = (unsigned char*)(entry+1); + pstring = pdata + entry->datalen; + + for (i=0; idatalen != GST.entry[i].head.datalen) { + printf("%s: len mismatch, user %d vs kernel %d\n", + __FUNCTION__, entry->datalen, + GST.entry[i].head.datalen); + return -1; + } + // check access (at the moment flags handles only the R/W rights + //later on will be type + access + if( (GST.entry[i].head.flags & 3) == CTLFLAG_RD) { + printf("%s: the entry %s is read only\n", + __FUNCTION__,GST.entry[i].name); + return -1; + } + bcopy(pdata, GST.entry[i].data, GST.entry[i].head.datalen); + return 0; + } + printf("%s: match not found\n",__FUNCTION__); + return 0; +} + +/* convert all _ to . until the first . */ +static void +underscoretopoint(char* s) { - printf("%s", fmt); - for (;;); + for (; *s && *s != '.'; s++) + if (*s == '_') + *s = '.'; } -#include +static int +formatnames() +{ + int i; + int size=0; + char* name; + + for (i=0; i> 2, + GST.entry[i].head.flags & 0x00000003); + printf("data %i\n", *(int*)(GST.entry[i].data)); + printf("datalen %i\n", GST.entry[i].head.datalen); + printf("blocklen %i\n", GST.entry[i].head.blocklen); + } +} -/* - * Windows' _snprintf doesn't terminate buffer with zero if size > buf_size - */ -int -snprintf(char *buf, int buf_size, char *fmt, ...) +void sysctl_addgroup_f1(); +void sysctl_addgroup_f2(); +void sysctl_addgroup_f3(); +void sysctl_addgroup_f4(); + +void +keinit_GST() { - va_list ap; - va_start(ap, fmt); - if (_vsnprintf(buf, buf_size, fmt, ap) < 0) - buf[buf_size - 1] = '\0'; - va_end(ap); + int ret; + + sysctl_addgroup_f1(); + sysctl_addgroup_f2(); + sysctl_addgroup_f3(); + sysctl_addgroup_f4(); + ret = formatnames(); + if (ret != 0) + printf("conversion of names failed for some reason\n"); + //dumpGST(); + printf("*** Global Sysctl Table entries = %i, total size = %i ***\n", + GST.count, GST.totalsize); +} - return 0; +void +keexit_GST() +{ + if (GST.namebuffer != NULL) + free(GST.namebuffer,0); + bzero(&GST, sizeof(GST)); } -#endif + +void +sysctl_pushback(char* name, int flags, int datalen, void* data) +{ + if (GST.count >= GST_HARD_LIMIT) { + printf("WARNING: global sysctl table full, this entry will not be added," + "please recompile the module increasing the table size\n"); + return; + } + GST.entry[GST.count].head.namelen = strlen(name)+1; //add space for '\0' + GST.entry[GST.count].name = name; + GST.entry[GST.count].head.flags = flags; + GST.entry[GST.count].data = data; + GST.entry[GST.count].head.datalen = datalen; + GST.entry[GST.count].head.blocklen = + ((sizeof(struct sysctlhead) + GST.entry[GST.count].head.namelen + + GST.entry[GST.count].head.datalen)+3) & ~3; + GST.totalsize += GST.entry[GST.count].head.blocklen; + GST.count++; +} +#endif /* EMULATE_SYSCTL */