fixes for range locking
[unix-history] / usr / src / sys / deprecated / bbnnet / ip_usrreq.c
CommitLineData
17efd7fe
MK
1/**************************************************************************/
2/* */
3/* miscellaneous ip routines */
4/* */
5/**************************************************************************/
6
7
8#include "../h/param.h"
9#include "../h/mbuf.h"
10#include "../h/protosw.h"
11#include "../h/socket.h"
12#include "../h/socketvar.h"
13#include "../h/errno.h"
14
15#include "../net/if.h"
16#include "../net/route.h"
17#include "../net/af.h"
18#include "../net/netisr.h"
19
20#include "../vax/mtpr.h"
21
22#include "../bbnnet/in.h"
23#include "../bbnnet/in_var.h"
24#include "../bbnnet/net.h"
25#include "../bbnnet/in_pcb.h"
26#include "../bbnnet/fsm.h"
27#include "../bbnnet/ip.h"
28#include "../bbnnet/icmp.h"
29
30
31ip_ioctl (inp, command, data)
32struct inpcb *inp;
33int command;
34caddr_t data;
35{
36 /* no IP ioctls */
37 return in_ioctl (command, data);
38}
39
40ip_ctloutput(req, so, level, optname, optval)
41int req;
42struct socket *so;
43int level, optname;
44struct mbuf **optval;
45{
46 struct inpcb *inp;
47
48 /*
49 * O.K., with the berkeley method of using the protocol number for the level,
50 * what magic cookie should we use to distinguish between IP and the interfaces?
51 */
52 inp = sotoinpcb(so);
53
54 switch(req)
55 {
56 case PRCO_GETOPT:
57 return(ip_getopt(inp,optname,optval));
58
59 case PRCO_SETOPT:
60 return(ip_setopt(inp,optname,optval));
61
62 default:
63 panic("ip_ctloutput");
64 }
65 /*NOTREACHED*/
66}
67
68ip_setopt (inpcb, command, data)
69struct inpcb *inpcb;
70struct mbuf **data;
71{
72 register int error = 0;
73 register struct mbuf *m = *data;
74
75 switch (command)
76 {
77 case SO_IPROUTE:
78 /* this probably breaks!! */
79 if (m->m_len == 0)
80 {
81 /* turns off use of options */
82 inpcb->inp_optlen = 0;
83 break;
84 }
85 if ((m->m_len < (2 * sizeof(struct in_addr))) ||
86 (m->m_len > (MAX_IPOPTLEN - sizeof(struct in_addr))) ||
87 (m->m_len % sizeof(struct in_addr)))
88 {
89 error = EINVAL;
90 break;
91 }
92 /*
93 * O.K., user process specifies it as:
94 * ->A->B->C->D
95 * D must be our final destination (but we can't
96 * check that since we haven't connected yet).
97 * Convert this into a form for ip_output.
98 */
99 inpcb->inp_optlen = m->m_len;
100 bcopy (mtod(m, caddr_t), inpcb->inp_options, (unsigned)m->m_len);
101
102 /*
103 * Following could be moved to ip_send(), but let's
104 * do it once for efficiency even though user may
105 * retrieve different from what stored.
106 */
107 {
108 char *p;
109 struct in_addr *ipa;
110
111 p = inpcb->inp_options;
112 ipa = (struct in_addr *) p;
113 ipa[m->m_len / sizeof(struct in_addr)] = ipa[0];
114 p[0] = IP_NOP_OPT;
115 p[1] = IP_LRTE_OPT;
116 p[2] = m->m_len -1;
117 p[3] = 4; /* offset: counting one based */
118 }
119 /*
120 * Now we have a correct IP source route recorded,
121 * and the first hop comes after the source route.
122 */
123 break;
124 default:
125 error = EINVAL;
126 }
127
128 /* they can futz with m */
129 if (*data)
130 m_freem(*data);
131
132 return (error);
133}
134
135ip_getopt (inpcb, command, data)
136struct inpcb *inpcb;
137struct mbuf **data;
138{
139 register error = 0;
140 register struct mbuf *m = NULL;
141
142 *data = NULL; /* o.k. (no data sent on getsockopt) */
143
144 switch (command)
145 {
146 case SO_IPROUTE:
147 if (!inpcb->inp_optlen)
148 break;
149
150 m = m_get(M_WAIT, MT_SOOPTS);
151
152 if (m == 0)
153 return(ENOBUFS);
154
155 m->m_len = inpcb->inp_optlen;
156
157 bcopy (inpcb->inp_options, mtod(m, caddr_t), (unsigned)m->m_len);
158 break;
159
160 default:
161 error = EINVAL;
162 }
163 *data = m;
164 return (error);
165}
166
167u_char inetctlerrmap[PRC_NCMDS] =
168{
169 ENETUNREACH, /* PRC_IFDOWN: connection oriented protocols use
170 * interface with their local address. Can't re-route.
171 */
172
173 ECONNABORTED, 0, 0,
174 0, 0, EHOSTDOWN, EHOSTUNREACH,
175 ENETUNREACH, EHOSTUNREACH, ECONNREFUSED, ECONNREFUSED,
176 EMSGSIZE, 0, 0, 0,
177 0, 0, 0, 0
178} ;