ddp_usrreq.c revision 128943
1184610Salfred/* 2184610Salfred * Copyright (c) 1990,1994 Regents of The University of Michigan. 3184610Salfred * All Rights Reserved. See COPYRIGHT. 4184610Salfred * 5184610Salfred * $FreeBSD: head/sys/netatalk/ddp_usrreq.c 128943 2004-05-05 03:34:37Z rwatson $ 6184610Salfred */ 7184610Salfred 8184610Salfred#include <sys/param.h> 9184610Salfred#include <sys/systm.h> 10184610Salfred#include <sys/malloc.h> 11184610Salfred#include <sys/mbuf.h> 12184610Salfred#include <sys/socket.h> 13184610Salfred#include <sys/socketvar.h> 14184610Salfred#include <sys/protosw.h> 15184610Salfred#include <net/if.h> 16184610Salfred#include <net/route.h> 17184610Salfred#include <net/netisr.h> 18184610Salfred 19184610Salfred#include <netatalk/at.h> 20184610Salfred#include <netatalk/at_var.h> 21184610Salfred#include <netatalk/ddp_var.h> 22184610Salfred#include <netatalk/ddp_pcb.h> 23184610Salfred#include <netatalk/at_extern.h> 24184610Salfred 25184610Salfredstatic u_long ddp_sendspace = DDP_MAXSZ; /* Max ddp size + 1 (ddp_type) */ 26184610Salfredstatic u_long ddp_recvspace = 10 * (587 + sizeof(struct sockaddr_at)); 27184610Salfred 28184610Salfredstatic struct ifqueue atintrq1, atintrq2, aarpintrq; 29184610Salfred 30184610Salfredstatic int 31184610Salfredddp_attach(struct socket *so, int proto, struct thread *td) 32184610Salfred{ 33184610Salfred struct ddpcb *ddp; 34184610Salfred int error = 0; 35190754Sthompsa int s; 36184610Salfred 37184610Salfred 38188942Sthompsa ddp = sotoddpcb(so); 39188942Sthompsa if (ddp != NULL) { 40188942Sthompsa return (EINVAL); 41184610Salfred } 42184610Salfred 43184610Salfred s = splnet(); 44188942Sthompsa error = at_pcballoc(so); 45188942Sthompsa splx(s); 46188942Sthompsa if (error) { 47188942Sthompsa return (error); 48188942Sthompsa } 49188942Sthompsa return (soreserve(so, ddp_sendspace, ddp_recvspace)); 50188942Sthompsa} 51188942Sthompsa 52184610Salfredstatic int 53188942Sthompsaddp_detach(struct socket *so) 54188942Sthompsa{ 55188942Sthompsa struct ddpcb *ddp; 56184610Salfred int s; 57190181Sthompsa 58190181Sthompsa ddp = sotoddpcb(so); 59190181Sthompsa if (ddp == NULL) { 60184610Salfred return (EINVAL); 61184610Salfred } 62184610Salfred s = splnet(); 63184610Salfred at_pcbdetach(so, ddp); 64184610Salfred splx(s); 65184610Salfred return (0); 66184610Salfred} 67184610Salfred 68184610Salfredstatic int 69184610Salfredddp_bind(struct socket *so, struct sockaddr *nam, struct thread *td) 70184610Salfred{ 71184610Salfred struct ddpcb *ddp; 72184610Salfred int error = 0; 73184610Salfred int s; 74184610Salfred 75184610Salfred ddp = sotoddpcb(so); 76184610Salfred if (ddp == NULL) { 77184610Salfred return (EINVAL); 78184610Salfred } 79184610Salfred s = splnet(); 80184610Salfred error = at_pcbsetaddr(ddp, nam, td); 81184610Salfred splx(s); 82184610Salfred return (error); 83184610Salfred} 84184610Salfred 85184610Salfredstatic int 86184610Salfredddp_connect(struct socket *so, struct sockaddr *nam, struct thread *td) 87184610Salfred{ 88184610Salfred struct ddpcb *ddp; 89184610Salfred int error = 0; 90184610Salfred int s; 91184610Salfred 92184610Salfred ddp = sotoddpcb(so); 93184610Salfred if (ddp == NULL) { 94184610Salfred return (EINVAL); 95184610Salfred } 96184610Salfred 97184610Salfred if (ddp->ddp_fsat.sat_port != ATADDR_ANYPORT) { 98184610Salfred return (EISCONN); 99184610Salfred } 100190735Sthompsa 101184610Salfred s = splnet(); 102184610Salfred error = at_pcbconnect(ddp, nam, td); 103184610Salfred splx(s); 104184610Salfred if (error == 0) 105184610Salfred soisconnected(so); 106184610Salfred return (error); 107184610Salfred} 108184610Salfred 109184610Salfredstatic int 110184610Salfredddp_disconnect(struct socket *so) 111184610Salfred{ 112190183Sthompsa 113184610Salfred struct ddpcb *ddp; 114184610Salfred int s; 115184610Salfred 116184610Salfred ddp = sotoddpcb(so); 117184610Salfred if (ddp == NULL) { 118184610Salfred return (EINVAL); 119184610Salfred } 120184610Salfred if (ddp->ddp_fsat.sat_addr.s_node == ATADDR_ANYNODE) { 121184610Salfred return (ENOTCONN); 122184610Salfred } 123184610Salfred 124184610Salfred s = splnet(); 125184610Salfred at_pcbdisconnect(ddp); 126184610Salfred ddp->ddp_fsat.sat_addr.s_node = ATADDR_ANYNODE; 127184610Salfred splx(s); 128184610Salfred soisdisconnected(so); 129184610Salfred return (0); 130184610Salfred} 131184610Salfred 132184610Salfredstatic int 133184610Salfredddp_shutdown(struct socket *so) 134184610Salfred{ 135184610Salfred struct ddpcb *ddp; 136184610Salfred 137184610Salfred ddp = sotoddpcb(so); 138184610Salfred if (ddp == NULL) { 139184610Salfred return (EINVAL); 140184610Salfred } 141184610Salfred socantsendmore(so); 142184610Salfred return (0); 143184610Salfred} 144184610Salfred 145184610Salfredstatic int 146184610Salfredddp_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, 147184610Salfred struct mbuf *control, struct thread *td) 148184610Salfred{ 149184610Salfred struct ddpcb *ddp; 150184610Salfred int error = 0; 151184610Salfred int s; 152184610Salfred 153184610Salfred ddp = sotoddpcb(so); 154184610Salfred if (ddp == NULL) { 155184610Salfred return (EINVAL); 156184610Salfred } 157184610Salfred 158184610Salfred if (control && control->m_len) { 159184610Salfred return (EINVAL); 160184610Salfred } 161184610Salfred 162184610Salfred if (addr != NULL) { 163184610Salfred if (ddp->ddp_fsat.sat_port != ATADDR_ANYPORT) { 164184610Salfred return (EISCONN); 165188409Sthompsa } 166184610Salfred 167184610Salfred s = splnet(); 168184610Salfred error = at_pcbconnect(ddp, addr, td); 169184610Salfred splx(s); 170184610Salfred if (error) { 171184610Salfred return (error); 172184610Salfred } 173184610Salfred } else { 174184610Salfred if (ddp->ddp_fsat.sat_port == ATADDR_ANYPORT) { 175184610Salfred return (ENOTCONN); 176184610Salfred } 177184610Salfred } 178188409Sthompsa 179188409Sthompsa s = splnet(); 180184610Salfred error = ddp_output(m, so); 181184610Salfred if (addr != NULL) { 182184610Salfred at_pcbdisconnect(ddp); 183184610Salfred } 184184610Salfred splx(s); 185184610Salfred return (error); 186184610Salfred} 187184610Salfred 188184610Salfredstatic int 189188409Sthompsaddp_abort(struct socket *so) 190188409Sthompsa{ 191184610Salfred struct ddpcb *ddp; 192184610Salfred int s; 193184610Salfred 194184610Salfred ddp = sotoddpcb(so); 195184610Salfred if (ddp == NULL) { 196184610Salfred return (EINVAL); 197184610Salfred } 198184610Salfred s = splnet(); 199184610Salfred at_pcbdetach(so, ddp); 200184610Salfred splx(s); 201184610Salfred return (0); 202184610Salfred} 203184610Salfred 204184610Salfredvoid 205184610Salfredddp_init(void) 206184610Salfred{ 207184610Salfred 208184610Salfred atintrq1.ifq_maxlen = IFQ_MAXLEN; 209184610Salfred atintrq2.ifq_maxlen = IFQ_MAXLEN; 210184610Salfred aarpintrq.ifq_maxlen = IFQ_MAXLEN; 211184610Salfred mtx_init(&atintrq1.ifq_mtx, "at1_inq", NULL, MTX_DEF); 212184610Salfred mtx_init(&atintrq2.ifq_mtx, "at2_inq", NULL, MTX_DEF); 213184610Salfred mtx_init(&aarpintrq.ifq_mtx, "aarp_inq", NULL, MTX_DEF); 214184610Salfred netisr_register(NETISR_ATALK1, at1intr, &atintrq1, 0); 215184610Salfred netisr_register(NETISR_ATALK2, at2intr, &atintrq2, 0); 216184610Salfred netisr_register(NETISR_AARP, aarpintr, &aarpintrq, 0); 217184610Salfred} 218184610Salfred 219184610Salfred#if 0 220184610Salfredstatic void 221184610Salfredddp_clean(void) 222184610Salfred{ 223184610Salfred struct ddpcb *ddp; 224184610Salfred 225184610Salfred for (ddp = ddpcb_list; ddp != NULL; ddp = ddp->ddp_next) { 226184610Salfred at_pcbdetach(ddp->ddp_socket, ddp); 227184610Salfred } 228184610Salfred} 229184610Salfred#endif 230184610Salfred 231184610Salfredstatic int 232184610Salfredat_setpeeraddr(struct socket *so, struct sockaddr **nam) 233184610Salfred{ 234184610Salfred return (EOPNOTSUPP); 235184610Salfred} 236184610Salfred 237184610Salfredstatic int 238184610Salfredat_setsockaddr(struct socket *so, struct sockaddr **nam) 239184610Salfred{ 240184610Salfred struct ddpcb *ddp; 241184610Salfred 242184610Salfred ddp = sotoddpcb(so); 243184610Salfred if (ddp == NULL) { 244184610Salfred return (EINVAL); 245184610Salfred } 246184610Salfred at_sockaddr(ddp, nam); 247184610Salfred return (0); 248184610Salfred} 249184610Salfred 250184610Salfredstruct pr_usrreqs ddp_usrreqs = { 251184610Salfred ddp_abort, 252188409Sthompsa pru_accept_notsupp, 253188409Sthompsa ddp_attach, 254184610Salfred ddp_bind, 255184610Salfred ddp_connect, 256184610Salfred pru_connect2_notsupp, 257184610Salfred at_control, 258184610Salfred ddp_detach, 259184610Salfred ddp_disconnect, 260184610Salfred pru_listen_notsupp, 261184610Salfred at_setpeeraddr, 262188409Sthompsa pru_rcvd_notsupp, 263188409Sthompsa pru_rcvoob_notsupp, 264184610Salfred ddp_send, 265184610Salfred pru_sense_null, 266184610Salfred ddp_shutdown, 267184610Salfred at_setsockaddr, 268184610Salfred sosend, 269184610Salfred soreceive, 270184610Salfred sopoll, 271184610Salfred pru_sosetlabel_null 272184610Salfred}; 273184610Salfred