* Copyright (c) 1982, 1986 Regents of the University of California.
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and that due credit is given
* to the University of California at Berkeley. The name of the University
* may not be used to endorse or promote products derived from this
* software without specific prior written permission. This software
* is provided ``as is'' without express or implied warranty.
* @(#)raw_ip.c 7.3 (Berkeley) %G%
#include "../net/route.h"
#include "../net/raw_cb.h"
* Raw interface to IP protocol.
struct sockaddr_in ripdst
= { AF_INET
};
struct sockaddr_in ripsrc
= { AF_INET
};
struct sockproto ripproto
= { PF_INET
};
* Setup generic address and protocol structures
* for raw_input routine, then pass them along with
register struct ip
*ip
= mtod(m
, struct ip
*);
ripproto
.sp_protocol
= ip
->ip_p
;
ripdst
.sin_addr
= ip
->ip_dst
;
ripsrc
.sin_addr
= ip
->ip_src
;
raw_input(m
, &ripproto
, (struct sockaddr
*)&ripsrc
,
(struct sockaddr
*)&ripdst
);
* Generate IP header and pass packet to ip_output.
* Tack on options user may have setup with control call.
struct rawcb
*rp
= sotorawcb(so
);
* Calculate data length and get an mbuf
for (m
= m0
; m
; m
= m
->m_next
)
m
= m_get(M_DONTWAIT
, MT_HEADER
);
* Fill in IP header as needed.
m
->m_off
= MMAXOFF
- sizeof(struct ip
);
m
->m_len
= sizeof(struct ip
);
ip
= mtod(m
, struct ip
*);
ip
->ip_p
= rp
->rcb_proto
.sp_protocol
;
ip
->ip_len
= sizeof(struct ip
) + len
;
if (rp
->rcb_flags
& RAW_LADDR
) {
sin
= (struct sockaddr_in
*)&rp
->rcb_laddr
;
if (sin
->sin_family
!= AF_INET
) {
ip
->ip_src
.s_addr
= sin
->sin_addr
.s_addr
;
ip
->ip_dst
= ((struct sockaddr_in
*)&rp
->rcb_faddr
)->sin_addr
;
return (ip_output(m
, rp
->rcb_options
, &rp
->rcb_route
,
(so
->so_options
& SO_DONTROUTE
) | IP_ALLOWBROADCAST
));
* Raw IP socket option processing.
rip_ctloutput(op
, so
, level
, optname
, m
)
register struct rawcb
*rp
= sotorawcb(so
);
return (ip_pcbopts(&rp
->rcb_options
, *m
));
*m
= m_get(M_WAIT
, MT_SOOPTS
);
(*m
)->m_off
= rp
->rcb_options
->m_off
;
(*m
)->m_len
= rp
->rcb_options
->m_len
;
bcopy(mtod(rp
->rcb_options
, caddr_t
),
mtod(*m
, caddr_t
), (unsigned)(*m
)->m_len
);
if (op
== PRCO_SETOPT
&& *m
)