* Checksum updates are a little complicated because the checksum in the TCP/UDP * header isn't always a full checksum. In some cases (i.e. output) it's a * pseudo-header checksum, which is a partial checksum over src/dst IP * addresses, protocol number and length. * * That means we have the following cases: * * Input or forwarding: we don't have TSO, the checksum fields are full * checks
| 2115 | * don't have to update anything. |
| 2116 | **/ |
| 2117 | u_int16_t |
| 2118 | pf_cksum_fixup(u_int16_t cksum, u_int16_t old, u_int16_t new, u_int8_t udp) |
| 2119 | { |
| 2120 | u_int32_t x; |
| 2121 | |
| 2122 | x = cksum + old - new; |
| 2123 | x = (x + (x >> 16)) & 0xffff; |
| 2124 | |
| 2125 | /* optimise: eliminate a branch when not udp */ |
| 2126 | if (udp && cksum == 0x0000) |
| 2127 | return cksum; |
| 2128 | if (udp && x == 0x0000) |
| 2129 | x = 0xffff; |
| 2130 | |
| 2131 | return (u_int16_t)(x); |
| 2132 | } |
| 2133 | |
| 2134 | static void |
| 2135 | pf_patch_8(struct mbuf *m, u_int16_t *cksum, u_int8_t *f, u_int8_t v, bool hi, |
no outgoing calls
no test coverage detected