add patchable udp ttl
[unix-history] / usr / src / sys / netinet / raw_ip.c
CommitLineData
8ae0e4b4 1/*
0880b18e 2 * Copyright (c) 1982, 1986 Regents of the University of California.
8ae0e4b4
KM
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 *
0880b18e 6 * @(#)raw_ip.c 7.1 (Berkeley) %G%
8ae0e4b4 7 */
2a598b25 8
20666ad3
JB
9#include "param.h"
10#include "mbuf.h"
11#include "socket.h"
12#include "protosw.h"
13#include "socketvar.h"
14#include "errno.h"
f4d55810 15
126472ab 16#include "../net/if.h"
f4d55810 17#include "../net/route.h"
48c8199a 18#include "../net/raw_cb.h"
f4d55810 19
20666ad3
JB
20#include "in.h"
21#include "in_systm.h"
22#include "ip.h"
23#include "ip_var.h"
2a598b25
BJ
24
25/*
94a62155
BJ
26 * Raw interface to IP protocol.
27 */
28
48c8199a
SL
29struct sockaddr_in ripdst = { AF_INET };
30struct sockaddr_in ripsrc = { AF_INET };
31struct sockproto ripproto = { PF_INET };
94a62155
BJ
32/*
33 * Setup generic address and protocol structures
34 * for raw_input routine, then pass them along with
35 * mbuf chain.
2a598b25 36 */
2a598b25
BJ
37rip_input(m)
38 struct mbuf *m;
39{
94a62155 40 register struct ip *ip = mtod(m, struct ip *);
2a598b25 41
94a62155 42 ripproto.sp_protocol = ip->ip_p;
faad37c0
SL
43 ripdst.sin_addr = ip->ip_dst;
44 ripsrc.sin_addr = ip->ip_src;
02122dcc
SL
45 raw_input(m, &ripproto, (struct sockaddr *)&ripsrc,
46 (struct sockaddr *)&ripdst);
2a598b25
BJ
47}
48
94a62155
BJ
49/*
50 * Generate IP header and pass packet to ip_output.
51 * Tack on options user may have setup with control call.
52 */
53rip_output(m0, so)
54 struct mbuf *m0;
55 struct socket *so;
2a598b25 56{
94a62155
BJ
57 register struct mbuf *m;
58 register struct ip *ip;
126472ab
SL
59 int len = 0, error;
60 struct rawcb *rp = sotorawcb(so);
a13c006d 61 struct sockaddr_in *sin;
2a598b25 62
94a62155
BJ
63 /*
64 * Calculate data length and get an mbuf
65 * for IP header.
66 */
67 for (m = m0; m; m = m->m_next)
68 len += m->m_len;
cce93e4b 69 m = m_get(M_DONTWAIT, MT_HEADER);
94a62155 70 if (m == 0) {
126472ab
SL
71 error = ENOBUFS;
72 goto bad;
94a62155
BJ
73 }
74
75 /*
76 * Fill in IP header as needed.
77 */
78 m->m_off = MMAXOFF - sizeof(struct ip);
79 m->m_len = sizeof(struct ip);
80 m->m_next = m0;
81 ip = mtod(m, struct ip *);
a8e2e674 82 ip->ip_tos = 0;
d5645656 83 ip->ip_off = 0;
f7c8d7b9 84 ip->ip_p = rp->rcb_proto.sp_protocol;
94a62155 85 ip->ip_len = sizeof(struct ip) + len;
a13c006d
BJ
86 if (rp->rcb_flags & RAW_LADDR) {
87 sin = (struct sockaddr_in *)&rp->rcb_laddr;
88 if (sin->sin_family != AF_INET) {
126472ab
SL
89 error = EAFNOSUPPORT;
90 goto bad;
91 }
a13c006d
BJ
92 ip->ip_src.s_addr = sin->sin_addr.s_addr;
93 } else
94 ip->ip_src.s_addr = 0;
95 ip->ip_dst = ((struct sockaddr_in *)&rp->rcb_faddr)->sin_addr;
94a62155 96 ip->ip_ttl = MAXTTL;
b197d52e
MK
97 return (ip_output(m, rp->rcb_options, &rp->rcb_route,
98 (so->so_options & SO_DONTROUTE) | IP_ALLOWBROADCAST));
126472ab
SL
99bad:
100 m_freem(m);
101 return (error);
2a598b25 102}
b197d52e
MK
103
104/*
105 * Raw IP socket option processing.
106 */
107rip_ctloutput(op, so, level, optname, m)
108 int op;
109 struct socket *so;
110 int level, optname;
111 struct mbuf **m;
112{
113 int error = 0;
114 register struct rawcb *rp = sotorawcb(so);
115
116 if (level != IPPROTO_IP)
117 error = EINVAL;
118 else switch (op) {
119
120 case PRCO_SETOPT:
121 switch (optname) {
122 case IP_OPTIONS:
123 return (ip_pcbopts(&rp->rcb_options, *m));
124
125 default:
126 error = EINVAL;
127 break;
128 }
129 break;
130
131 case PRCO_GETOPT:
132 switch (optname) {
133 case IP_OPTIONS:
134 *m = m_get(M_WAIT, MT_SOOPTS);
135 if (rp->rcb_options) {
136 (*m)->m_off = rp->rcb_options->m_off;
137 (*m)->m_len = rp->rcb_options->m_len;
138 bcopy(mtod(rp->rcb_options, caddr_t),
8011f5df 139 mtod(*m, caddr_t), (unsigned)(*m)->m_len);
b197d52e
MK
140 } else
141 (*m)->m_len = 0;
142 break;
143 default:
144 error = EINVAL;
145 break;
146 }
147 break;
148 }
149 if (op == PRCO_SETOPT)
8011f5df 150 (void)m_free(*m);
b197d52e
MK
151 return (error);
152}