*/
/*
- * $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.
*/
#include <sys/cdefs.h>
#include <asm/div64.h> /* do_div on 2.4 */
#include <linux/random.h> /* get_random_bytes on 2.4 */
+#include <netinet/ip_fw.h>
+#include <netinet/ip_dummynet.h>
+#include <sys/malloc.h>
/*
* gettimeofday would be in sys/time.h but it is not
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;
/* credentials check */
#include <netinet/ip_fw.h>
+#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,
match = (u->gid == (uid_t)insn->d[0]);
return match;
}
+#endif /* __linux__ */
int
jailed(struct ucred *cred)
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;
}
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;
}
void
getmicrouptime(struct timeval *tv)
{
-#ifdef _WIN32
-#else
do_gettimeofday(tv);
-#endif
}
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));
#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.
*/
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; i<GST.count; i++) {
+ entry->blocklen = 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; i<GST.count; i++) {
+ if (strcmp(GST.entry[i].name, pstring) != 0)
+ continue;
+ printf("%s: match found! %s\n",__FUNCTION__,pstring);
+ //sanity check on len, not really useful now since
+ //we only accept int32
+ if (entry->datalen != 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 <stdarg.h>
+static int
+formatnames()
+{
+ int i;
+ int size=0;
+ char* name;
+
+ for (i=0; i<GST.count; i++)
+ size += GST.entry[i].head.namelen;
+ GST.namebuffer = malloc(size, 0, 0);
+ if (GST.namebuffer == NULL)
+ return -1;
+ name = GST.namebuffer;
+ for (i=0; i<GST.count; i++) {
+ bcopy(GST.entry[i].name, name, GST.entry[i].head.namelen);
+ underscoretopoint(name);
+ GST.entry[i].name = name;
+ name += GST.entry[i].head.namelen;
+ }
+ return 0;
+}
-extern int _vsnprintf(char *buf, int buf_size, char * fmt, va_list ap);
+static void
+dumpGST()
+{
+ int i;
+
+ for (i=0; i<GST.count; i++) {
+ printf("SYSCTL: entry %i\n", i);
+ printf("name %s\n", GST.entry[i].name);
+ printf("namelen %i\n", GST.entry[i].head.namelen);
+ printf("type %i access %i\n",
+ GST.entry[i].head.flags >> 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 */