1: /*
2: * Copyright (c) 1982, 1986 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: *
6: * @(#)raw_ip.c 7.1 (Berkeley) 6/5/86
7: */
8:
9: #include "param.h"
10: #include "mbuf.h"
11: #include "socket.h"
12: #include "protosw.h"
13: #include "socketvar.h"
14: #include "errno.h"
15:
16: #include "../net/if.h"
17: #include "../net/route.h"
18: #include "../net/raw_cb.h"
19:
20: #include "in.h"
21: #include "in_systm.h"
22: #include "ip.h"
23: #include "ip_var.h"
24:
25: /*
26: * Raw interface to IP protocol.
27: */
28:
29: struct sockaddr_in ripdst = { AF_INET };
30: struct sockaddr_in ripsrc = { AF_INET };
31: struct sockproto ripproto = { PF_INET };
32: /*
33: * Setup generic address and protocol structures
34: * for raw_input routine, then pass them along with
35: * mbuf chain.
36: */
37: rip_input(m)
38: struct mbuf *m;
39: {
40: register struct ip *ip = mtod(m, struct ip *);
41:
42: ripproto.sp_protocol = ip->ip_p;
43: ripdst.sin_addr = ip->ip_dst;
44: ripsrc.sin_addr = ip->ip_src;
45: raw_input(m, &ripproto, (struct sockaddr *)&ripsrc,
46: (struct sockaddr *)&ripdst);
47: }
48:
49: /*
50: * Generate IP header and pass packet to ip_output.
51: * Tack on options user may have setup with control call.
52: */
53: rip_output(m0, so)
54: struct mbuf *m0;
55: struct socket *so;
56: {
57: register struct mbuf *m;
58: register struct ip *ip;
59: int len = 0, error;
60: struct rawcb *rp = sotorawcb(so);
61: struct sockaddr_in *sin;
62:
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;
69: m = m_get(M_DONTWAIT, MT_HEADER);
70: if (m == 0) {
71: error = ENOBUFS;
72: goto bad;
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 *);
82: ip->ip_tos = 0;
83: ip->ip_off = 0;
84: ip->ip_p = rp->rcb_proto.sp_protocol;
85: ip->ip_len = sizeof(struct ip) + len;
86: if (rp->rcb_flags & RAW_LADDR) {
87: sin = (struct sockaddr_in *)&rp->rcb_laddr;
88: if (sin->sin_family != AF_INET) {
89: error = EAFNOSUPPORT;
90: goto bad;
91: }
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;
96: ip->ip_ttl = MAXTTL;
97: return (ip_output(m, rp->rcb_options, &rp->rcb_route,
98: (so->so_options & SO_DONTROUTE) | IP_ALLOWBROADCAST));
99: bad:
100: m_freem(m);
101: return (error);
102: }
103:
104: /*
105: * Raw IP socket option processing.
106: */
107: rip_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),
139: mtod(*m, caddr_t), (unsigned)(*m)->m_len);
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)
150: (void)m_free(*m);
151: return (error);
152: }
Defined functions
Defined variables