|
|
1.1 root 1: /*
2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * The contents of this file constitute Original Code as defined in and
7: * are subject to the Apple Public Source License Version 1.1 (the
8: * "License"). You may not use this file except in compliance with the
9: * License. Please obtain a copy of the License at
10: * http://www.apple.com/publicsource and read it before using this file.
11: *
12: * This Original Code and all software distributed under the License are
13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17: * License for the specific language governing rights and limitations
18: * under the License.
19: *
20: * @APPLE_LICENSE_HEADER_END@
21: */
22: /*
23: * Copyright (c) 1998 Apple Computer, Inc.
24: */
25:
26: /* ddp_usrreq.c
27: */
28:
29: #include <sys/errno.h>
30: #include <sys/types.h>
31: #include <sys/param.h>
32: #include <machine/spl.h>
33: #include <sys/systm.h>
34: #include <sys/kernel.h>
35: #include <sys/proc.h>
36: #include <sys/filedesc.h>
37: #include <sys/fcntl.h>
38: #include <sys/mbuf.h>
39: #include <sys/ioctl.h>
40: #include <sys/malloc.h>
41: #include <sys/socket.h>
42: #include <sys/socketvar.h>
43: #include <sys/protosw.h>
44:
45: #include <net/if.h>
46:
47: #include <netat/appletalk.h>
48: #include <netat/at_var.h>
49: #include <netat/sysglue.h>
50: #include <netat/lap.h>
51: #include <netat/ddp.h>
52: #include <netat/ep.h>
53: #include <netat/rtmp.h>
54: #include <netat/zip.h>
55: #include <netat/at_pcb.h>
56: #include <netat/routing_tables.h>
57: #include <netat/nbp.h>
58:
59: extern int at_control(), at_memzone_init();
60: extern void nbp_input(), ep_input(), zip_router_input(),
61: sip_input(), add_ddp_handler(), init_ddp_handler(),
62: ddp_start(), appletalk_hack_start();
63:
64: extern int xpatcnt;
65:
66: struct atpcb ddp_head;
67: u_long ddp_sendspace = 600, /* *** what should this value be? *** */
68: ddp_recvspace = 50 * (600 + sizeof(struct sockaddr_at));
69:
70: int ddp_pru_control(struct socket *so, u_long cmd, caddr_t data,
71: struct ifnet *ifp, struct proc *p)
72: {
73: return(at_control(so, cmd, data, ifp));
74: }
75:
76:
77: int ddp_pru_attach(struct socket *so, int proto,
78: struct proc *p)
79: {
80: int s, error = 0;
81: at_ddp_t *ddp = NULL;
82: struct atpcb *pcb = (struct atpcb *)((so)->so_pcb);
83:
84: s = splnet();
85: error = at_pcballoc(so, &ddp_head);
86: splx(s);
87: if (error)
88: return error;
89: error = soreserve(so, ddp_sendspace, ddp_recvspace);
90: pcb = (struct atpcb *)((so)->so_pcb);
91: pcb->pid = current_proc()->p_pid;
92: pcb->ddptype = (u_char) proto; /* set in socreate() */
93:
94: /* *** to support at_ioctl() hack *** */
95: pcb->proto = (pcb->ddptype == DDP_ATP)? ATPROTO_ATP:
96: (pcb->ddptype == DDP_ADSP)? ATPROTO_ADSP:
97: ATPROTO_DDP;
98: ATEVENTINIT(pcb->iocevent);
99: /* *** end of hack *** */
100:
101: return error;
102: }
103:
104:
105: int ddp_pru_disconnect(struct socket *so)
106: {
107:
108: int s, error = 0;
109: at_ddp_t *ddp = NULL;
110: struct atpcb *pcb = (struct atpcb *)((so)->so_pcb);
111:
112: if (pcb == NULL)
113: return (EINVAL);
114:
115: if ((so->so_state & SS_ISCONNECTED) == 0)
116: return ENOTCONN;
117:
118: soisdisconnected(so);
119: s = splnet();
120: at_pcbdetach(pcb);
121: splx(s);
122:
123: return error;
124: }
125:
126:
127: int ddp_pru_abort(struct socket *so)
128: {
129: int s;
130: struct atpcb *pcb = (struct atpcb *)((so)->so_pcb);
131:
132: if (pcb == NULL)
133: return (EINVAL);
134:
135: soisdisconnected(so);
136: s = splnet();
137: at_pcbdetach(pcb);
138: splx(s);
139:
140: return 0;
141: }
142:
143: int ddp_pru_detach(struct socket *so)
144: {
145: int s;
146: struct atpcb *pcb = (struct atpcb *)((so)->so_pcb);
147:
148: if (pcb == NULL)
149: return (EINVAL);
150:
151: s = splnet();
152: at_pcbdetach(pcb);
153: splx(s);
154: return 0;
155: }
156:
157: int ddp_pru_shutdown(struct socket *so)
158: {
159: struct atpcb *pcb = (struct atpcb *)((so)->so_pcb);
160:
161: if (pcb == NULL)
162: return (EINVAL);
163:
164: socantsendmore(so);
165: return 0;
166: }
167:
168:
169: int ddp_pru_bind(struct socket *so, struct sockaddr *nam,
170: struct proc *p)
171: {
172: struct atpcb *pcb = (struct atpcb *)((so)->so_pcb);
173:
174: if (pcb == NULL)
175: return (EINVAL);
176:
177: return (at_pcbbind(pcb, nam));
178: }
179:
180:
181: int ddp_pru_send(struct socket *so, int flags, struct mbuf *m,
182: struct sockaddr *addr, struct mbuf *control,
183: struct proc *p)
184: {
185: int s, error = 0;
186: at_ddp_t *ddp = NULL;
187: struct atpcb *pcb = (struct atpcb *)((so)->so_pcb);
188:
189: if (pcb == NULL)
190: return (EINVAL);
191:
192: if (!(pcb->ddp_flags & DDPFLG_HDRINCL)) {
193: /* prepend a DDP header */
194: M_PREPEND(m, DDP_X_HDR_SIZE, M_WAIT);
195: ddp = mtod(m, at_ddp_t *);
196: }
197: if (so->so_state & SS_ISCONNECTED) {
198: if (addr)
199: return EISCONN;
200:
201: if (ddp) {
202: NET_ASSIGN(ddp->dst_net, pcb->raddr.s_net);
203: ddp->dst_node = pcb->raddr.s_node;
204: ddp->dst_socket = pcb->rport;
205: }
206: } else {
207: if (addr == NULL)
208: return ENOTCONN;
209:
210: if (ddp) {
211: struct sockaddr_at *dst =
212: (struct sockaddr_at *) addr;
213: NET_ASSIGN(ddp->dst_net, dst->sat_addr.s_net);
214: ddp->dst_node = dst->sat_addr.s_node;
215: ddp->dst_socket = dst->sat_port;
216: }
217: }
218: ddp->length = m->m_pkthdr.len;
219: UAS_ASSIGN(ddp->checksum, 0);
220: ddp->type = (pcb->ddptype)? pcb->ddptype: DEFAULT_OT_DDPTYPE;
221: #ifdef NOT_YET
222: NET_ASSIGN(ddp->src_net, pcb->laddr.s_net);
223: ddp->src_node = pcb->laddr.s_node;
224: ddp->src_socket = pcb->lport;
225: #endif
226: error = ddp_output(&m, pcb->lport, FALSE);
227: m = NULL;
228: return error;
229: }
230:
231: int ddp_pru_sockaddr(struct socket *so,
232: struct sockaddr **nam)
233: {
234: struct atpcb *pcb = (struct atpcb *)((so)->so_pcb);
235:
236: if (pcb == NULL)
237: return (EINVAL);
238:
239: at_setsockaddr(pcb, *nam);
240: return 0;
241: }
242:
243:
244: int ddp_pru_peeraddr(struct socket *so,
245: struct sockaddr **nam)
246: {
247: struct atpcb *pcb = (struct atpcb *)((so)->so_pcb);
248:
249: if (pcb == NULL)
250: return (EINVAL);
251:
252: at_setpeeraddr(pcb, *nam);
253: return 0;
254: }
255:
256:
257: int ddp_pru_connect(struct socket *so, struct sockaddr *nam,
258: struct proc *p)
259: {
260: struct atpcb *pcb = (struct atpcb *)((so)->so_pcb);
261: struct sockaddr_at *faddr = (struct sockaddr_at *) nam;
262:
263: if (pcb != NULL)
264: return (EINVAL);
265:
266: if (xpatcnt == 0)
267: return (EADDRNOTAVAIL);
268:
269: if (faddr->sat_family != AF_APPLETALK)
270: return (EAFNOSUPPORT);
271:
272: pcb->raddr = faddr->sat_addr;
273: soisconnected(so);
274: return 0;
275: }
276:
277:
278:
279: /*
280: * One-time AppleTalk initialization
281: */
282: void ddp_init()
283: {
284: at_memzone_init();
285: ddp_head.atpcb_next = ddp_head.atpcb_prev = &ddp_head;
286: init_ddp_handler();
287:
288: /* Initialize protocols implemented in the kernel */
289: add_ddp_handler(EP_SOCKET, ep_input);
290: add_ddp_handler(ZIP_SOCKET, zip_router_input);
291: add_ddp_handler(NBP_SOCKET, nbp_input);
292: add_ddp_handler(DDP_SOCKET_1st_DYNAMIC, sip_input);
293:
294: ddp_start();
295:
296: appletalk_hack_start();
297: } /* ddp_init */
298:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.