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