date and time created 82/12/16 14:38:25 by sam
[unix-history] / usr / src / sys / netinet / raw_ip.c
CommitLineData
cce93e4b 1/* raw_ip.c 4.16 82/12/14 */
2a598b25
BJ
2
3#include "../h/param.h"
4#include "../h/mbuf.h"
5#include "../h/socket.h"
94a62155 6#include "../h/protosw.h"
2a598b25 7#include "../h/socketvar.h"
126472ab 8#include "../net/if.h"
fcfe450e
BJ
9#include "../netinet/in.h"
10#include "../netinet/in_systm.h"
11#include "../netinet/ip.h"
12#include "../netinet/ip_var.h"
94a62155 13#include "../net/raw_cb.h"
a13c006d 14#include "../net/route.h"
126472ab 15#include <errno.h>
2a598b25
BJ
16
17/*
94a62155
BJ
18 * Raw interface to IP protocol.
19 */
20
ee787340
SL
21static struct sockaddr_in ripdst = { AF_INET };
22static struct sockaddr_in ripsrc = { AF_INET };
23static struct sockproto ripproto = { PF_INET };
94a62155
BJ
24/*
25 * Setup generic address and protocol structures
26 * for raw_input routine, then pass them along with
27 * mbuf chain.
2a598b25 28 */
2a598b25
BJ
29rip_input(m)
30 struct mbuf *m;
31{
94a62155 32 register struct ip *ip = mtod(m, struct ip *);
2a598b25 33
94a62155 34 ripproto.sp_protocol = ip->ip_p;
faad37c0
SL
35 ripdst.sin_addr = ip->ip_dst;
36 ripsrc.sin_addr = ip->ip_src;
02122dcc
SL
37 raw_input(m, &ripproto, (struct sockaddr *)&ripsrc,
38 (struct sockaddr *)&ripdst);
2a598b25
BJ
39}
40
94a62155
BJ
41/*
42 * Generate IP header and pass packet to ip_output.
43 * Tack on options user may have setup with control call.
44 */
45rip_output(m0, so)
46 struct mbuf *m0;
47 struct socket *so;
2a598b25 48{
94a62155
BJ
49 register struct mbuf *m;
50 register struct ip *ip;
126472ab
SL
51 int len = 0, error;
52 struct rawcb *rp = sotorawcb(so);
a13c006d 53 struct sockaddr_in *sin;
2a598b25 54
94a62155
BJ
55 /*
56 * Calculate data length and get an mbuf
57 * for IP header.
58 */
59 for (m = m0; m; m = m->m_next)
60 len += m->m_len;
cce93e4b 61 m = m_get(M_DONTWAIT, MT_HEADER);
94a62155 62 if (m == 0) {
126472ab
SL
63 error = ENOBUFS;
64 goto bad;
94a62155
BJ
65 }
66
67 /*
68 * Fill in IP header as needed.
69 */
70 m->m_off = MMAXOFF - sizeof(struct ip);
71 m->m_len = sizeof(struct ip);
72 m->m_next = m0;
73 ip = mtod(m, struct ip *);
74 ip->ip_p = so->so_proto->pr_protocol;
75 ip->ip_len = sizeof(struct ip) + len;
a13c006d
BJ
76 if (rp->rcb_flags & RAW_LADDR) {
77 sin = (struct sockaddr_in *)&rp->rcb_laddr;
78 if (sin->sin_family != AF_INET) {
126472ab
SL
79 error = EAFNOSUPPORT;
80 goto bad;
81 }
a13c006d
BJ
82 ip->ip_src.s_addr = sin->sin_addr.s_addr;
83 } else
84 ip->ip_src.s_addr = 0;
85 ip->ip_dst = ((struct sockaddr_in *)&rp->rcb_faddr)->sin_addr;
94a62155 86 ip->ip_ttl = MAXTTL;
a13c006d 87 return (ip_output(m, (struct mbuf *)0, &routetoif, 1));
126472ab
SL
88bad:
89 m_freem(m);
90 return (error);
2a598b25 91}