|
|
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.