Handle Reverse-Path in some reasonable way. You must put the 'X'
[unix-history] / usr / src / sys / net / raw_cb.c
CommitLineData
14fa60f2 1/* raw_cb.c 4.12 82/10/09 */
785d93ac
BJ
2
3#include "../h/param.h"
4#include "../h/systm.h"
5#include "../h/mbuf.h"
6#include "../h/socket.h"
7#include "../h/socketvar.h"
8#include "../h/mtpr.h"
785d93ac
BJ
9#include "../net/if.h"
10#include "../net/raw_cb.h"
c47a5909 11#include <errno.h>
785d93ac
BJ
12
13/*
14 * Routines to manage the raw protocol control blocks.
15 *
16 * TODO:
17 * hash lookups by protocol family/protocol + address family
ee787340 18 * take care of unique address problems per AF?
1e25d807 19 * redo address binding to allow wildcards
785d93ac
BJ
20 */
21
22/*
23 * Allocate a control block and a nominal amount
24 * of buffer space for the socket.
25 */
14fa60f2 26raw_attach(so)
785d93ac 27 register struct socket *so;
785d93ac
BJ
28{
29 struct mbuf *m;
30 register struct rawcb *rp;
785d93ac 31
785d93ac
BJ
32 m = m_getclr(M_DONTWAIT);
33 if (m == 0)
34 return (ENOBUFS);
35 if (sbreserve(&so->so_snd, RAWSNDQ) == 0)
36 goto bad;
37 if (sbreserve(&so->so_rcv, RAWRCVQ) == 0)
38 goto bad2;
39 rp = mtod(m, struct rawcb *);
40 rp->rcb_socket = so;
41 insque(rp, &rawcb);
42 so->so_pcb = (caddr_t)rp;
43 rp->rcb_pcb = 0;
785d93ac
BJ
44 return (0);
45bad2:
46 sbrelease(&so->so_snd);
47bad:
48 (void) m_free(m);
49 return (ENOBUFS);
50}
51
52/*
53 * Detach the raw connection block and discard
54 * socket resources.
55 */
56raw_detach(rp)
57 register struct rawcb *rp;
58{
59 struct socket *so = rp->rcb_socket;
60
785d93ac
BJ
61 so->so_pcb = 0;
62 sofree(so);
63 remque(rp);
ee787340 64 (void) m_freem(dtom(rp));
785d93ac
BJ
65}
66
67/*
68 * Disconnect and possibly release resources.
69 */
70raw_disconnect(rp)
71 struct rawcb *rp;
72{
126472ab 73 rp->rcb_flags &= ~RAW_FADDR;
f832270b 74 if (rp->rcb_socket->so_state & SS_NOFDREF)
785d93ac
BJ
75 raw_detach(rp);
76}
77
14fa60f2
BJ
78raw_bind(so, nam)
79 register struct socket *so;
80 struct mbuf *nam;
81{
82 struct sockaddr *addr = mtod(nam, struct sockaddr *);
83 struct mbuf *m;
84 register struct rawcb *rp;
85
86 if (ifnet == 0)
87 return (EADDRNOTAVAIL);
88{
89#include "../netinet/in.h"
90#include "../netinet/in_systm.h"
91/* BEGIN DUBIOUS */
92 /*
93 * Should we verify address not already in use?
94 * Some say yes, others no.
95 */
96 switch (addr->sa_family) {
97
98 case AF_IMPLINK:
99 case AF_INET:
100 if (((struct sockaddr_in *)addr)->sin_addr.s_addr &&
101 if_ifwithaddr(addr) == 0)
102 return (EADDRNOTAVAIL);
103 break;
104
105#ifdef PUP
106 /*
107 * Curious, we convert PUP address format to internet
108 * to allow us to verify we're asking for an Ethernet
109 * interface. This is wrong, but things are heavily
110 * oriented towards the internet addressing scheme, and
111 * converting internet to PUP would be very expensive.
112 */
113 case AF_PUP: {
114#include "../netpup/pup.h"
115 struct sockaddr_pup *spup = (struct sockaddr_pup *)addr;
116 struct sockaddr_in inpup;
117
118 bzero((caddr_t)&inpup, sizeof(inpup));
119 inpup.sin_family = AF_INET;
120 inpup.sin_addr.s_net = spup->sp_net;
121 inpup.sin_addr.s_impno = spup->sp_host;
122 if (inpup.sin_addr.s_addr &&
123 if_ifwithaddr((struct sockaddr *)&inpup) == 0)
124 return (EADDRNOTAVAIL);
125 break;
126 }
127#endif
128
129 default:
130 return (EAFNOSUPPORT);
131 }
132}
133/* END DUBIOUS */
134 bcopy((caddr_t)addr, (caddr_t)&rp->rcb_laddr, sizeof (*addr));
135 rp->rcb_flags |= RAW_LADDR;
136 return (0);
137}
138
785d93ac
BJ
139/*
140 * Associate a peer's address with a
141 * raw connection block.
142 */
14fa60f2 143raw_connaddr(rp, nam)
785d93ac 144 struct rawcb *rp;
14fa60f2 145 struct mbuf *nam;
785d93ac 146{
14fa60f2
BJ
147 struct sockaddr *addr = mtod(nam, struct sockaddr *);
148
126472ab
SL
149 bcopy((caddr_t)addr, (caddr_t)&rp->rcb_faddr, sizeof(*addr));
150 rp->rcb_flags |= RAW_FADDR;
785d93ac 151}