Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/ip_output.c
| Show First 20 Lines • Show All 1,038 Lines • ▼ Show 20 Lines | #endif | ||||
| } | } | ||||
| done: | done: | ||||
| *m_frag = m0; | *m_frag = m0; | ||||
| return error; | return error; | ||||
| } | } | ||||
| void | void | ||||
| in_delayed_cksum(struct mbuf *m) | in_delayed_cksum_o(struct mbuf *m, uint16_t iph_offset) | ||||
| { | { | ||||
| struct ip *ip; | struct ip *ip; | ||||
| struct udphdr *uh; | struct udphdr *uh; | ||||
| uint16_t cklen, csum, offset; | uint16_t cklen, csum, offset; | ||||
| ip = mtod(m, struct ip *); | ip = (struct ip *)mtodo(m, iph_offset); | ||||
| offset = ip->ip_hl << 2 ; | offset = iph_offset + (ip->ip_hl << 2); | ||||
markj: We should add an assertion here `KASSERT(iph_offset + sizeof(*ip) <= m->m_len, ("%s: truncated… | |||||
| if (m->m_pkthdr.csum_flags & CSUM_UDP) { | if (m->m_pkthdr.csum_flags & CSUM_UDP) { | ||||
| /* if udp header is not in the first mbuf copy udplen */ | /* if udp header is not in the first mbuf copy udplen */ | ||||
| if (offset + sizeof(struct udphdr) > m->m_len) { | if (offset + sizeof(struct udphdr) > m->m_len) { | ||||
| m_copydata(m, offset + offsetof(struct udphdr, | m_copydata(m, offset + offsetof(struct udphdr, | ||||
| uh_ulen), sizeof(cklen), (caddr_t)&cklen); | uh_ulen), sizeof(cklen), (caddr_t)&cklen); | ||||
| cklen = ntohs(cklen); | cklen = ntohs(cklen); | ||||
| } else { | } else { | ||||
| uh = (struct udphdr *)mtodo(m, offset); | uh = (struct udphdr *)mtodo(m, offset); | ||||
| cklen = ntohs(uh->uh_ulen); | cklen = ntohs(uh->uh_ulen); | ||||
| } | } | ||||
| csum = in_cksum_skip(m, cklen + offset, offset); | csum = in_cksum_skip(m, cklen + offset, offset); | ||||
| if (csum == 0) | if (csum == 0) | ||||
| csum = 0xffff; | csum = 0xffff; | ||||
| } else { | } else { | ||||
| cklen = ntohs(ip->ip_len); | cklen = ntohs(ip->ip_len); | ||||
| csum = in_cksum_skip(m, cklen, offset); | csum = in_cksum_skip(m, cklen, offset); | ||||
| } | } | ||||
| offset += m->m_pkthdr.csum_data; /* checksum offset */ | offset += m->m_pkthdr.csum_data; /* checksum offset */ | ||||
| if (offset + sizeof(csum) > m->m_len) | if (offset + sizeof(csum) > m->m_len) | ||||
| m_copyback(m, offset, sizeof(csum), (caddr_t)&csum); | m_copyback(m, offset, sizeof(csum), (caddr_t)&csum); | ||||
| else | else | ||||
| *(u_short *)mtodo(m, offset) = csum; | *(u_short *)mtodo(m, offset) = csum; | ||||
| } | |||||
| void | |||||
| in_delayed_cksum(struct mbuf *m) | |||||
| { | |||||
| in_delayed_cksum_o(m, 0); | |||||
| } | } | ||||
| /* | /* | ||||
| * IP socket option processing. | * IP socket option processing. | ||||
| */ | */ | ||||
| int | int | ||||
| ip_ctloutput(struct socket *so, struct sockopt *sopt) | ip_ctloutput(struct socket *so, struct sockopt *sopt) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 495 Lines • Show Last 20 Lines | |||||
We should add an assertion here KASSERT(iph_offset + sizeof(*ip) <= m->m_len, ("%s: truncated mbuf %p", __func__, m));