* Do option processing on a datagram, possibly discarding it if bad options * are encountered, or forwarding it if source-routed. * * The pass argument is used when operating in the IPSTEALTH mode to tell * what options to process: [LS]SRR (pass 0) or the others (pass 1). The * reason for as many as two passes is that when doing IPSTEALTH, non-routing * options should be processed only if t
| 100 | * processed further. |
| 101 | */ |
| 102 | int |
| 103 | ip_dooptions(struct mbuf *m, int pass) |
| 104 | { |
| 105 | struct ip *ip = mtod(m, struct ip *); |
| 106 | u_char *cp; |
| 107 | struct in_ifaddr *ia; |
| 108 | int opt, optlen, cnt, off, code, type = ICMP_PARAMPROB, forward = 0; |
| 109 | struct in_addr *sin, dst; |
| 110 | uint32_t ntime; |
| 111 | struct nhop_object *nh; |
| 112 | struct sockaddr_in ipaddr = { sizeof(ipaddr), AF_INET }; |
| 113 | |
| 114 | NET_EPOCH_ASSERT(); |
| 115 | |
| 116 | /* Ignore or reject packets with IP options. */ |
| 117 | if (V_ip_doopts == 0) |
| 118 | return 0; |
| 119 | else if (V_ip_doopts == 2) { |
| 120 | type = ICMP_UNREACH; |
| 121 | code = ICMP_UNREACH_FILTER_PROHIB; |
| 122 | goto bad; |
| 123 | } |
| 124 | |
| 125 | dst = ip->ip_dst; |
| 126 | cp = (u_char *)(ip + 1); |
| 127 | cnt = (ip->ip_hl << 2) - sizeof (struct ip); |
| 128 | for (; cnt > 0; cnt -= optlen, cp += optlen) { |
| 129 | opt = cp[IPOPT_OPTVAL]; |
| 130 | if (opt == IPOPT_EOL) |
| 131 | break; |
| 132 | if (opt == IPOPT_NOP) |
| 133 | optlen = 1; |
| 134 | else { |
| 135 | if (cnt < IPOPT_OLEN + sizeof(*cp)) { |
| 136 | code = &cp[IPOPT_OLEN] - (u_char *)ip; |
| 137 | goto bad; |
| 138 | } |
| 139 | optlen = cp[IPOPT_OLEN]; |
| 140 | if (optlen < IPOPT_OLEN + sizeof(*cp) || optlen > cnt) { |
| 141 | code = &cp[IPOPT_OLEN] - (u_char *)ip; |
| 142 | goto bad; |
| 143 | } |
| 144 | } |
| 145 | switch (opt) { |
| 146 | default: |
| 147 | break; |
| 148 | |
| 149 | /* |
| 150 | * Source routing with record. Find interface with current |
| 151 | * destination address. If none on this machine then drop if |
| 152 | * strictly routed, or do nothing if loosely routed. Record |
| 153 | * interface address and bring up next address component. If |
| 154 | * strictly routed make sure next address is on directly |
| 155 | * accessible net. |
| 156 | */ |
| 157 | case IPOPT_LSRR: |
| 158 | case IPOPT_SSRR: |
| 159 | #ifdef IPSTEALTH |
no test coverage detected