| 376 | } |
| 377 | |
| 378 | static void |
| 379 | ProxyEncodeIpHeader(struct ip *pip, |
| 380 | int maxpacketsize) |
| 381 | { |
| 382 | #define OPTION_LEN_BYTES 8 |
| 383 | #define OPTION_LEN_INT16 4 |
| 384 | #define OPTION_LEN_INT32 2 |
| 385 | _Alignas(_Alignof(u_short)) u_char option[OPTION_LEN_BYTES]; |
| 386 | |
| 387 | #ifdef LIBALIAS_DEBUG |
| 388 | fprintf(stdout, " ip cksum 1 = %x\n", (u_int) IpChecksum(pip)); |
| 389 | fprintf(stdout, "tcp cksum 1 = %x\n", (u_int) TcpChecksum(pip)); |
| 390 | #endif |
| 391 | |
| 392 | (void)maxpacketsize; |
| 393 | |
| 394 | /* Check to see that there is room to add an IP option */ |
| 395 | if (pip->ip_hl > (0x0f - OPTION_LEN_INT32)) |
| 396 | return; |
| 397 | |
| 398 | /* Build option and copy into packet */ |
| 399 | { |
| 400 | u_char *ptr; |
| 401 | struct tcphdr *tc; |
| 402 | |
| 403 | ptr = (u_char *) pip; |
| 404 | ptr += 20; |
| 405 | memcpy(ptr + OPTION_LEN_BYTES, ptr, ntohs(pip->ip_len) - 20); |
| 406 | |
| 407 | option[0] = 0x64; /* class: 3 (reserved), option 4 */ |
| 408 | option[1] = OPTION_LEN_BYTES; |
| 409 | |
| 410 | memcpy(&option[2], (u_char *) & pip->ip_dst, 4); |
| 411 | |
| 412 | tc = (struct tcphdr *)ip_next(pip); |
| 413 | memcpy(&option[6], (u_char *) & tc->th_sport, 2); |
| 414 | |
| 415 | memcpy(ptr, option, 8); |
| 416 | } |
| 417 | |
| 418 | /* Update checksum, header length and packet length */ |
| 419 | { |
| 420 | int i; |
| 421 | int accumulate; |
| 422 | u_short *sptr; |
| 423 | |
| 424 | sptr = (u_short *) option; |
| 425 | accumulate = 0; |
| 426 | for (i = 0; i < OPTION_LEN_INT16; i++) |
| 427 | accumulate -= *(sptr++); |
| 428 | |
| 429 | sptr = (u_short *) pip; |
| 430 | accumulate += *sptr; |
| 431 | pip->ip_hl += OPTION_LEN_INT32; |
| 432 | accumulate -= *sptr; |
| 433 | |
| 434 | accumulate += pip->ip_len; |
| 435 | pip->ip_len = htons(ntohs(pip->ip_len) + OPTION_LEN_BYTES); |
no test coverage detected