xref: /csrg-svn/sys/netinet/udp_usrreq.c (revision 4912)
1*4912Swnj /*	udp_usrreq.c	4.5	81/11/16	*/
24784Swnj 
34784Swnj #include "../h/param.h"
44887Swnj #include "../h/dir.h"
54887Swnj #include "../h/user.h"
64784Swnj #include "../h/mbuf.h"
74805Swnj #include "../h/protosw.h"
84887Swnj #include "../h/socket.h"
94887Swnj #include "../h/socketvar.h"
10*4912Swnj #include "../h/inaddr.h"
114805Swnj #include "../net/inet.h"
124887Swnj #include "../net/inet_host.h"
134887Swnj #include "../net/inet_pcb.h"
144805Swnj #include "../net/inet_systm.h"
154901Swnj #include "../net/ip.h"
164901Swnj #include "../net/ip_var.h"
174887Swnj #include "../net/udp.h"
184887Swnj #include "../net/udp_var.h"
194784Swnj 
204805Swnj udp_init()
214805Swnj {
224805Swnj 
234901Swnj 	udb.inp_next = udb.inp_prev = &udb;
244805Swnj }
254805Swnj 
264901Swnj int	udpcksum;
274901Swnj 
284784Swnj udp_input(m)
294784Swnj 	struct mbuf *m;
304784Swnj {
314901Swnj 	register struct udpiphdr *ui;
324887Swnj 	register struct inpcb *inp;
33*4912Swnj 	u_short lport, fport, ulen;
344784Swnj 
354901Swnj 	ui = mtod(m, struct udpiphdr *);
364901Swnj 	if (ui->ui_len > sizeof (struct ip))		/* XXX */
374901Swnj 		ip_stripoptions((struct ip *)ui);
384901Swnj 	ulen = ((struct ip *)ui)->ip_len;
394901Swnj 	ui->ui_len = htons(ulen);
404901Swnj 	ui->ui_prev = ui->ui_next = 0;
414901Swnj 	ui->ui_x1 = 0;
424901Swnj 	lport = ntohs(ui->ui_dport);
434901Swnj 	fport = ntohs(ui->ui_sport);
444901Swnj 	if (sizeof (struct udpiphdr) > m->m_len)
454901Swnj 	    { printf("udp header overflow\n"); m_freem(m); return; }
464901Swnj 	if (udpcksum) {
47*4912Swnj 		(void) inet_cksum(m, sizeof (struct ip) + ulen);
484901Swnj 		if (ui->ui_sum) {
494901Swnj 			printf("udp cksum %x\n", ui->ui_sum);
504901Swnj 			m_freem(m);
514901Swnj 			return;
524901Swnj 		}
534901Swnj 	}
54*4912Swnj 	inp = in_pcblookup(&udb, &ui->ui_src, fport, &ui->ui_dst, lport);
554887Swnj 	if (inp == 0)
564901Swnj 		goto notwanted;
574901Swnj 	/* stuff on queue using some subroutine */
584887Swnj 	return;
594901Swnj notwanted:
604887Swnj 	m_freem(m);
614887Swnj 	/* gen icmp? */
624784Swnj }
634784Swnj 
644887Swnj udp_ctlinput(m)
654887Swnj 	struct mbuf *m;
664887Swnj {
674887Swnj 
684887Swnj 	m_freem(m);
694887Swnj }
704887Swnj 
71*4912Swnj udp_ctlinput(m)
724784Swnj 	struct mbuf *m;
734784Swnj {
744784Swnj 
754784Swnj 	m_freem(m);
764784Swnj }
774784Swnj 
78*4912Swnj /*ARGSUSED*/
794887Swnj udp_output(raddr, rport, m)
804887Swnj 	int raddr, rport;
814784Swnj 	struct mbuf *m;
824784Swnj {
834784Swnj 
844887Swnj 	/* setup header */
854887Swnj 	ip_output(m);
864784Swnj }
874784Swnj 
88*4912Swnj /*ARGSUSED*/
894887Swnj udp_usrreq(so, req, m, addr)
904887Swnj 	struct socket *so;
914784Swnj 	int req;
924784Swnj 	struct mbuf *m;
93*4912Swnj 	caddr_t addr;
944784Swnj {
954887Swnj 	struct inpcb *inp = sotoinpcb(so);
964887Swnj 	int error;
974784Swnj 
984784Swnj 	switch (req) {
994784Swnj 
1004784Swnj 	case PRU_ATTACH:
1014887Swnj 		if (inp != 0)
1024887Swnj 			return (EINVAL);
103*4912Swnj 		inp = in_pcballoc();
1044887Swnj 		if (inp == NULL)
1054887Swnj 			return (ENOBUFS);
1064887Swnj 		so->so_pcb = (caddr_t)inp;
1074887Swnj 		break;
1084784Swnj 
1094784Swnj 	case PRU_DETACH:
1104887Swnj 		if (inp == 0)
1114887Swnj 			return (ENOTCONN);
112*4912Swnj 		in_pcbfree(inp);
1134887Swnj 		break;
1144784Swnj 
1154784Swnj 	case PRU_CONNECT:
1164887Swnj 		if (inp->inp_fhost)
1174887Swnj 			return (EISCONN);
118*4912Swnj 		inp->inp_fhost = in_hosteval((struct inaddr *)addr, &error);
1194887Swnj 		if (inp->inp_fhost == 0)
1204887Swnj 			return (error);
1214887Swnj 		soisconnected(so);
1224887Swnj 		break;
1234784Swnj 
1244784Swnj 	case PRU_DISCONNECT:
1254887Swnj 		if (inp->inp_fhost == 0)
1264887Swnj 			return (ENOTCONN);
127*4912Swnj 		in_hostfree(inp->inp_fhost);
1284887Swnj 		inp->inp_fhost = 0;
1294887Swnj 		soisdisconnected(so);
1304784Swnj 		break;
1314784Swnj 
132*4912Swnj 	case PRU_FLUSH:
133*4912Swnj 		return (EOPNOTSUPP);
134*4912Swnj 
135*4912Swnj 	case PRU_SHUTDOWN:
136*4912Swnj 		socantsendmore(so);
137*4912Swnj 		break;
138*4912Swnj 
1394784Swnj 	case PRU_SEND:
1404887Swnj #if 0
1414887Swnj 		if (addr) {
1424887Swnj 			if (inp->inp_fhost)
1434887Swnj 				return (EISCONN);
1444887Swnj 			udp_output(addr->in_fhost, addr->in_fport, m);
1454887Swnj 		} else
146*4912Swnj #endif
1474887Swnj 			udp_output(inp->inp_fhost->h_addr, ip->inp_fport, m);
1484784Swnj 		break;
1494784Swnj 
1504784Swnj 	case PRU_ABORT:
1514887Swnj 		in_pcbfree(inp);
1524887Swnj 		sofree(so);
1534887Swnj 		soisdisconnected(so);
1544784Swnj 		break;
1554784Swnj 
1564784Swnj 	case PRU_CONTROL:
1574887Swnj 		return (EOPNOTSUPP);
1584784Swnj 
1594784Swnj 	default:
1604784Swnj 		panic("udp_usrreq");
1614805Swnj 	}
1624887Swnj 	return (0);
1634784Swnj }
1644805Swnj 
1654805Swnj udp_sense()
1664805Swnj {
1674805Swnj 
1684805Swnj }
169