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