ddp_usrreq.c revision 127288
1214455Srpaulo/* 2214455Srpaulo * Copyright (c) 1990,1994 Regents of The University of Michigan. 3214455Srpaulo * All Rights Reserved. See COPYRIGHT. 4214455Srpaulo * 5214455Srpaulo * $FreeBSD: head/sys/netatalk/ddp_usrreq.c 127288 2004-03-22 03:24:10Z rwatson $ 6214455Srpaulo */ 7214455Srpaulo 8214455Srpaulo#include <sys/param.h> 9214455Srpaulo#include <sys/systm.h> 10214455Srpaulo#include <sys/malloc.h> 11214455Srpaulo#include <sys/mbuf.h> 12214455Srpaulo#include <sys/socket.h> 13214455Srpaulo#include <sys/socketvar.h> 14214455Srpaulo#include <sys/protosw.h> 15214455Srpaulo#include <net/if.h> 16214455Srpaulo#include <net/route.h> 17214455Srpaulo#include <net/netisr.h> 18214455Srpaulo 19214455Srpaulo#include <netatalk/at.h> 20214455Srpaulo#include <netatalk/at_var.h> 21214455Srpaulo#include <netatalk/ddp_var.h> 22214455Srpaulo#include <netatalk/ddp_pcb.h> 23214455Srpaulo#include <netatalk/at_extern.h> 24214455Srpaulo 25214455Srpaulostatic u_long ddp_sendspace = DDP_MAXSZ; /* Max ddp size + 1 (ddp_type) */ 26214455Srpaulostatic u_long ddp_recvspace = 10 * (587 + sizeof(struct sockaddr_at)); 27214455Srpaulo 28214455Srpaulostatic struct ifqueue atintrq1, atintrq2, aarpintrq; 29214455Srpaulo 30214455Srpaulostatic int 31214455Srpauloddp_attach(struct socket *so, int proto, struct thread *td) 32214455Srpaulo{ 33214455Srpaulo struct ddpcb *ddp; 34214455Srpaulo int error = 0; 35214455Srpaulo int s; 36214455Srpaulo 37214455Srpaulo 38214455Srpaulo ddp = sotoddpcb(so); 39214455Srpaulo if (ddp != NULL) { 40214455Srpaulo return (EINVAL); 41214455Srpaulo } 42214455Srpaulo 43214455Srpaulo s = splnet(); 44214455Srpaulo error = at_pcballoc(so); 45214455Srpaulo splx(s); 46214455Srpaulo if (error) { 47214455Srpaulo return (error); 48214455Srpaulo } 49214455Srpaulo return (soreserve(so, ddp_sendspace, ddp_recvspace)); 50214455Srpaulo} 51214455Srpaulo 52214455Srpaulostatic int 53214455Srpauloddp_detach(struct socket *so) 54214455Srpaulo{ 55214455Srpaulo struct ddpcb *ddp; 56214455Srpaulo int s; 57214455Srpaulo 58214455Srpaulo ddp = sotoddpcb(so); 59214455Srpaulo if (ddp == NULL) { 60214455Srpaulo return (EINVAL); 61214455Srpaulo } 62214455Srpaulo s = splnet(); 63214455Srpaulo at_pcbdetach(so, ddp); 64214455Srpaulo splx(s); 65214455Srpaulo return (0); 66214455Srpaulo} 67214455Srpaulo 68214455Srpaulostatic int 69214455Srpauloddp_bind(struct socket *so, struct sockaddr *nam, struct thread *td) 70214455Srpaulo{ 71214455Srpaulo struct ddpcb *ddp; 72214455Srpaulo int error = 0; 73214455Srpaulo int s; 74214455Srpaulo 75214455Srpaulo ddp = sotoddpcb(so); 76214455Srpaulo if (ddp == NULL) { 77214455Srpaulo return (EINVAL); 78214455Srpaulo } 79214455Srpaulo s = splnet(); 80214455Srpaulo error = at_pcbsetaddr(ddp, nam, td); 81214455Srpaulo splx(s); 82214455Srpaulo return (error); 83214455Srpaulo} 84214455Srpaulo 85214455Srpaulostatic int 86214455Srpauloddp_connect(struct socket *so, struct sockaddr *nam, struct thread *td) 87214455Srpaulo{ 88214455Srpaulo struct ddpcb *ddp; 89214455Srpaulo int error = 0; 90214455Srpaulo int s; 91214455Srpaulo 92214455Srpaulo ddp = sotoddpcb(so); 93214455Srpaulo if (ddp == NULL) { 94214455Srpaulo return (EINVAL); 95214455Srpaulo } 96214455Srpaulo 97214455Srpaulo if (ddp->ddp_fsat.sat_port != ATADDR_ANYPORT) { 98214455Srpaulo return (EISCONN); 99214455Srpaulo } 100214455Srpaulo 101214455Srpaulo s = splnet(); 102214455Srpaulo error = at_pcbconnect(ddp, nam, td); 103214455Srpaulo splx(s); 104214455Srpaulo if (error == 0) 105214455Srpaulo soisconnected(so); 106214455Srpaulo return (error); 107214455Srpaulo} 108214455Srpaulo 109214455Srpaulostatic int 110214455Srpauloddp_disconnect(struct socket *so) 111214455Srpaulo{ 112214455Srpaulo 113214455Srpaulo struct ddpcb *ddp; 114214455Srpaulo int s; 115214455Srpaulo 116214455Srpaulo ddp = sotoddpcb(so); 117214455Srpaulo if (ddp == NULL) { 118214455Srpaulo return (EINVAL); 119214455Srpaulo } 120214455Srpaulo if (ddp->ddp_fsat.sat_addr.s_node == ATADDR_ANYNODE) { 121214455Srpaulo return (ENOTCONN); 122214455Srpaulo } 123214455Srpaulo 124214455Srpaulo s = splnet(); 125214455Srpaulo at_pcbdisconnect(ddp); 126214455Srpaulo ddp->ddp_fsat.sat_addr.s_node = ATADDR_ANYNODE; 127214455Srpaulo splx(s); 128214455Srpaulo soisdisconnected(so); 129214455Srpaulo return (0); 130214455Srpaulo} 131214455Srpaulo 132214455Srpaulostatic int 133214455Srpauloddp_shutdown(struct socket *so) 134214455Srpaulo{ 135214455Srpaulo struct ddpcb *ddp; 136214455Srpaulo 137214455Srpaulo ddp = sotoddpcb(so); 138214455Srpaulo if (ddp == NULL) { 139214455Srpaulo return (EINVAL); 140214455Srpaulo } 141214455Srpaulo socantsendmore(so); 142214455Srpaulo return (0); 143214455Srpaulo} 144214455Srpaulo 145214455Srpaulostatic int 146214455Srpauloddp_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, 147214455Srpaulo struct mbuf *control, struct thread *td) 148214455Srpaulo{ 149214455Srpaulo struct ddpcb *ddp; 150214455Srpaulo int error = 0; 151214455Srpaulo int s; 152214455Srpaulo 153214455Srpaulo ddp = sotoddpcb(so); 154214455Srpaulo if (ddp == NULL) { 155214455Srpaulo return (EINVAL); 156214455Srpaulo } 157214455Srpaulo 158214455Srpaulo if (control && control->m_len) { 159214455Srpaulo return (EINVAL); 160214455Srpaulo } 161214455Srpaulo 162214455Srpaulo if (addr) { 163214455Srpaulo if (ddp->ddp_fsat.sat_port != ATADDR_ANYPORT) { 164214455Srpaulo return (EISCONN); 165214455Srpaulo } 166214455Srpaulo 167214455Srpaulo s = splnet(); 168214455Srpaulo error = at_pcbconnect(ddp, addr, td); 169214455Srpaulo splx(s); 170214455Srpaulo if (error) { 171214455Srpaulo return (error); 172214455Srpaulo } 173214455Srpaulo } else { 174214455Srpaulo if (ddp->ddp_fsat.sat_port == ATADDR_ANYPORT) { 175214455Srpaulo return (ENOTCONN); 176214455Srpaulo } 177214455Srpaulo } 178214455Srpaulo 179214455Srpaulo s = splnet(); 180214455Srpaulo error = ddp_output(m, so); 181214455Srpaulo if (addr) { 182214455Srpaulo at_pcbdisconnect(ddp); 183214455Srpaulo } 184214455Srpaulo splx(s); 185214455Srpaulo return (error); 186214455Srpaulo} 187214455Srpaulo 188214455Srpaulostatic int 189214455Srpauloddp_abort(struct socket *so) 190214455Srpaulo{ 191214455Srpaulo struct ddpcb *ddp; 192214455Srpaulo int s; 193214455Srpaulo 194214455Srpaulo ddp = sotoddpcb(so); 195214455Srpaulo if (ddp == NULL) { 196214455Srpaulo return (EINVAL); 197214455Srpaulo } 198214455Srpaulo soisdisconnected(so); 199214455Srpaulo s = splnet(); 200214455Srpaulo at_pcbdetach(so, ddp); 201214455Srpaulo splx(s); 202214455Srpaulo return (0); 203214455Srpaulo} 204214455Srpaulo 205214455Srpaulovoid 206214455Srpauloddp_init(void) 207214455Srpaulo{ 208214455Srpaulo 209214455Srpaulo atintrq1.ifq_maxlen = IFQ_MAXLEN; 210214455Srpaulo atintrq2.ifq_maxlen = IFQ_MAXLEN; 211214455Srpaulo aarpintrq.ifq_maxlen = IFQ_MAXLEN; 212214455Srpaulo mtx_init(&atintrq1.ifq_mtx, "at1_inq", NULL, MTX_DEF); 213214455Srpaulo mtx_init(&atintrq2.ifq_mtx, "at2_inq", NULL, MTX_DEF); 214214455Srpaulo mtx_init(&aarpintrq.ifq_mtx, "aarp_inq", NULL, MTX_DEF); 215214455Srpaulo netisr_register(NETISR_ATALK1, at1intr, &atintrq1, 0); 216214455Srpaulo netisr_register(NETISR_ATALK2, at2intr, &atintrq2, 0); 217214455Srpaulo netisr_register(NETISR_AARP, aarpintr, &aarpintrq, 0); 218214455Srpaulo} 219214455Srpaulo 220214455Srpaulo#if 0 221214455Srpaulostatic void 222214455Srpauloddp_clean(void) 223214455Srpaulo{ 224214455Srpaulo struct ddpcb *ddp; 225214455Srpaulo 226214455Srpaulo for (ddp = ddpcb; ddp; ddp = ddp->ddp_next) { 227214455Srpaulo at_pcbdetach(ddp->ddp_socket, ddp); 228214455Srpaulo } 229214455Srpaulo} 230214455Srpaulo#endif 231214455Srpaulo 232214455Srpaulostatic int 233214455Srpauloat_setpeeraddr(struct socket *so, struct sockaddr **nam) 234214455Srpaulo{ 235214455Srpaulo return (EOPNOTSUPP); 236214455Srpaulo} 237214455Srpaulo 238214455Srpaulostatic int 239214455Srpauloat_setsockaddr(struct socket *so, struct sockaddr **nam) 240214455Srpaulo{ 241214455Srpaulo struct ddpcb *ddp; 242214455Srpaulo 243214455Srpaulo ddp = sotoddpcb(so); 244214455Srpaulo if (ddp == NULL) { 245214455Srpaulo return (EINVAL); 246214455Srpaulo } 247251129Sdelphij at_sockaddr(ddp, nam); 248214455Srpaulo return (0); 249214455Srpaulo} 250214455Srpaulo 251214455Srpaulostruct pr_usrreqs ddp_usrreqs = { 252214455Srpaulo ddp_abort, 253214455Srpaulo pru_accept_notsupp, 254214455Srpaulo ddp_attach, 255214455Srpaulo ddp_bind, 256214455Srpaulo ddp_connect, 257251129Sdelphij pru_connect2_notsupp, 258214455Srpaulo at_control, 259214455Srpaulo ddp_detach, 260214455Srpaulo ddp_disconnect, 261214455Srpaulo pru_listen_notsupp, 262214455Srpaulo at_setpeeraddr, 263214455Srpaulo pru_rcvd_notsupp, 264251129Sdelphij pru_rcvoob_notsupp, 265251129Sdelphij ddp_send, 266251129Sdelphij pru_sense_null, 267214455Srpaulo ddp_shutdown, 268251129Sdelphij at_setsockaddr, 269214455Srpaulo sosend, 270214455Srpaulo soreceive, 271214455Srpaulo sopoll, 272214455Srpaulo pru_sosetlabel_null 273214455Srpaulo}; 274251129Sdelphij