/* * Copyright (c) 1995 Danny Gasparovski. * * Please read the file COPYRIGHT for the * terms and conditions of the copyright. */ #define WANT_SYS_IOCTL_H #include <slirp.h> u_int curtime, time_fasttimo, last_slowtimo, detach_time; u_int detach_wait = 600000; /* 10 minutes */ struct emu_t *tcpemu; int inet_strtoip(const char* str, uint32_t *ip) { int comp[4]; if (sscanf(str, "%d.%d.%d.%d", &comp[0], &comp[1], &comp[2], &comp[3]) != 4) return -1; if ((unsigned)comp[0] >= 256 || (unsigned)comp[1] >= 256 || (unsigned)comp[2] >= 256 || (unsigned)comp[3] >= 256) return -1; *ip = (uint32_t)((comp[0] << 24) | (comp[1] << 16) | (comp[2] << 8) | comp[3]); return 0; } char* inet_iptostr(uint32_t ip) { static char buff[32]; snprintf(buff, sizeof(buff), "%d.%d.%d.%d", (ip >> 24) & 255, (ip >> 16) & 255, (ip >> 8) & 255, ip & 255); return buff; } /* * Get our IP address and put it in our_addr */ void getouraddr() { char* hostname = host_name(); SockAddress hostaddr; our_addr_ip = loopback_addr_ip; if (sock_address_init_resolve( &hostaddr, hostname, 0, 0 ) < 0) return; our_addr_ip = sock_address_get_ip(&hostaddr); if (our_addr_ip == (uint32_t)-1) our_addr_ip = loopback_addr_ip; } struct quehead { struct quehead *qh_link; struct quehead *qh_rlink; }; inline void insque(void* a, void* b) { register struct quehead *element = (struct quehead *) a; register struct quehead *head = (struct quehead *) b; element->qh_link = head->qh_link; head->qh_link = (struct quehead *)element; element->qh_rlink = (struct quehead *)head; ((struct quehead *)(element->qh_link))->qh_rlink = (struct quehead *)element; } inline void remque(void* a) { register struct quehead *element = (struct quehead *) a; ((struct quehead *)(element->qh_link))->qh_rlink = element->qh_rlink; ((struct quehead *)(element->qh_rlink))->qh_link = element->qh_link; element->qh_rlink = NULL; /* element->qh_link = NULL; TCP FIN1 crashes if you do this. Why ? */ } /* #endif */ #ifndef HAVE_STRERROR /* * For systems with no strerror */ extern int sys_nerr; extern char *sys_errlist[]; char * strerror(int error) { if (error < sys_nerr) return sys_errlist[error]; else return "Unknown error."; } #endif #ifndef HAVE_STRDUP char * strdup(const char* str) { char *bptr; int len = strlen(str); bptr = (char *)malloc(len+1); memcpy(bptr, str, len+1); return bptr; } #endif int (*lprint_print) _P((void *, const char *, va_list)); char *lprint_ptr, *lprint_ptr2, **lprint_arg; void lprint(const char *format, ...) { va_list args; va_start(args, format); if (lprint_print) lprint_ptr += (*lprint_print)(*lprint_arg, format, args); /* Check if they want output to be logged to file as well */ if (lfd) { /* * Remove \r's * otherwise you'll get ^M all over the file */ int len = strlen(format); char *bptr1, *bptr2; bptr1 = bptr2 = strdup(format); while (len--) { if (*bptr1 == '\r') memcpy(bptr1, bptr1+1, len+1); else bptr1++; } vfprintf(lfd, bptr2, args); free(bptr2); } va_end(args); } void add_emu(char* buff) { u_int lport, fport; u_int8_t tos = 0, emu = 0; char buff1[256], buff2[256], buff4[128]; char *buff3 = buff4; struct emu_t *emup; struct socket *so; if (sscanf(buff, "%256s %256s", buff2, buff1) != 2) { lprint("Error: Bad arguments\r\n"); return; } if (sscanf(buff1, "%d:%d", &lport, &fport) != 2) { lport = 0; if (sscanf(buff1, "%d", &fport) != 1) { lprint("Error: Bad first argument\r\n"); return; } } if (sscanf(buff2, "%128[^:]:%128s", buff1, buff3) != 2) { buff3 = 0; if (sscanf(buff2, "%256s", buff1) != 1) { lprint("Error: Bad second argument\r\n"); return; } } if (buff3) { if (strcmp(buff3, "lowdelay") == 0) tos = IPTOS_LOWDELAY; else if (strcmp(buff3, "throughput") == 0) tos = IPTOS_THROUGHPUT; else { lprint("Error: Expecting \"lowdelay\"/\"throughput\"\r\n"); return; } } if (strcmp(buff1, "ftp") == 0) emu = EMU_FTP; else if (strcmp(buff1, "irc") == 0) emu = EMU_IRC; else if (strcmp(buff1, "none") == 0) emu = EMU_NONE; /* ie: no emulation */ else { lprint("Error: Unknown service\r\n"); return; } /* First, check that it isn't already emulated */ for (emup = tcpemu; emup; emup = emup->next) { if (emup->lport == lport && emup->fport == fport) { lprint("Error: port already emulated\r\n"); return; } } /* link it */ emup = (struct emu_t *)malloc(sizeof (struct emu_t)); emup->lport = (u_int16_t)lport; emup->fport = (u_int16_t)fport; emup->tos = tos; emup->emu = emu; emup->next = tcpemu; tcpemu = emup; /* And finally, mark all current sessions, if any, as being emulated */ for (so = tcb.so_next; so != &tcb; so = so->so_next) { if ((lport && lport == so->so_laddr_port) || (fport && fport == so->so_faddr_port)) { if (emu) so->so_emu = emu; if (tos) so->so_iptos = tos; } } lprint("Adding emulation for %s to port %d/%d\r\n", buff1, emup->lport, emup->fport); } #ifdef BAD_SPRINTF #undef vsprintf #undef sprintf /* * Some BSD-derived systems have a sprintf which returns char * */ int vsprintf_len(char* string, const char* format, va_list args) { vsprintf(string, format, args); return strlen(string); } int sprintf_len(char *string, const char *format, ...) { va_list args; va_start(args, format); vsprintf(string, format, args); return strlen(string); } #endif