alias_proxy.c (124621) | alias_proxy.c (127094) |
---|---|
1/*- 2 * Copyright (c) 2001 Charles Mott <cm@linktel.net> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2001 Charles Mott <cm@linktel.net> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> |
28__FBSDID("$FreeBSD: head/sys/netinet/libalias/alias_proxy.c 124621 2004-01-17 10:52:21Z phk $"); | 28__FBSDID("$FreeBSD: head/sys/netinet/libalias/alias_proxy.c 127094 2004-03-16 21:30:41Z des $"); |
29 30/* file: alias_proxy.c 31 32 This file encapsulates special operations related to transparent 33 proxy redirection. This is where packets with a particular destination, 34 usually tcp port 80, are redirected to a proxy server. 35 36 When packets are proxied, the destination address and port are --- 29 unchanged lines hidden (view full) --- 66/* BSD IPV4 includes */ 67#include <netinet/in_systm.h> 68#include <netinet/in.h> 69#include <netinet/ip.h> 70#include <netinet/tcp.h> 71 72#include <arpa/inet.h> 73 | 29 30/* file: alias_proxy.c 31 32 This file encapsulates special operations related to transparent 33 proxy redirection. This is where packets with a particular destination, 34 usually tcp port 80, are redirected to a proxy server. 35 36 When packets are proxied, the destination address and port are --- 29 unchanged lines hidden (view full) --- 66/* BSD IPV4 includes */ 67#include <netinet/in_systm.h> 68#include <netinet/in.h> 69#include <netinet/ip.h> 70#include <netinet/tcp.h> 71 72#include <arpa/inet.h> 73 |
74#include "alias_local.h" /* Functions used by alias*.c */ 75#include "alias.h" /* Public API functions for libalias */ | 74#include "alias_local.h" /* Functions used by alias*.c */ 75#include "alias.h" /* Public API functions for libalias */ |
76 77 78 79/* 80 Data structures 81 */ 82 83/* 84 * A linked list of arbitrary length, based on struct proxy_entry is 85 * used to store proxy rules. 86 */ | 76 77 78 79/* 80 Data structures 81 */ 82 83/* 84 * A linked list of arbitrary length, based on struct proxy_entry is 85 * used to store proxy rules. 86 */ |
87struct proxy_entry 88{ 89 struct libalias *la; | 87struct proxy_entry { 88 struct libalias *la; |
90#define PROXY_TYPE_ENCODE_NONE 1 91#define PROXY_TYPE_ENCODE_TCPSTREAM 2 92#define PROXY_TYPE_ENCODE_IPHDR 3 | 89#define PROXY_TYPE_ENCODE_NONE 1 90#define PROXY_TYPE_ENCODE_TCPSTREAM 2 91#define PROXY_TYPE_ENCODE_IPHDR 3 |
93 int rule_index; 94 int proxy_type; 95 u_char proto; 96 u_short proxy_port; 97 u_short server_port; | 92 int rule_index; 93 int proxy_type; 94 u_char proto; 95 u_short proxy_port; 96 u_short server_port; |
98 | 97 |
99 struct in_addr server_addr; | 98 struct in_addr server_addr; |
100 | 99 |
101 struct in_addr src_addr; 102 struct in_addr src_mask; | 100 struct in_addr src_addr; 101 struct in_addr src_mask; |
103 | 102 |
104 struct in_addr dst_addr; 105 struct in_addr dst_mask; | 103 struct in_addr dst_addr; 104 struct in_addr dst_mask; |
106 | 105 |
107 struct proxy_entry *next; 108 struct proxy_entry *last; | 106 struct proxy_entry *next; 107 struct proxy_entry *last; |
109}; 110 111 112 113/* 114 File scope variables 115*/ 116 --- 12 unchanged lines hidden (view full) --- 129 RuleNumberDelete() -- Removes all elements from the rule list 130 having a certain rule number. 131 ProxyEncodeTcpStream() -- Adds [DEST x.x.x.x xxxx] to the beginning 132 of a TCP stream. 133 ProxyEncodeIpHeader() -- Adds an IP option indicating the true 134 destination of a proxied IP packet 135*/ 136 | 108}; 109 110 111 112/* 113 File scope variables 114*/ 115 --- 12 unchanged lines hidden (view full) --- 128 RuleNumberDelete() -- Removes all elements from the rule list 129 having a certain rule number. 130 ProxyEncodeTcpStream() -- Adds [DEST x.x.x.x xxxx] to the beginning 131 of a TCP stream. 132 ProxyEncodeIpHeader() -- Adds an IP option indicating the true 133 destination of a proxied IP packet 134*/ 135 |
137static int IpMask(int, struct in_addr *); 138static int IpAddr(char *, struct in_addr *); 139static int IpPort(char *, int, int *); 140static void RuleAdd(struct libalias *la, struct proxy_entry *); 141static void RuleDelete(struct proxy_entry *); 142static int RuleNumberDelete(struct libalias *la, int); 143static void ProxyEncodeTcpStream(struct alias_link *, struct ip *, int); 144static void ProxyEncodeIpHeader(struct ip *, int); | 136static int IpMask(int, struct in_addr *); 137static int IpAddr(char *, struct in_addr *); 138static int IpPort(char *, int, int *); 139static void RuleAdd(struct libalias *la, struct proxy_entry *); 140static void RuleDelete(struct proxy_entry *); 141static int RuleNumberDelete(struct libalias *la, int); 142static void ProxyEncodeTcpStream(struct alias_link *, struct ip *, int); 143static void ProxyEncodeIpHeader(struct ip *, int); |
145 146static int 147IpMask(int nbits, struct in_addr *mask) 148{ | 144 145static int 146IpMask(int nbits, struct in_addr *mask) 147{ |
149 int i; 150 u_int imask; | 148 int i; 149 u_int imask; |
151 | 150 |
152 if (nbits < 0 || nbits > 32) 153 return -1; | 151 if (nbits < 0 || nbits > 32) 152 return -1; |
154 | 153 |
155 imask = 0; 156 for (i=0; i<nbits; i++) 157 imask = (imask >> 1) + 0x80000000; 158 mask->s_addr = htonl(imask); | 154 imask = 0; 155 for (i = 0; i < nbits; i++) 156 imask = (imask >> 1) + 0x80000000; 157 mask->s_addr = htonl(imask); |
159 | 158 |
160 return 0; | 159 return 0; |
161} 162 163static int 164IpAddr(char *s, struct in_addr *addr) 165{ | 160} 161 162static int 163IpAddr(char *s, struct in_addr *addr) 164{ |
166 if (inet_aton(s, addr) == 0) 167 return -1; 168 else 169 return 0; | 165 if (inet_aton(s, addr) == 0) 166 return -1; 167 else 168 return 0; |
170} 171 172static int 173IpPort(char *s, int proto, int *port) 174{ | 169} 170 171static int 172IpPort(char *s, int proto, int *port) 173{ |
175 int n; | 174 int n; |
176 | 175 |
177 n = sscanf(s, "%d", port); 178 if (n != 1) 179 { 180 struct servent *se; | 176 n = sscanf(s, "%d", port); 177 if (n != 1) { 178 struct servent *se; |
181 | 179 |
182 if (proto == IPPROTO_TCP) 183 se = getservbyname(s, "tcp"); 184 else if (proto == IPPROTO_UDP) 185 se = getservbyname(s, "udp"); 186 else 187 return -1; | 180 if (proto == IPPROTO_TCP) 181 se = getservbyname(s, "tcp"); 182 else if (proto == IPPROTO_UDP) 183 se = getservbyname(s, "udp"); 184 else 185 return -1; |
188 | 186 |
189 if (se == NULL) 190 return -1; | 187 if (se == NULL) 188 return -1; |
191 | 189 |
192 *port = (u_int) ntohs(se->s_port); 193 } 194 195 return 0; | 190 *port = (u_int) ntohs(se->s_port); 191 } 192 return 0; |
196} 197 198void 199RuleAdd(struct libalias *la, struct proxy_entry *entry) 200{ | 193} 194 195void 196RuleAdd(struct libalias *la, struct proxy_entry *entry) 197{ |
201 int rule_index; 202 struct proxy_entry *ptr; 203 struct proxy_entry *ptr_last; | 198 int rule_index; 199 struct proxy_entry *ptr; 200 struct proxy_entry *ptr_last; |
204 | 201 |
205 if (la->proxyList == NULL) 206 { 207 la->proxyList = entry; 208 entry->last = NULL; 209 entry->next = NULL; 210 return; 211 } 212 entry->la = la; | 202 if (la->proxyList == NULL) { 203 la->proxyList = entry; 204 entry->last = NULL; 205 entry->next = NULL; 206 return; 207 } 208 entry->la = la; |
213 | 209 |
214 rule_index = entry->rule_index; 215 ptr = la->proxyList; 216 ptr_last = NULL; 217 while (ptr != NULL) 218 { 219 if (ptr->rule_index >= rule_index) 220 { 221 if (ptr_last == NULL) 222 { 223 entry->next = la->proxyList; 224 entry->last = NULL; 225 la->proxyList->last = entry; 226 la->proxyList = entry; 227 return; 228 } | 210 rule_index = entry->rule_index; 211 ptr = la->proxyList; 212 ptr_last = NULL; 213 while (ptr != NULL) { 214 if (ptr->rule_index >= rule_index) { 215 if (ptr_last == NULL) { 216 entry->next = la->proxyList; 217 entry->last = NULL; 218 la->proxyList->last = entry; 219 la->proxyList = entry; 220 return; 221 } 222 ptr_last->next = entry; 223 ptr->last = entry; 224 entry->last = ptr->last; 225 entry->next = ptr; 226 return; 227 } 228 ptr_last = ptr; 229 ptr = ptr->next; 230 } |
229 | 231 |
230 ptr_last->next = entry; 231 ptr->last = entry; 232 entry->last = ptr->last; 233 entry->next = ptr; 234 return; 235 } 236 ptr_last = ptr; 237 ptr = ptr->next; 238 } 239 240 ptr_last->next = entry; 241 entry->last = ptr_last; 242 entry->next = NULL; | 232 ptr_last->next = entry; 233 entry->last = ptr_last; 234 entry->next = NULL; |
243} 244 245static void 246RuleDelete(struct proxy_entry *entry) 247{ | 235} 236 237static void 238RuleDelete(struct proxy_entry *entry) 239{ |
248 struct libalias *la; 249 250 la = entry->la; 251 if (entry->last != NULL) 252 entry->last->next = entry->next; 253 else 254 la->proxyList = entry->next; | 240 struct libalias *la; |
255 | 241 |
256 if (entry->next != NULL) 257 entry->next->last = entry->last; | 242 la = entry->la; 243 if (entry->last != NULL) 244 entry->last->next = entry->next; 245 else 246 la->proxyList = entry->next; |
258 | 247 |
259 free(entry); | 248 if (entry->next != NULL) 249 entry->next->last = entry->last; 250 251 free(entry); |
260} 261 262static int 263RuleNumberDelete(struct libalias *la, int rule_index) 264{ | 252} 253 254static int 255RuleNumberDelete(struct libalias *la, int rule_index) 256{ |
265 int err; 266 struct proxy_entry *ptr; | 257 int err; 258 struct proxy_entry *ptr; |
267 | 259 |
268 err = -1; 269 ptr = la->proxyList; 270 while (ptr != NULL) 271 { 272 struct proxy_entry *ptr_next; | 260 err = -1; 261 ptr = la->proxyList; 262 while (ptr != NULL) { 263 struct proxy_entry *ptr_next; |
273 | 264 |
274 ptr_next = ptr->next; 275 if (ptr->rule_index == rule_index) 276 { 277 err = 0; 278 RuleDelete(ptr); 279 } | 265 ptr_next = ptr->next; 266 if (ptr->rule_index == rule_index) { 267 err = 0; 268 RuleDelete(ptr); 269 } 270 ptr = ptr_next; 271 } |
280 | 272 |
281 ptr = ptr_next; 282 } 283 284 return err; | 273 return err; |
285} 286 287static void 288ProxyEncodeTcpStream(struct alias_link *link, | 274} 275 276static void 277ProxyEncodeTcpStream(struct alias_link *link, |
289 struct ip *pip, 290 int maxpacketsize) | 278 struct ip *pip, 279 int maxpacketsize) |
291{ | 280{ |
292 int slen; 293 char buffer[40]; 294 struct tcphdr *tc; | 281 int slen; 282 char buffer[40]; 283 struct tcphdr *tc; |
295 296/* Compute pointer to tcp header */ | 284 285/* Compute pointer to tcp header */ |
297 tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2)); | 286 tc = (struct tcphdr *)((char *)pip + (pip->ip_hl << 2)); |
298 299/* Don't modify if once already modified */ 300 | 287 288/* Don't modify if once already modified */ 289 |
301 if (GetAckModified (link)) 302 return; | 290 if (GetAckModified(link)) 291 return; |
303 304/* Translate destination address and port to string form */ | 292 293/* Translate destination address and port to string form */ |
305 snprintf(buffer, sizeof(buffer) - 2, "[DEST %s %d]", 306 inet_ntoa(GetProxyAddress (link)), (u_int) ntohs(GetProxyPort (link))); | 294 snprintf(buffer, sizeof(buffer) - 2, "[DEST %s %d]", 295 inet_ntoa(GetProxyAddress(link)), (u_int) ntohs(GetProxyPort(link))); |
307 308/* Pad string out to a multiple of two in length */ | 296 297/* Pad string out to a multiple of two in length */ |
309 slen = strlen(buffer); 310 switch (slen % 2) 311 { 312 case 0: 313 strcat(buffer, " \n"); 314 slen += 2; 315 break; 316 case 1: 317 strcat(buffer, "\n"); 318 slen += 1; 319 } | 298 slen = strlen(buffer); 299 switch (slen % 2) { 300 case 0: 301 strcat(buffer, " \n"); 302 slen += 2; 303 break; 304 case 1: 305 strcat(buffer, "\n"); 306 slen += 1; 307 } |
320 321/* Check for packet overflow */ | 308 309/* Check for packet overflow */ |
322 if ((ntohs(pip->ip_len) + strlen(buffer)) > maxpacketsize) 323 return; | 310 if ((ntohs(pip->ip_len) + strlen(buffer)) > maxpacketsize) 311 return; |
324 325/* Shift existing TCP data and insert destination string */ | 312 313/* Shift existing TCP data and insert destination string */ |
326 { 327 int dlen; 328 int hlen; 329 u_char *p; | 314 { 315 int dlen; 316 int hlen; 317 u_char *p; |
330 | 318 |
331 hlen = (pip->ip_hl + tc->th_off) << 2; 332 dlen = ntohs (pip->ip_len) - hlen; | 319 hlen = (pip->ip_hl + tc->th_off) << 2; 320 dlen = ntohs(pip->ip_len) - hlen; |
333 334/* Modify first packet that has data in it */ 335 | 321 322/* Modify first packet that has data in it */ 323 |
336 if (dlen == 0) 337 return; | 324 if (dlen == 0) 325 return; |
338 | 326 |
339 p = (char *) pip; 340 p += hlen; | 327 p = (char *)pip; 328 p += hlen; |
341 | 329 |
342 memmove(p + slen, p, dlen); 343 memcpy(p, buffer, slen); 344 } | 330 memmove(p + slen, p, dlen); 331 memcpy(p, buffer, slen); 332 } |
345 346/* Save information about modfied sequence number */ | 333 334/* Save information about modfied sequence number */ |
347 { 348 int delta; | 335 { 336 int delta; |
349 | 337 |
350 SetAckModified(link); 351 delta = GetDeltaSeqOut(pip, link); 352 AddSeq(pip, link, delta+slen); 353 } | 338 SetAckModified(link); 339 delta = GetDeltaSeqOut(pip, link); 340 AddSeq(pip, link, delta + slen); 341 } |
354 355/* Update IP header packet length and checksum */ | 342 343/* Update IP header packet length and checksum */ |
356 { 357 int accumulate; | 344 { 345 int accumulate; |
358 | 346 |
359 accumulate = pip->ip_len; 360 pip->ip_len = htons(ntohs(pip->ip_len) + slen); 361 accumulate -= pip->ip_len; | 347 accumulate = pip->ip_len; 348 pip->ip_len = htons(ntohs(pip->ip_len) + slen); 349 accumulate -= pip->ip_len; |
362 | 350 |
363 ADJUST_CHECKSUM(accumulate, pip->ip_sum); 364 } | 351 ADJUST_CHECKSUM(accumulate, pip->ip_sum); 352 } |
365 366/* Update TCP checksum, Use TcpChecksum since so many things have 367 already changed. */ 368 | 353 354/* Update TCP checksum, Use TcpChecksum since so many things have 355 already changed. */ 356 |
369 tc->th_sum = 0; 370 tc->th_sum = TcpChecksum (pip); | 357 tc->th_sum = 0; 358 tc->th_sum = TcpChecksum(pip); |
371} 372 373static void 374ProxyEncodeIpHeader(struct ip *pip, | 359} 360 361static void 362ProxyEncodeIpHeader(struct ip *pip, |
375 int maxpacketsize) | 363 int maxpacketsize) |
376{ 377#define OPTION_LEN_BYTES 8 378#define OPTION_LEN_INT16 4 379#define OPTION_LEN_INT32 2 | 364{ 365#define OPTION_LEN_BYTES 8 366#define OPTION_LEN_INT16 4 367#define OPTION_LEN_INT32 2 |
380 u_char option[OPTION_LEN_BYTES]; | 368 u_char option[OPTION_LEN_BYTES]; |
381 382#ifdef DEBUG | 369 370#ifdef DEBUG |
383 fprintf(stdout, " ip cksum 1 = %x\n", (u_int) IpChecksum(pip)); 384 fprintf(stdout, "tcp cksum 1 = %x\n", (u_int) TcpChecksum(pip)); | 371 fprintf(stdout, " ip cksum 1 = %x\n", (u_int) IpChecksum(pip)); 372 fprintf(stdout, "tcp cksum 1 = %x\n", (u_int) TcpChecksum(pip)); |
385#endif 386 387/* Check to see that there is room to add an IP option */ | 373#endif 374 375/* Check to see that there is room to add an IP option */ |
388 if (pip->ip_hl > (0x0f - OPTION_LEN_INT32)) 389 return; | 376 if (pip->ip_hl > (0x0f - OPTION_LEN_INT32)) 377 return; |
390 391/* Build option and copy into packet */ | 378 379/* Build option and copy into packet */ |
392 { 393 u_char *ptr; 394 struct tcphdr *tc; | 380 { 381 u_char *ptr; 382 struct tcphdr *tc; |
395 | 383 |
396 ptr = (u_char *) pip; 397 ptr += 20; 398 memcpy(ptr + OPTION_LEN_BYTES, ptr, ntohs(pip->ip_len) - 20); | 384 ptr = (u_char *) pip; 385 ptr += 20; 386 memcpy(ptr + OPTION_LEN_BYTES, ptr, ntohs(pip->ip_len) - 20); |
399 | 387 |
400 option[0] = 0x64; /* class: 3 (reserved), option 4 */ 401 option[1] = OPTION_LEN_BYTES; | 388 option[0] = 0x64; /* class: 3 (reserved), option 4 */ 389 option[1] = OPTION_LEN_BYTES; |
402 | 390 |
403 memcpy(&option[2], (u_char *) &pip->ip_dst, 4); | 391 memcpy(&option[2], (u_char *) & pip->ip_dst, 4); |
404 | 392 |
405 tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2)); 406 memcpy(&option[6], (u_char *) &tc->th_sport, 2); | 393 tc = (struct tcphdr *)((char *)pip + (pip->ip_hl << 2)); 394 memcpy(&option[6], (u_char *) & tc->th_sport, 2); |
407 | 395 |
408 memcpy(ptr, option, 8); 409 } | 396 memcpy(ptr, option, 8); 397 } |
410 411/* Update checksum, header length and packet length */ | 398 399/* Update checksum, header length and packet length */ |
412 { 413 int i; 414 int accumulate; 415 u_short *sptr; | 400 { 401 int i; 402 int accumulate; 403 u_short *sptr; |
416 | 404 |
417 sptr = (u_short *) option; 418 accumulate = 0; 419 for (i=0; i<OPTION_LEN_INT16; i++) 420 accumulate -= *(sptr++); | 405 sptr = (u_short *) option; 406 accumulate = 0; 407 for (i = 0; i < OPTION_LEN_INT16; i++) 408 accumulate -= *(sptr++); |
421 | 409 |
422 sptr = (u_short *) pip; 423 accumulate += *sptr; 424 pip->ip_hl += OPTION_LEN_INT32; 425 accumulate -= *sptr; | 410 sptr = (u_short *) pip; 411 accumulate += *sptr; 412 pip->ip_hl += OPTION_LEN_INT32; 413 accumulate -= *sptr; |
426 | 414 |
427 accumulate += pip->ip_len; 428 pip->ip_len = htons(ntohs(pip->ip_len) + OPTION_LEN_BYTES); 429 accumulate -= pip->ip_len; | 415 accumulate += pip->ip_len; 416 pip->ip_len = htons(ntohs(pip->ip_len) + OPTION_LEN_BYTES); 417 accumulate -= pip->ip_len; |
430 | 418 |
431 ADJUST_CHECKSUM(accumulate, pip->ip_sum); 432 } | 419 ADJUST_CHECKSUM(accumulate, pip->ip_sum); 420 } |
433#undef OPTION_LEN_BYTES 434#undef OPTION_LEN_INT16 435#undef OPTION_LEN_INT32 436#ifdef DEBUG | 421#undef OPTION_LEN_BYTES 422#undef OPTION_LEN_INT16 423#undef OPTION_LEN_INT32 424#ifdef DEBUG |
437 fprintf(stdout, " ip cksum 2 = %x\n", (u_int) IpChecksum(pip)); 438 fprintf(stdout, "tcp cksum 2 = %x\n", (u_int) TcpChecksum(pip)); | 425 fprintf(stdout, " ip cksum 2 = %x\n", (u_int) IpChecksum(pip)); 426 fprintf(stdout, "tcp cksum 2 = %x\n", (u_int) TcpChecksum(pip)); |
439#endif 440} 441 442 443/* Functions by other packet alias source files 444 445 ProxyCheck() -- Checks whether an outgoing packet should 446 be proxied. 447 ProxyModify() -- Encodes the original destination address/port 448 for a packet which is to be redirected to 449 a proxy server. 450*/ 451 452int 453ProxyCheck(struct libalias *la, struct ip *pip, | 427#endif 428} 429 430 431/* Functions by other packet alias source files 432 433 ProxyCheck() -- Checks whether an outgoing packet should 434 be proxied. 435 ProxyModify() -- Encodes the original destination address/port 436 for a packet which is to be redirected to 437 a proxy server. 438*/ 439 440int 441ProxyCheck(struct libalias *la, struct ip *pip, |
454 struct in_addr *proxy_server_addr, 455 u_short *proxy_server_port) | 442 struct in_addr *proxy_server_addr, 443 u_short * proxy_server_port) |
456{ | 444{ |
457 u_short dst_port; 458 struct in_addr src_addr; 459 struct in_addr dst_addr; 460 struct proxy_entry *ptr; | 445 u_short dst_port; 446 struct in_addr src_addr; 447 struct in_addr dst_addr; 448 struct proxy_entry *ptr; |
461 | 449 |
462 src_addr = pip->ip_src; 463 dst_addr = pip->ip_dst; 464 dst_port = ((struct tcphdr *) ((char *) pip + (pip->ip_hl << 2))) 465 ->th_dport; | 450 src_addr = pip->ip_src; 451 dst_addr = pip->ip_dst; 452 dst_port = ((struct tcphdr *)((char *)pip + (pip->ip_hl << 2))) 453 ->th_dport; |
466 | 454 |
467 ptr = la->proxyList; 468 while (ptr != NULL) 469 { 470 u_short proxy_port; | 455 ptr = la->proxyList; 456 while (ptr != NULL) { 457 u_short proxy_port; |
471 | 458 |
472 proxy_port = ptr->proxy_port; 473 if ((dst_port == proxy_port || proxy_port == 0) 474 && pip->ip_p == ptr->proto 475 && src_addr.s_addr != ptr->server_addr.s_addr) 476 { 477 struct in_addr src_addr_masked; 478 struct in_addr dst_addr_masked; | 459 proxy_port = ptr->proxy_port; 460 if ((dst_port == proxy_port || proxy_port == 0) 461 && pip->ip_p == ptr->proto 462 && src_addr.s_addr != ptr->server_addr.s_addr) { 463 struct in_addr src_addr_masked; 464 struct in_addr dst_addr_masked; |
479 | 465 |
480 src_addr_masked.s_addr = src_addr.s_addr & ptr->src_mask.s_addr; 481 dst_addr_masked.s_addr = dst_addr.s_addr & ptr->dst_mask.s_addr; | 466 src_addr_masked.s_addr = src_addr.s_addr & ptr->src_mask.s_addr; 467 dst_addr_masked.s_addr = dst_addr.s_addr & ptr->dst_mask.s_addr; |
482 | 468 |
483 if ((src_addr_masked.s_addr == ptr->src_addr.s_addr) 484 && (dst_addr_masked.s_addr == ptr->dst_addr.s_addr)) 485 { 486 if ((*proxy_server_port = ptr->server_port) == 0) 487 *proxy_server_port = dst_port; 488 *proxy_server_addr = ptr->server_addr; 489 return ptr->proxy_type; 490 } 491 } 492 ptr = ptr->next; 493 } | 469 if ((src_addr_masked.s_addr == ptr->src_addr.s_addr) 470 && (dst_addr_masked.s_addr == ptr->dst_addr.s_addr)) { 471 if ((*proxy_server_port = ptr->server_port) == 0) 472 *proxy_server_port = dst_port; 473 *proxy_server_addr = ptr->server_addr; 474 return ptr->proxy_type; 475 } 476 } 477 ptr = ptr->next; 478 } |
494 | 479 |
495 return 0; | 480 return 0; |
496} 497 498void 499ProxyModify(struct libalias *la, struct alias_link *link, | 481} 482 483void 484ProxyModify(struct libalias *la, struct alias_link *link, |
500 struct ip *pip, 501 int maxpacketsize, 502 int proxy_type) | 485 struct ip *pip, 486 int maxpacketsize, 487 int proxy_type) |
503{ | 488{ |
504 switch (proxy_type) 505 { 506 case PROXY_TYPE_ENCODE_IPHDR: 507 ProxyEncodeIpHeader(pip, maxpacketsize); 508 break; | 489 switch (proxy_type) { 490 case PROXY_TYPE_ENCODE_IPHDR: 491 ProxyEncodeIpHeader(pip, maxpacketsize); 492 break; |
509 | 493 |
510 case PROXY_TYPE_ENCODE_TCPSTREAM: 511 ProxyEncodeTcpStream(link, pip, maxpacketsize); 512 break; 513 } | 494 case PROXY_TYPE_ENCODE_TCPSTREAM: 495 ProxyEncodeTcpStream(link, pip, maxpacketsize); 496 break; 497 } |
514} 515 516 517/* 518 Public API functions 519*/ 520 521int --- 15 unchanged lines hidden (view full) --- 537 * Subfields can be in arbitrary order. Port numbers and addresses 538 * must be in either numeric or symbolic form. An optional rule number 539 * is used to control the order in which rules are searched. If two 540 * rules have the same number, then search order cannot be guaranteed, 541 * and the rules should be disjoint. If no rule number is specified, 542 * then 0 is used, and group 0 rules are always checked before any 543 * others. 544 */ | 498} 499 500 501/* 502 Public API functions 503*/ 504 505int --- 15 unchanged lines hidden (view full) --- 521 * Subfields can be in arbitrary order. Port numbers and addresses 522 * must be in either numeric or symbolic form. An optional rule number 523 * is used to control the order in which rules are searched. If two 524 * rules have the same number, then search order cannot be guaranteed, 525 * and the rules should be disjoint. If no rule number is specified, 526 * then 0 is used, and group 0 rules are always checked before any 527 * others. 528 */ |
545 int i, n, len; 546 int cmd_len; 547 int token_count; 548 int state; 549 char *token; 550 char buffer[256]; 551 char str_port[sizeof(buffer)]; 552 char str_server_port[sizeof(buffer)]; 553 char *res = buffer; | 529 int i, n, len; 530 int cmd_len; 531 int token_count; 532 int state; 533 char *token; 534 char buffer[256]; 535 char str_port[sizeof(buffer)]; 536 char str_server_port[sizeof(buffer)]; 537 char *res = buffer; |
554 | 538 |
555 int rule_index; 556 int proto; 557 int proxy_type; 558 int proxy_port; 559 int server_port; 560 struct in_addr server_addr; 561 struct in_addr src_addr, src_mask; 562 struct in_addr dst_addr, dst_mask; 563 struct proxy_entry *proxy_entry; | 539 int rule_index; 540 int proto; 541 int proxy_type; 542 int proxy_port; 543 int server_port; 544 struct in_addr server_addr; 545 struct in_addr src_addr, src_mask; 546 struct in_addr dst_addr, dst_mask; 547 struct proxy_entry *proxy_entry; |
564 565/* Copy command line into a buffer */ | 548 549/* Copy command line into a buffer */ |
566 cmd += strspn(cmd, " \t"); 567 cmd_len = strlen(cmd); 568 if (cmd_len > (sizeof(buffer) - 1)) 569 return -1; 570 strcpy(buffer, cmd); | 550 cmd += strspn(cmd, " \t"); 551 cmd_len = strlen(cmd); 552 if (cmd_len > (sizeof(buffer) - 1)) 553 return -1; 554 strcpy(buffer, cmd); |
571 572/* Convert to lower case */ | 555 556/* Convert to lower case */ |
573 len = strlen(buffer); 574 for (i=0; i<len; i++) 575 buffer[i] = tolower((unsigned char)buffer[i]); | 557 len = strlen(buffer); 558 for (i = 0; i < len; i++) 559 buffer[i] = tolower((unsigned char)buffer[i]); |
576 577/* Set default proxy type */ 578 579/* Set up default values */ | 560 561/* Set default proxy type */ 562 563/* Set up default values */ |
580 rule_index = 0; 581 proxy_type = PROXY_TYPE_ENCODE_NONE; 582 proto = IPPROTO_TCP; 583 proxy_port = 0; 584 server_addr.s_addr = 0; 585 server_port = 0; 586 src_addr.s_addr = 0; 587 IpMask(0, &src_mask); 588 dst_addr.s_addr = 0; 589 IpMask(0, &dst_mask); | 564 rule_index = 0; 565 proxy_type = PROXY_TYPE_ENCODE_NONE; 566 proto = IPPROTO_TCP; 567 proxy_port = 0; 568 server_addr.s_addr = 0; 569 server_port = 0; 570 src_addr.s_addr = 0; 571 IpMask(0, &src_mask); 572 dst_addr.s_addr = 0; 573 IpMask(0, &dst_mask); |
590 | 574 |
591 str_port[0] = 0; 592 str_server_port[0] = 0; | 575 str_port[0] = 0; 576 str_server_port[0] = 0; |
593 594/* Parse command string with state machine */ 595#define STATE_READ_KEYWORD 0 596#define STATE_READ_TYPE 1 597#define STATE_READ_PORT 2 598#define STATE_READ_SERVER 3 599#define STATE_READ_RULE 4 600#define STATE_READ_DELETE 5 601#define STATE_READ_PROTO 6 602#define STATE_READ_SRC 7 603#define STATE_READ_DST 8 | 577 578/* Parse command string with state machine */ 579#define STATE_READ_KEYWORD 0 580#define STATE_READ_TYPE 1 581#define STATE_READ_PORT 2 582#define STATE_READ_SERVER 3 583#define STATE_READ_RULE 4 584#define STATE_READ_DELETE 5 585#define STATE_READ_PROTO 6 586#define STATE_READ_SRC 7 587#define STATE_READ_DST 8 |
604 state = STATE_READ_KEYWORD; 605 token = strsep(&res, " \t"); 606 token_count = 0; 607 while (token != NULL) 608 { 609 token_count++; 610 switch (state) 611 { 612 case STATE_READ_KEYWORD: 613 if (strcmp(token, "type") == 0) 614 state = STATE_READ_TYPE; 615 else if (strcmp(token, "port") == 0) 616 state = STATE_READ_PORT; 617 else if (strcmp(token, "server") == 0) 618 state = STATE_READ_SERVER; 619 else if (strcmp(token, "rule") == 0) 620 state = STATE_READ_RULE; 621 else if (strcmp(token, "delete") == 0) 622 state = STATE_READ_DELETE; 623 else if (strcmp(token, "proto") == 0) 624 state = STATE_READ_PROTO; 625 else if (strcmp(token, "src") == 0) 626 state = STATE_READ_SRC; 627 else if (strcmp(token, "dst") == 0) 628 state = STATE_READ_DST; 629 else 630 return -1; 631 break; | 588 state = STATE_READ_KEYWORD; 589 token = strsep(&res, " \t"); 590 token_count = 0; 591 while (token != NULL) { 592 token_count++; 593 switch (state) { 594 case STATE_READ_KEYWORD: 595 if (strcmp(token, "type") == 0) 596 state = STATE_READ_TYPE; 597 else if (strcmp(token, "port") == 0) 598 state = STATE_READ_PORT; 599 else if (strcmp(token, "server") == 0) 600 state = STATE_READ_SERVER; 601 else if (strcmp(token, "rule") == 0) 602 state = STATE_READ_RULE; 603 else if (strcmp(token, "delete") == 0) 604 state = STATE_READ_DELETE; 605 else if (strcmp(token, "proto") == 0) 606 state = STATE_READ_PROTO; 607 else if (strcmp(token, "src") == 0) 608 state = STATE_READ_SRC; 609 else if (strcmp(token, "dst") == 0) 610 state = STATE_READ_DST; 611 else 612 return -1; 613 break; |
632 | 614 |
633 case STATE_READ_TYPE: 634 if (strcmp(token, "encode_ip_hdr") == 0) 635 proxy_type = PROXY_TYPE_ENCODE_IPHDR; 636 else if (strcmp(token, "encode_tcp_stream") == 0) 637 proxy_type = PROXY_TYPE_ENCODE_TCPSTREAM; 638 else if (strcmp(token, "no_encode") == 0) 639 proxy_type = PROXY_TYPE_ENCODE_NONE; 640 else 641 return -1; 642 state = STATE_READ_KEYWORD; 643 break; | 615 case STATE_READ_TYPE: 616 if (strcmp(token, "encode_ip_hdr") == 0) 617 proxy_type = PROXY_TYPE_ENCODE_IPHDR; 618 else if (strcmp(token, "encode_tcp_stream") == 0) 619 proxy_type = PROXY_TYPE_ENCODE_TCPSTREAM; 620 else if (strcmp(token, "no_encode") == 0) 621 proxy_type = PROXY_TYPE_ENCODE_NONE; 622 else 623 return -1; 624 state = STATE_READ_KEYWORD; 625 break; |
644 | 626 |
645 case STATE_READ_PORT: 646 strcpy(str_port, token); 647 state = STATE_READ_KEYWORD; 648 break; | 627 case STATE_READ_PORT: 628 strcpy(str_port, token); 629 state = STATE_READ_KEYWORD; 630 break; |
649 | 631 |
650 case STATE_READ_SERVER: 651 { 652 int err; 653 char *p; 654 char s[sizeof(buffer)]; | 632 case STATE_READ_SERVER: 633 { 634 int err; 635 char *p; 636 char s[sizeof(buffer)]; |
655 | 637 |
656 p = token; 657 while (*p != ':' && *p != 0) 658 p++; | 638 p = token; 639 while (*p != ':' && *p != 0) 640 p++; |
659 | 641 |
660 if (*p != ':') 661 { 662 err = IpAddr(token, &server_addr); 663 if (err) 664 return -1; 665 } 666 else 667 { 668 *p = ' '; | 642 if (*p != ':') { 643 err = IpAddr(token, &server_addr); 644 if (err) 645 return -1; 646 } else { 647 *p = ' '; |
669 | 648 |
670 n = sscanf(token, "%s %s", s, str_server_port); 671 if (n != 2) 672 return -1; | 649 n = sscanf(token, "%s %s", s, str_server_port); 650 if (n != 2) 651 return -1; |
673 | 652 |
674 err = IpAddr(s, &server_addr); 675 if (err) 676 return -1; 677 } 678 } 679 state = STATE_READ_KEYWORD; 680 break; | 653 err = IpAddr(s, &server_addr); 654 if (err) 655 return -1; 656 } 657 } 658 state = STATE_READ_KEYWORD; 659 break; |
681 | 660 |
682 case STATE_READ_RULE: 683 n = sscanf(token, "%d", &rule_index); 684 if (n != 1 || rule_index < 0) 685 return -1; 686 state = STATE_READ_KEYWORD; 687 break; | 661 case STATE_READ_RULE: 662 n = sscanf(token, "%d", &rule_index); 663 if (n != 1 || rule_index < 0) 664 return -1; 665 state = STATE_READ_KEYWORD; 666 break; |
688 | 667 |
689 case STATE_READ_DELETE: 690 { 691 int err; 692 int rule_to_delete; | 668 case STATE_READ_DELETE: 669 { 670 int err; 671 int rule_to_delete; |
693 | 672 |
694 if (token_count != 2) 695 return -1; | 673 if (token_count != 2) 674 return -1; |
696 | 675 |
697 n = sscanf(token, "%d", &rule_to_delete); 698 if (n != 1) 699 return -1; 700 err = RuleNumberDelete(la, rule_to_delete); 701 if (err) 702 return -1; 703 return 0; 704 } | 676 n = sscanf(token, "%d", &rule_to_delete); 677 if (n != 1) 678 return -1; 679 err = RuleNumberDelete(la, rule_to_delete); 680 if (err) 681 return -1; 682 return 0; 683 } |
705 | 684 |
706 case STATE_READ_PROTO: 707 if (strcmp(token, "tcp") == 0) 708 proto = IPPROTO_TCP; 709 else if (strcmp(token, "udp") == 0) 710 proto = IPPROTO_UDP; 711 else 712 return -1; 713 state = STATE_READ_KEYWORD; 714 break; | 685 case STATE_READ_PROTO: 686 if (strcmp(token, "tcp") == 0) 687 proto = IPPROTO_TCP; 688 else if (strcmp(token, "udp") == 0) 689 proto = IPPROTO_UDP; 690 else 691 return -1; 692 state = STATE_READ_KEYWORD; 693 break; |
715 | 694 |
716 case STATE_READ_SRC: 717 case STATE_READ_DST: 718 { 719 int err; 720 char *p; 721 struct in_addr mask; 722 struct in_addr addr; | 695 case STATE_READ_SRC: 696 case STATE_READ_DST: 697 { 698 int err; 699 char *p; 700 struct in_addr mask; 701 struct in_addr addr; |
723 | 702 |
724 p = token; 725 while (*p != '/' && *p != 0) 726 p++; | 703 p = token; 704 while (*p != '/' && *p != 0) 705 p++; |
727 | 706 |
728 if (*p != '/') 729 { 730 IpMask(32, &mask); 731 err = IpAddr(token, &addr); 732 if (err) 733 return -1; 734 } 735 else 736 { 737 int nbits; 738 char s[sizeof(buffer)]; | 707 if (*p != '/') { 708 IpMask(32, &mask); 709 err = IpAddr(token, &addr); 710 if (err) 711 return -1; 712 } else { 713 int nbits; 714 char s[sizeof(buffer)]; |
739 | 715 |
740 *p = ' '; 741 n = sscanf(token, "%s %d", s, &nbits); 742 if (n != 2) 743 return -1; | 716 *p = ' '; 717 n = sscanf(token, "%s %d", s, &nbits); 718 if (n != 2) 719 return -1; |
744 | 720 |
745 err = IpAddr(s, &addr); 746 if (err) 747 return -1; | 721 err = IpAddr(s, &addr); 722 if (err) 723 return -1; |
748 | 724 |
749 err = IpMask(nbits, &mask); 750 if (err) 751 return -1; 752 } | 725 err = IpMask(nbits, &mask); 726 if (err) 727 return -1; 728 } |
753 | 729 |
754 if (state == STATE_READ_SRC) 755 { 756 src_addr = addr; 757 src_mask = mask; 758 } 759 else 760 { 761 dst_addr = addr; 762 dst_mask = mask; 763 } 764 } 765 state = STATE_READ_KEYWORD; 766 break; | 730 if (state == STATE_READ_SRC) { 731 src_addr = addr; 732 src_mask = mask; 733 } else { 734 dst_addr = addr; 735 dst_mask = mask; 736 } 737 } 738 state = STATE_READ_KEYWORD; 739 break; |
767 | 740 |
768 default: 769 return -1; 770 break; 771 } | 741 default: 742 return -1; 743 break; 744 } |
772 | 745 |
773 do { 774 token = strsep(&res, " \t"); 775 } while (token != NULL && !*token); 776 } | 746 do { 747 token = strsep(&res, " \t"); 748 } while (token != NULL && !*token); 749 } |
777#undef STATE_READ_KEYWORD 778#undef STATE_READ_TYPE 779#undef STATE_READ_PORT 780#undef STATE_READ_SERVER 781#undef STATE_READ_RULE 782#undef STATE_READ_DELETE 783#undef STATE_READ_PROTO 784#undef STATE_READ_SRC 785#undef STATE_READ_DST 786 787/* Convert port strings to numbers. This needs to be done after 788 the string is parsed, because the prototype might not be designated 789 before the ports (which might be symbolic entries in /etc/services) */ 790 | 750#undef STATE_READ_KEYWORD 751#undef STATE_READ_TYPE 752#undef STATE_READ_PORT 753#undef STATE_READ_SERVER 754#undef STATE_READ_RULE 755#undef STATE_READ_DELETE 756#undef STATE_READ_PROTO 757#undef STATE_READ_SRC 758#undef STATE_READ_DST 759 760/* Convert port strings to numbers. This needs to be done after 761 the string is parsed, because the prototype might not be designated 762 before the ports (which might be symbolic entries in /etc/services) */ 763 |
791 if (strlen(str_port) != 0) 792 { 793 int err; | 764 if (strlen(str_port) != 0) { 765 int err; |
794 | 766 |
795 err = IpPort(str_port, proto, &proxy_port); 796 if (err) 797 return -1; 798 } 799 else 800 { 801 proxy_port = 0; 802 } | 767 err = IpPort(str_port, proto, &proxy_port); 768 if (err) 769 return -1; 770 } else { 771 proxy_port = 0; 772 } |
803 | 773 |
804 if (strlen(str_server_port) != 0) 805 { 806 int err; | 774 if (strlen(str_server_port) != 0) { 775 int err; |
807 | 776 |
808 err = IpPort(str_server_port, proto, &server_port); 809 if (err) 810 return -1; 811 } 812 else 813 { 814 server_port = 0; 815 } | 777 err = IpPort(str_server_port, proto, &server_port); 778 if (err) 779 return -1; 780 } else { 781 server_port = 0; 782 } |
816 817/* Check that at least the server address has been defined */ | 783 784/* Check that at least the server address has been defined */ |
818 if (server_addr.s_addr == 0) 819 return -1; | 785 if (server_addr.s_addr == 0) 786 return -1; |
820 821/* Add to linked list */ | 787 788/* Add to linked list */ |
822 proxy_entry = malloc(sizeof(struct proxy_entry)); 823 if (proxy_entry == NULL) 824 return -1; | 789 proxy_entry = malloc(sizeof(struct proxy_entry)); 790 if (proxy_entry == NULL) 791 return -1; |
825 | 792 |
826 proxy_entry->proxy_type = proxy_type; 827 proxy_entry->rule_index = rule_index; 828 proxy_entry->proto = proto; 829 proxy_entry->proxy_port = htons(proxy_port); 830 proxy_entry->server_port = htons(server_port); 831 proxy_entry->server_addr = server_addr; 832 proxy_entry->src_addr.s_addr = src_addr.s_addr & src_mask.s_addr; 833 proxy_entry->dst_addr.s_addr = dst_addr.s_addr & dst_mask.s_addr; 834 proxy_entry->src_mask = src_mask; 835 proxy_entry->dst_mask = dst_mask; | 793 proxy_entry->proxy_type = proxy_type; 794 proxy_entry->rule_index = rule_index; 795 proxy_entry->proto = proto; 796 proxy_entry->proxy_port = htons(proxy_port); 797 proxy_entry->server_port = htons(server_port); 798 proxy_entry->server_addr = server_addr; 799 proxy_entry->src_addr.s_addr = src_addr.s_addr & src_mask.s_addr; 800 proxy_entry->dst_addr.s_addr = dst_addr.s_addr & dst_mask.s_addr; 801 proxy_entry->src_mask = src_mask; 802 proxy_entry->dst_mask = dst_mask; |
836 | 803 |
837 RuleAdd(la, proxy_entry); | 804 RuleAdd(la, proxy_entry); |
838 | 805 |
839 return 0; | 806 return 0; |
840} | 807} |