• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 1995 Danny Gasparovski.
3  *
4  * Please read the file COPYRIGHT for the
5  * terms and conditions of the copyright.
6  */
7 
8 #define WANT_SYS_IOCTL_H
9 #include <slirp.h>
10 
11 u_int curtime, time_fasttimo, last_slowtimo, detach_time;
12 u_int detach_wait = 600000;	/* 10 minutes */
13 struct emu_t *tcpemu;
14 
15 int
inet_strtoip(const char * str,uint32_t * ip)16 inet_strtoip(const char*  str, uint32_t  *ip)
17 {
18     int  comp[4];
19 
20     if (sscanf(str, "%d.%d.%d.%d", &comp[0], &comp[1], &comp[2], &comp[3]) != 4)
21         return -1;
22 
23     if ((unsigned)comp[0] >= 256 ||
24         (unsigned)comp[1] >= 256 ||
25         (unsigned)comp[2] >= 256 ||
26         (unsigned)comp[3] >= 256)
27         return -1;
28 
29     *ip = (uint32_t)((comp[0] << 24) | (comp[1] << 16) |
30                      (comp[2] << 8)  |  comp[3]);
31     return 0;
32 }
33 
inet_iptostr(uint32_t ip)34 char*  inet_iptostr(uint32_t  ip)
35 {
36     static char  buff[32];
37 
38     snprintf(buff, sizeof(buff), "%d.%d.%d.%d",
39              (ip >> 24) & 255,
40              (ip >> 16) & 255,
41              (ip >> 8) & 255,
42              ip & 255);
43     return buff;
44 }
45 
46 /*
47  * Get our IP address and put it in our_addr
48  */
49 void
getouraddr()50 getouraddr()
51 {
52     char*        hostname = host_name();
53     SockAddress  hostaddr;
54 
55     our_addr_ip = loopback_addr_ip;
56 
57     if (sock_address_init_resolve( &hostaddr, hostname, 0, 0 ) < 0)
58         return;
59 
60     our_addr_ip = sock_address_get_ip(&hostaddr);
61     if (our_addr_ip == (uint32_t)-1)
62         our_addr_ip = loopback_addr_ip;
63 }
64 
65 struct quehead {
66 	struct quehead *qh_link;
67 	struct quehead *qh_rlink;
68 };
69 
70 inline void
insque(void * a,void * b)71 insque(void*  a, void*  b)
72 {
73 	register struct quehead *element = (struct quehead *) a;
74 	register struct quehead *head = (struct quehead *) b;
75 	element->qh_link = head->qh_link;
76 	head->qh_link = (struct quehead *)element;
77 	element->qh_rlink = (struct quehead *)head;
78 	((struct quehead *)(element->qh_link))->qh_rlink
79 	= (struct quehead *)element;
80 }
81 
82 inline void
remque(void * a)83 remque(void*  a)
84 {
85   register struct quehead *element = (struct quehead *) a;
86   ((struct quehead *)(element->qh_link))->qh_rlink = element->qh_rlink;
87   ((struct quehead *)(element->qh_rlink))->qh_link = element->qh_link;
88   element->qh_rlink = NULL;
89   /*  element->qh_link = NULL;  TCP FIN1 crashes if you do this.  Why ? */
90 }
91 
92 /* #endif */
93 
94 
95 #ifndef HAVE_STRERROR
96 
97 /*
98  * For systems with no strerror
99  */
100 
101 extern int sys_nerr;
102 extern char *sys_errlist[];
103 
104 char *
strerror(int error)105 strerror(int  error)
106 {
107 	if (error < sys_nerr)
108 	   return sys_errlist[error];
109 	else
110 	   return "Unknown error.";
111 }
112 
113 #endif
114 
115 
116 
117 #ifndef HAVE_STRDUP
118 char *
strdup(const char * str)119 strdup(const char*  str)
120 {
121 	char *bptr;
122 	int   len = strlen(str);
123 
124 	bptr = (char *)malloc(len+1);
125 	memcpy(bptr, str, len+1);
126 
127 	return bptr;
128 }
129 #endif
130 
131 
132 int (*lprint_print) _P((void *, const char *, va_list));
133 char *lprint_ptr, *lprint_ptr2, **lprint_arg;
134 
135 void
lprint(const char * format,...)136 lprint(const char *format, ...)
137 {
138 	va_list args;
139 
140     va_start(args, format);
141 	if (lprint_print)
142 	   lprint_ptr += (*lprint_print)(*lprint_arg, format, args);
143 
144 	/* Check if they want output to be logged to file as well */
145 	if (lfd) {
146 		/*
147 		 * Remove \r's
148 		 * otherwise you'll get ^M all over the file
149 		 */
150 		int len = strlen(format);
151 		char *bptr1, *bptr2;
152 
153 		bptr1 = bptr2 = strdup(format);
154 
155 		while (len--) {
156 			if (*bptr1 == '\r')
157 			   memcpy(bptr1, bptr1+1, len+1);
158 			else
159 			   bptr1++;
160 		}
161 		vfprintf(lfd, bptr2, args);
162 		free(bptr2);
163 	}
164 	va_end(args);
165 }
166 
167 void
add_emu(char * buff)168 add_emu(char* buff)
169 {
170 	u_int lport, fport;
171 	u_int8_t tos = 0, emu = 0;
172 	char buff1[256], buff2[256], buff4[128];
173 	char *buff3 = buff4;
174 	struct emu_t *emup;
175 	struct socket *so;
176 
177 	if (sscanf(buff, "%256s %256s", buff2, buff1) != 2) {
178 		lprint("Error: Bad arguments\r\n");
179 		return;
180 	}
181 
182 	if (sscanf(buff1, "%d:%d", &lport, &fport) != 2) {
183 		lport = 0;
184 		if (sscanf(buff1, "%d", &fport) != 1) {
185 			lprint("Error: Bad first argument\r\n");
186 			return;
187 		}
188 	}
189 
190 	if (sscanf(buff2, "%128[^:]:%128s", buff1, buff3) != 2) {
191 		buff3 = 0;
192 		if (sscanf(buff2, "%256s", buff1) != 1) {
193 			lprint("Error: Bad second argument\r\n");
194 			return;
195 		}
196 	}
197 
198 	if (buff3) {
199 		if (strcmp(buff3, "lowdelay") == 0)
200 		   tos = IPTOS_LOWDELAY;
201 		else if (strcmp(buff3, "throughput") == 0)
202 		   tos = IPTOS_THROUGHPUT;
203 		else {
204 			lprint("Error: Expecting \"lowdelay\"/\"throughput\"\r\n");
205 			return;
206 		}
207 	}
208 
209 	if (strcmp(buff1, "ftp") == 0)
210 	   emu = EMU_FTP;
211 	else if (strcmp(buff1, "irc") == 0)
212 	   emu = EMU_IRC;
213 	else if (strcmp(buff1, "none") == 0)
214 	   emu = EMU_NONE; /* ie: no emulation */
215 	else {
216 		lprint("Error: Unknown service\r\n");
217 		return;
218 	}
219 
220 	/* First, check that it isn't already emulated */
221 	for (emup = tcpemu; emup; emup = emup->next) {
222 		if (emup->lport == lport && emup->fport == fport) {
223 			lprint("Error: port already emulated\r\n");
224 			return;
225 		}
226 	}
227 
228 	/* link it */
229 	emup = (struct emu_t *)malloc(sizeof (struct emu_t));
230 	emup->lport = (u_int16_t)lport;
231 	emup->fport = (u_int16_t)fport;
232 	emup->tos = tos;
233 	emup->emu = emu;
234 	emup->next = tcpemu;
235 	tcpemu = emup;
236 
237 	/* And finally, mark all current sessions, if any, as being emulated */
238 	for (so = tcb.so_next; so != &tcb; so = so->so_next) {
239 		if ((lport && lport == so->so_laddr_port) ||
240 		    (fport && fport == so->so_faddr_port)) {
241 			if (emu)
242 			   so->so_emu = emu;
243 			if (tos)
244 			   so->so_iptos = tos;
245 		}
246 	}
247 
248 	lprint("Adding emulation for %s to port %d/%d\r\n", buff1, emup->lport, emup->fport);
249 }
250 
251 #ifdef BAD_SPRINTF
252 
253 #undef vsprintf
254 #undef sprintf
255 
256 /*
257  * Some BSD-derived systems have a sprintf which returns char *
258  */
259 
260 int
vsprintf_len(char * string,const char * format,va_list args)261 vsprintf_len(char* string, const char* format, va_list args)
262 {
263 	vsprintf(string, format, args);
264 	return strlen(string);
265 }
266 
267 int
sprintf_len(char * string,const char * format,...)268 sprintf_len(char *string, const char *format, ...)
269 {
270 	va_list args;
271 	va_start(args, format);
272 	vsprintf(string, format, args);
273 	return strlen(string);
274 }
275 
276 #endif
277 
278