156888Ssklower /*
2*63222Sbostic * Copyright (c) 1992, 1993
3*63222Sbostic * The Regents of the University of California. All rights reserved.
456888Ssklower *
556888Ssklower * %sccs.include.redist.c%
656888Ssklower *
7*63222Sbostic * @(#)idrp_usrreq.c 8.1 (Berkeley) 06/10/93
856888Ssklower */
956888Ssklower
1056888Ssklower #include <sys/param.h>
1156888Ssklower #include <sys/proc.h>
1256888Ssklower #include <sys/systm.h>
1356888Ssklower #include <sys/malloc.h>
1456888Ssklower #include <sys/mbuf.h>
1556888Ssklower #include <sys/socket.h>
1656888Ssklower #include <sys/socketvar.h>
1756888Ssklower #include <sys/protosw.h>
1856888Ssklower #include <sys/errno.h>
1956888Ssklower
2056888Ssklower #include <net/route.h>
2156888Ssklower #include <net/if.h>
2256888Ssklower
2356888Ssklower #include <netiso/argo_debug.h>
2456888Ssklower #include <netiso/iso.h>
2556888Ssklower #include <netiso/clnp.h>
2656888Ssklower #include <netiso/clnl.h>
2756888Ssklower #include <netiso/iso_pcb.h>
2856888Ssklower #include <netiso/iso_var.h>
2956888Ssklower
3056888Ssklower int idrp_input();
3156888Ssklower struct isopcb idrp_isop;
3256888Ssklower static struct sockaddr_iso idrp_addrs[2] =
3356888Ssklower { { sizeof(idrp_addrs), AF_ISO, }, { sizeof(idrp_addrs[1]), AF_ISO, } };
3456888Ssklower /*
3556888Ssklower * IDRP initialization
3656888Ssklower */
idrp_init()3756888Ssklower idrp_init()
3856888Ssklower {
3956888Ssklower extern struct clnl_protosw clnl_protox[256];
4056888Ssklower
4156888Ssklower idrp_isop.isop_next = idrp_isop.isop_prev = &idrp_isop;
4256888Ssklower idrp_isop.isop_faddr = &idrp_isop.isop_sfaddr;
4356888Ssklower idrp_isop.isop_laddr = &idrp_isop.isop_sladdr;
4456888Ssklower idrp_isop.isop_sladdr = idrp_addrs[1];
4556888Ssklower idrp_isop.isop_sfaddr = idrp_addrs[1];
4656888Ssklower clnl_protox[ISO10747_IDRP].clnl_input = idrp_input;
4756888Ssklower }
4856888Ssklower
4956888Ssklower /*
5056888Ssklower * CALLED FROM:
5156888Ssklower * tpclnp_input().
5256888Ssklower * FUNCTION and ARGUMENTS:
5356888Ssklower * Take a packet (m) from clnp, strip off the clnp header
5456888Ssklower * and mke suitable for the idrp socket.
5556888Ssklower * No return value.
5656888Ssklower */
idrp_input(m,src,dst)5756888Ssklower idrp_input(m, src, dst)
5856888Ssklower register struct mbuf *m;
5956888Ssklower struct sockaddr_iso *src, *dst;
6056888Ssklower {
6156888Ssklower if (idrp_isop.isop_socket == 0) {
6256888Ssklower bad: m_freem(m);
6356888Ssklower return 0;
6456888Ssklower }
6556888Ssklower bzero(idrp_addrs[0].siso_data, sizeof(idrp_addrs[0].siso_data));
6656888Ssklower bcopy((caddr_t)&(src->siso_addr), (caddr_t)&idrp_addrs[0].siso_addr,
6756888Ssklower 1 + src->siso_nlen);
6856888Ssklower bzero(idrp_addrs[1].siso_data, sizeof(idrp_addrs[1].siso_data));
6956888Ssklower bcopy((caddr_t)&(dst->siso_addr), (caddr_t)&idrp_addrs[1].siso_addr,
7056888Ssklower 1 + dst->siso_nlen);
7156888Ssklower if (sbappendaddr(&idrp_isop.isop_socket->so_rcv,
7256888Ssklower (struct sockaddr *)idrp_addrs, m, (struct mbuf *)0) == 0)
7356888Ssklower goto bad;
7456888Ssklower sorwakeup(idrp_isop.isop_socket);
7556888Ssklower return 0;
7656888Ssklower }
7756888Ssklower
7856888Ssklower idrp_output(m, addr)
7956888Ssklower struct mbuf *m, *addr;
8056888Ssklower {
8156888Ssklower register struct sockaddr_iso *siso = mtod(addr, struct sockaddr_iso *);
8256888Ssklower int s = splnet(), i;
8356888Ssklower
8456888Ssklower bcopy((caddr_t)&(siso->siso_addr),
8556888Ssklower (caddr_t)&idrp_isop.isop_sfaddr.siso_addr, 1 + siso->siso_nlen);
8656888Ssklower siso++;
8756888Ssklower bcopy((caddr_t)&(siso->siso_addr),
8856888Ssklower (caddr_t)&idrp_isop.isop_sladdr.siso_addr, 1 + siso->siso_nlen);
8956888Ssklower i = clnp_output(m, idrp_isop, m->m_pkthdr.len, 0);
9056888Ssklower splx(s);
9156888Ssklower return (i);
9256888Ssklower }
9356888Ssklower
9456888Ssklower u_long idrp_sendspace = 3072; /* really max datagram size */
9556888Ssklower u_long idrp_recvspace = 40 * 1024; /* 40 1K datagrams */
9656888Ssklower
9756888Ssklower /*ARGSUSED*/
9856888Ssklower idrp_usrreq(so, req, m, addr, control)
9956888Ssklower struct socket *so;
10056888Ssklower int req;
10156888Ssklower struct mbuf *m, *addr, *control;
10256888Ssklower {
10356888Ssklower int error = 0;
10456888Ssklower
10556888Ssklower /* Note: need to block idrp_input while changing
10656888Ssklower * the udp pcb queue and/or pcb addresses.
10756888Ssklower */
10856888Ssklower switch (req) {
10956888Ssklower
11056888Ssklower case PRU_ATTACH:
11156888Ssklower if (idrp_isop.isop_socket != NULL) {
11256888Ssklower error = ENXIO;
11356888Ssklower break;
11456888Ssklower }
11556888Ssklower idrp_isop.isop_socket = so;
11656888Ssklower error = soreserve(so, idrp_sendspace, idrp_recvspace);
11756888Ssklower break;
11856888Ssklower
11956888Ssklower case PRU_SHUTDOWN:
12056888Ssklower socantsendmore(so);
12156888Ssklower break;
12256888Ssklower
12356888Ssklower case PRU_SEND:
12456888Ssklower return (idrp_output(m, addr));
12556888Ssklower
12656888Ssklower case PRU_ABORT:
12756888Ssklower soisdisconnected(so);
12856888Ssklower case PRU_DETACH:
12956888Ssklower idrp_isop.isop_socket = 0;
13056888Ssklower break;
13156888Ssklower
13256888Ssklower
13356888Ssklower case PRU_SENSE:
13456888Ssklower /*
13556888Ssklower * stat: don't bother with a blocksize.
13656888Ssklower */
13756888Ssklower return (0);
13856888Ssklower
13956888Ssklower default:
14056888Ssklower return (EOPNOTSUPP); /* do not free mbuf's */
14156888Ssklower }
14256888Ssklower
14356888Ssklower release:
14456888Ssklower if (control) {
14556888Ssklower printf("idrp control data unexpectedly retained\n");
14656888Ssklower m_freem(control);
14756888Ssklower }
14856888Ssklower if (m)
14956888Ssklower m_freem(m);
15056888Ssklower return (error);
15156888Ssklower }
152