1 /* 2 * Copyright (c) 1992 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)idrp_usrreq.c 7.1 (Berkeley) 11/17/92 8 */ 9 10 #include <sys/param.h> 11 #include <sys/proc.h> 12 #include <sys/systm.h> 13 #include <sys/malloc.h> 14 #include <sys/mbuf.h> 15 #include <sys/socket.h> 16 #include <sys/socketvar.h> 17 #include <sys/protosw.h> 18 #include <sys/errno.h> 19 20 #include <net/route.h> 21 #include <net/if.h> 22 23 #include <netiso/argo_debug.h> 24 #include <netiso/iso.h> 25 #include <netiso/clnp.h> 26 #include <netiso/clnl.h> 27 #include <netiso/iso_pcb.h> 28 #include <netiso/iso_var.h> 29 30 int idrp_input(); 31 struct isopcb idrp_isop; 32 static struct sockaddr_iso idrp_addrs[2] = 33 { { sizeof(idrp_addrs), AF_ISO, }, { sizeof(idrp_addrs[1]), AF_ISO, } }; 34 /* 35 * IDRP initialization 36 */ 37 idrp_init() 38 { 39 extern struct clnl_protosw clnl_protox[256]; 40 41 idrp_isop.isop_next = idrp_isop.isop_prev = &idrp_isop; 42 idrp_isop.isop_faddr = &idrp_isop.isop_sfaddr; 43 idrp_isop.isop_laddr = &idrp_isop.isop_sladdr; 44 idrp_isop.isop_sladdr = idrp_addrs[1]; 45 idrp_isop.isop_sfaddr = idrp_addrs[1]; 46 clnl_protox[ISO10747_IDRP].clnl_input = idrp_input; 47 } 48 49 /* 50 * CALLED FROM: 51 * tpclnp_input(). 52 * FUNCTION and ARGUMENTS: 53 * Take a packet (m) from clnp, strip off the clnp header 54 * and mke suitable for the idrp socket. 55 * No return value. 56 */ 57 idrp_input(m, src, dst) 58 register struct mbuf *m; 59 struct sockaddr_iso *src, *dst; 60 { 61 if (idrp_isop.isop_socket == 0) { 62 bad: m_freem(m); 63 return 0; 64 } 65 bzero(idrp_addrs[0].siso_data, sizeof(idrp_addrs[0].siso_data)); 66 bcopy((caddr_t)&(src->siso_addr), (caddr_t)&idrp_addrs[0].siso_addr, 67 1 + src->siso_nlen); 68 bzero(idrp_addrs[1].siso_data, sizeof(idrp_addrs[1].siso_data)); 69 bcopy((caddr_t)&(dst->siso_addr), (caddr_t)&idrp_addrs[1].siso_addr, 70 1 + dst->siso_nlen); 71 if (sbappendaddr(&idrp_isop.isop_socket->so_rcv, 72 (struct sockaddr *)idrp_addrs, m, (struct mbuf *)0) == 0) 73 goto bad; 74 sorwakeup(idrp_isop.isop_socket); 75 return 0; 76 } 77 78 idrp_output(m, addr) 79 struct mbuf *m, *addr; 80 { 81 register struct sockaddr_iso *siso = mtod(addr, struct sockaddr_iso *); 82 int s = splnet(), i; 83 84 bcopy((caddr_t)&(siso->siso_addr), 85 (caddr_t)&idrp_isop.isop_sfaddr.siso_addr, 1 + siso->siso_nlen); 86 siso++; 87 bcopy((caddr_t)&(siso->siso_addr), 88 (caddr_t)&idrp_isop.isop_sladdr.siso_addr, 1 + siso->siso_nlen); 89 i = clnp_output(m, idrp_isop, m->m_pkthdr.len, 0); 90 splx(s); 91 return (i); 92 } 93 94 u_long idrp_sendspace = 3072; /* really max datagram size */ 95 u_long idrp_recvspace = 40 * 1024; /* 40 1K datagrams */ 96 97 /*ARGSUSED*/ 98 idrp_usrreq(so, req, m, addr, control) 99 struct socket *so; 100 int req; 101 struct mbuf *m, *addr, *control; 102 { 103 int error = 0; 104 105 /* Note: need to block idrp_input while changing 106 * the udp pcb queue and/or pcb addresses. 107 */ 108 switch (req) { 109 110 case PRU_ATTACH: 111 if (idrp_isop.isop_socket != NULL) { 112 error = ENXIO; 113 break; 114 } 115 idrp_isop.isop_socket = so; 116 error = soreserve(so, idrp_sendspace, idrp_recvspace); 117 break; 118 119 case PRU_SHUTDOWN: 120 socantsendmore(so); 121 break; 122 123 case PRU_SEND: 124 return (idrp_output(m, addr)); 125 126 case PRU_ABORT: 127 soisdisconnected(so); 128 case PRU_DETACH: 129 idrp_isop.isop_socket = 0; 130 break; 131 132 133 case PRU_SENSE: 134 /* 135 * stat: don't bother with a blocksize. 136 */ 137 return (0); 138 139 default: 140 return (EOPNOTSUPP); /* do not free mbuf's */ 141 } 142 143 release: 144 if (control) { 145 printf("idrp control data unexpectedly retained\n"); 146 m_freem(control); 147 } 148 if (m) 149 m_freem(m); 150 return (error); 151 } 152