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