| 770 | #endif |
| 771 | |
| 772 | static void |
| 773 | syncache_get_toa(struct mbuf *m, struct socket *so) |
| 774 | { |
| 775 | int length; |
| 776 | u_char *ptr = NULL; |
| 777 | struct tcphdr *th = NULL; |
| 778 | |
| 779 | struct ipovly *ipov = mtod(m, struct ipovly *); |
| 780 | struct ip *ip = (struct ip *)ipov; |
| 781 | |
| 782 | #ifdef INET6 |
| 783 | struct ip6_hdr *ip6 = (struct ip6_hdr *)ipov; |
| 784 | |
| 785 | if (ip->ip_v == 6) { |
| 786 | /* |
| 787 | * FIXME: ipv6 not support now |
| 788 | * th = ??? |
| 789 | */ |
| 790 | |
| 791 | return; |
| 792 | |
| 793 | } else |
| 794 | #endif |
| 795 | { |
| 796 | th = (struct tcphdr *)((caddr_t)ip + (ntohs(ip->ip_len) - ntohs(ipov->ih_len))); |
| 797 | } |
| 798 | |
| 799 | length = (th->th_off << 2) - sizeof (struct tcphdr); |
| 800 | ptr = (u_char *)(th + 1); |
| 801 | |
| 802 | while (length > 0) { |
| 803 | int opcode = *ptr++; |
| 804 | int opsize; |
| 805 | |
| 806 | switch (opcode) { |
| 807 | case TCPOPT_EOL: |
| 808 | return; |
| 809 | |
| 810 | case TCPOPT_NOP: |
| 811 | length--; |
| 812 | continue; |
| 813 | |
| 814 | default: |
| 815 | opsize = *ptr++; |
| 816 | if (opsize < 2 || opsize > length) { |
| 817 | return; |
| 818 | } |
| 819 | |
| 820 | if (TCPOPT_TOA == opcode && TCPOLEN_TOA == opsize) { |
| 821 | bcopy(ptr - 2, so->so_toa, TCPOLEN_TOA); |
| 822 | return; |
| 823 | } |
| 824 | |
| 825 | ptr += opsize - 2; |
| 826 | length -= opsize; |
| 827 | } |
| 828 | } |
| 829 | } |