summaryrefslogtreecommitdiffstats
path: root/sys/netinet/ip_output.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet/ip_output.c')
-rw-r--r--sys/netinet/ip_output.c213
1 files changed, 1 insertions, 212 deletions
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index edd49e1..6e4388e 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -57,6 +57,7 @@
#include <netinet/in_pcb.h>
#include <netinet/in_var.h>
#include <netinet/ip_var.h>
+#include <netinet/ip_options.h>
#include <machine/in_cksum.h>
@@ -92,16 +93,11 @@ SYSCTL_INT(_net_inet_ip, OID_AUTO, mbuf_frag_size, CTLFLAG_RW,
&mbuf_frag_size, 0, "Fragment outgoing mbufs to this size");
#endif
-static struct mbuf *ip_insertoptions(struct mbuf *, struct mbuf *, int *);
static struct ifnet *ip_multicast_if(struct in_addr *, int *);
static void ip_mloopback
(struct ifnet *, struct mbuf *, struct sockaddr_in *, int);
static int ip_getmoptions(struct inpcb *, struct sockopt *);
-static int ip_pcbopts(struct inpcb *, int, struct mbuf *);
static int ip_setmoptions(struct inpcb *, struct sockopt *);
-static struct ip_moptions *ip_findmoptions(struct inpcb *inp);
-
-int ip_optcopy(struct ip *, struct ip *);
extern struct protosw inetsw[];
@@ -1053,109 +1049,6 @@ in_delayed_cksum(struct mbuf *m)
}
/*
- * Insert IP options into preformed packet.
- * Adjust IP destination as required for IP source routing,
- * as indicated by a non-zero in_addr at the start of the options.
- *
- * XXX This routine assumes that the packet has no options in place.
- */
-static struct mbuf *
-ip_insertoptions(m, opt, phlen)
- register struct mbuf *m;
- struct mbuf *opt;
- int *phlen;
-{
- register struct ipoption *p = mtod(opt, struct ipoption *);
- struct mbuf *n;
- register struct ip *ip = mtod(m, struct ip *);
- unsigned optlen;
-
- optlen = opt->m_len - sizeof(p->ipopt_dst);
- if (optlen + ip->ip_len > IP_MAXPACKET) {
- *phlen = 0;
- return (m); /* XXX should fail */
- }
- if (p->ipopt_dst.s_addr)
- ip->ip_dst = p->ipopt_dst;
- if (m->m_flags & M_EXT || m->m_data - optlen < m->m_pktdat) {
- MGETHDR(n, M_DONTWAIT, MT_DATA);
- if (n == NULL) {
- *phlen = 0;
- return (m);
- }
- M_MOVE_PKTHDR(n, m);
- n->m_pkthdr.rcvif = NULL;
-#ifdef MAC
- mac_copy_mbuf(m, n);
-#endif
- n->m_pkthdr.len += optlen;
- m->m_len -= sizeof(struct ip);
- m->m_data += sizeof(struct ip);
- n->m_next = m;
- m = n;
- m->m_len = optlen + sizeof(struct ip);
- m->m_data += max_linkhdr;
- bcopy(ip, mtod(m, void *), sizeof(struct ip));
- } else {
- m->m_data -= optlen;
- m->m_len += optlen;
- m->m_pkthdr.len += optlen;
- bcopy(ip, mtod(m, void *), sizeof(struct ip));
- }
- ip = mtod(m, struct ip *);
- bcopy(p->ipopt_list, ip + 1, optlen);
- *phlen = sizeof(struct ip) + optlen;
- ip->ip_v = IPVERSION;
- ip->ip_hl = *phlen >> 2;
- ip->ip_len += optlen;
- return (m);
-}
-
-/*
- * Copy options from ip to jp,
- * omitting those not copied during fragmentation.
- */
-int
-ip_optcopy(ip, jp)
- struct ip *ip, *jp;
-{
- register u_char *cp, *dp;
- int opt, optlen, cnt;
-
- cp = (u_char *)(ip + 1);
- dp = (u_char *)(jp + 1);
- cnt = (ip->ip_hl << 2) - sizeof (struct ip);
- for (; cnt > 0; cnt -= optlen, cp += optlen) {
- opt = cp[0];
- if (opt == IPOPT_EOL)
- break;
- if (opt == IPOPT_NOP) {
- /* Preserve for IP mcast tunnel's LSRR alignment. */
- *dp++ = IPOPT_NOP;
- optlen = 1;
- continue;
- }
-
- KASSERT(cnt >= IPOPT_OLEN + sizeof(*cp),
- ("ip_optcopy: malformed ipv4 option"));
- optlen = cp[IPOPT_OLEN];
- KASSERT(optlen >= IPOPT_OLEN + sizeof(*cp) && optlen <= cnt,
- ("ip_optcopy: malformed ipv4 option"));
-
- /* bogus lengths should have been caught by ip_dooptions */
- if (optlen > cnt)
- optlen = cnt;
- if (IPOPT_COPIED(opt)) {
- bcopy(cp, dp, optlen);
- dp += optlen;
- }
- }
- for (optlen = dp - (u_char *)(jp+1); optlen & 0x3; optlen++)
- *dp++ = IPOPT_EOL;
- return (optlen);
-}
-
-/*
* IP socket option processing.
*/
int
@@ -1465,110 +1358,6 @@ ip_ctloutput(so, sopt)
}
/*
- * Set up IP options in pcb for insertion in output packets.
- * Store in mbuf with pointer in pcbopt, adding pseudo-option
- * with destination address if source routed.
- */
-static int
-ip_pcbopts(struct inpcb *inp, int optname, struct mbuf *m)
-{
- register int cnt, optlen;
- register u_char *cp;
- struct mbuf **pcbopt;
- u_char opt;
-
- INP_LOCK_ASSERT(inp);
-
- pcbopt = &inp->inp_options;
-
- /* turn off any old options */
- if (*pcbopt)
- (void)m_free(*pcbopt);
- *pcbopt = 0;
- if (m == NULL || m->m_len == 0) {
- /*
- * Only turning off any previous options.
- */
- if (m != NULL)
- (void)m_free(m);
- return (0);
- }
-
- if (m->m_len % sizeof(int32_t))
- goto bad;
- /*
- * IP first-hop destination address will be stored before
- * actual options; move other options back
- * and clear it when none present.
- */
- if (m->m_data + m->m_len + sizeof(struct in_addr) >= &m->m_dat[MLEN])
- goto bad;
- cnt = m->m_len;
- m->m_len += sizeof(struct in_addr);
- cp = mtod(m, u_char *) + sizeof(struct in_addr);
- bcopy(mtod(m, void *), cp, (unsigned)cnt);
- bzero(mtod(m, void *), sizeof(struct in_addr));
-
- for (; cnt > 0; cnt -= optlen, cp += optlen) {
- opt = cp[IPOPT_OPTVAL];
- if (opt == IPOPT_EOL)
- break;
- if (opt == IPOPT_NOP)
- optlen = 1;
- else {
- if (cnt < IPOPT_OLEN + sizeof(*cp))
- goto bad;
- optlen = cp[IPOPT_OLEN];
- if (optlen < IPOPT_OLEN + sizeof(*cp) || optlen > cnt)
- goto bad;
- }
- switch (opt) {
-
- default:
- break;
-
- case IPOPT_LSRR:
- case IPOPT_SSRR:
- /*
- * user process specifies route as:
- * ->A->B->C->D
- * D must be our final destination (but we can't
- * check that since we may not have connected yet).
- * A is first hop destination, which doesn't appear in
- * actual IP option, but is stored before the options.
- */
- if (optlen < IPOPT_MINOFF - 1 + sizeof(struct in_addr))
- goto bad;
- m->m_len -= sizeof(struct in_addr);
- cnt -= sizeof(struct in_addr);
- optlen -= sizeof(struct in_addr);
- cp[IPOPT_OLEN] = optlen;
- /*
- * Move first hop before start of options.
- */
- bcopy((caddr_t)&cp[IPOPT_OFFSET+1], mtod(m, caddr_t),
- sizeof(struct in_addr));
- /*
- * Then copy rest of options back
- * to close up the deleted entry.
- */
- bcopy((&cp[IPOPT_OFFSET+1] + sizeof(struct in_addr)),
- &cp[IPOPT_OFFSET+1],
- (unsigned)cnt - (IPOPT_MINOFF - 1));
- break;
- }
- }
- if (m->m_len > MAX_IPOPTLEN + sizeof(struct in_addr))
- goto bad;
- *pcbopt = m;
- return (0);
-
-bad:
- (void)m_free(m);
- return (EINVAL);
-}
-
-/*
* XXX
* The whole multicast option thing needs to be re-thought.
* Several of these options are equally applicable to non-multicast
OpenPOWER on IntegriCloud