| Summary: | sendto returns systematically EINVAL with HDRINCL raw socks. | ||
|---|---|---|---|
| Product: | Base System | Reporter: | Kalou <pb> |
| Component: | kern | Assignee: | freebsd-bugs (Nobody) <bugs> |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | ||
| Priority: | Normal | ||
| Version: | 4.1-RELEASE | ||
| Hardware: | Any | ||
| OS: | Any | ||
State Changed From-To: open->closed Unfortunately this unexpected byte-swapping of IP_HDRINCL fields is something FreeBSD has done for a long time, and fixing it would break binary compatibility with existing applications. |
An IPPROTO_RAW socket, set with IP_HDRINCL option via setsockopt, won't let any raw packet out and return EINVAL. This is due to the fact that FreeBSD kernel uses flipped ip_len to speed up handling, where the user just supplied a htons'ed one. Then, a check in rip_output() forbids the case where : ip->ip_len < m->m_pkthdr.len A user supplied IP header is seen as 10240 bytes long and denied. Is this a kernel bug or a documented feature of the IPPROTO_RAW layer ? Fix: Against version 1.64.2.1 of sys/netinet/raw_ip.c : -- pub 1024D/98F6C473 2000-08-14 Pascal Bouchareine (kalou) <pb@hert.org>--Qyb7dSnpCu39ivbQ8pQtBhNQdghxT3XUwTT6OlQUzmRC6NGT Content-Type: text/plain; name="file.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="file.diff" --- raw_ip.c Sat Jul 15 09:14:31 2000 +++ /sys/netinet/raw_ip.c Wed Oct 4 02:45:28 2000 @@ -210,7 +210,16 @@ m_freem(m); return(EMSGSIZE); } + ip = mtod(m, struct ip *); + + /* user supplied packet is supposed to be sent + ** as is. Since we work with flipped ip_len until + ** the packet is sent, fixup user input :) + */ + + ip->ip_len = ntohs(ip->ip_len); + /* don't allow both user specified and setsockopt options, and don't allow packet length sizes that will crash */ if (((IP_VHL_HL(ip->ip_vhl) != (sizeof (*ip) >> 2)) How-To-Repeat: Well the code is rather heavy so i won't post there in. Just compile and run freebsd-spoof.c or any raw ip utility using IP_HDRINCL or mail me back for an example..