xref: /csrg-svn/sys/netinet/udp_usrreq.c (revision 4901)
1*4901Swnj /*	udp_usrreq.c	4.4	81/11/15	*/
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"
104805Swnj #include "../net/inet.h"
114887Swnj #include "../net/inet_host.h"
124887Swnj #include "../net/inet_pcb.h"
134805Swnj #include "../net/inet_systm.h"
14*4901Swnj #include "../net/ip.h"
15*4901Swnj #include "../net/ip_var.h"
164887Swnj #include "../net/udp.h"
174887Swnj #include "../net/udp_var.h"
184784Swnj 
194805Swnj udp_init()
204805Swnj {
214805Swnj 
22*4901Swnj 	udb.inp_next = udb.inp_prev = &udb;
234805Swnj }
244805Swnj 
25*4901Swnj int	udpcksum;
26*4901Swnj 
274784Swnj udp_input(m)
284784Swnj 	struct mbuf *m;
294784Swnj {
30*4901Swnj 	register struct udpiphdr *ui;
314887Swnj 	register struct inpcb *inp;
32*4901Swnj 	u_short lport, fport;
33*4901Swnj 	int ulen;
344784Swnj 
35*4901Swnj 	ui = mtod(m, struct udpiphdr *);
36*4901Swnj 	if (ui->ui_len > sizeof (struct ip))		/* XXX */
37*4901Swnj 		ip_stripoptions((struct ip *)ui);
38*4901Swnj 	ulen = ((struct ip *)ui)->ip_len;
39*4901Swnj 	ui->ui_len = htons(ulen);
40*4901Swnj 	ui->ui_prev = ui->ui_next = 0;
41*4901Swnj 	ui->ui_x1 = 0;
42*4901Swnj 	lport = ntohs(ui->ui_dport);
43*4901Swnj 	fport = ntohs(ui->ui_sport);
44*4901Swnj 	if (sizeof (struct udpiphdr) > m->m_len)
45*4901Swnj 	    { printf("udp header overflow\n"); m_freem(m); return; }
46*4901Swnj 	if (udpcksum) {
47*4901Swnj 		inet_cksum(m, sizeof (struct ip) + ulen);
48*4901Swnj 		if (ui->ui_sum) {
49*4901Swnj 			printf("udp cksum %x\n", ui->ui_sum);
50*4901Swnj 			m_freem(m);
51*4901Swnj 			return;
52*4901Swnj 		}
53*4901Swnj 	}
54*4901Swnj 	inp = inpcb_lookup(&ui->ui_src, fport, &ui->ui_dst, lport);
554887Swnj 	if (inp == 0)
56*4901Swnj 		goto notwanted;
57*4901Swnj 	/* stuff on queue using some subroutine */
584887Swnj 	return;
59*4901Swnj 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 
714784Swnj udp_advise(m)
724784Swnj 	struct mbuf *m;
734784Swnj {
744784Swnj 
754784Swnj 	m_freem(m);
764784Swnj }
774784Swnj 
784887Swnj udp_output(raddr, rport, m)
794887Swnj 	int raddr, rport;
804784Swnj 	struct mbuf *m;
814784Swnj {
824784Swnj 
834887Swnj 	/* setup header */
844887Swnj 	ip_output(m);
854784Swnj }
864784Swnj 
874887Swnj udp_usrreq(so, req, m, addr)
884887Swnj 	struct socket *so;
894784Swnj 	int req;
904784Swnj 	struct mbuf *m;
914784Swnj 	struct in_addr *addr;
924784Swnj {
934887Swnj 	struct inpcb *inp = sotoinpcb(so);
944887Swnj 	int error;
954784Swnj 
964784Swnj 	switch (req) {
974784Swnj 
984784Swnj 	case PRU_ATTACH:
994887Swnj 		if (inp != 0)
1004887Swnj 			return (EINVAL);
101*4901Swnj 		inp = inpcb_alloc();
1024887Swnj 		if (inp == NULL)
1034887Swnj 			return (ENOBUFS);
1044887Swnj 		so->so_pcb = (caddr_t)inp;
1054887Swnj 		break;
1064784Swnj 
1074784Swnj 	case PRU_DETACH:
1084887Swnj 		if (inp == 0)
1094887Swnj 			return (ENOTCONN);
1104887Swnj 		sofree(inp->inp_socket);
1114887Swnj 		udp_detach(inp);
1124887Swnj 		break;
1134784Swnj 
1144784Swnj 	case PRU_CONNECT:
1154887Swnj 		if (inp->inp_fhost)
1164887Swnj 			return (EISCONN);
1174887Swnj 		inp->inp_fhost = in_hmake((struct in_addr *)addr, &error);
1184887Swnj 		if (inp->inp_fhost == 0)
1194887Swnj 			return (error);
1204887Swnj 		soisconnected(so);
1214887Swnj 		break;
1224784Swnj 
1234784Swnj 	case PRU_DISCONNECT:
1244887Swnj 		if (inp->inp_fhost == 0)
1254887Swnj 			return (ENOTCONN);
1264887Swnj 		h_free(inp->inp_fhost);
1274887Swnj 		inp->inp_fhost = 0;
1284887Swnj 		soisdisconnected(so);
1294784Swnj 		break;
1304784Swnj 
1314784Swnj 	case PRU_SEND:
1324887Swnj #if 0
1334887Swnj 		if (addr) {
1344887Swnj 			if (inp->inp_fhost)
1354887Swnj 				return (EISCONN);
1364887Swnj 			udp_output(addr->in_fhost, addr->in_fport, m);
1374887Swnj 		} else
1384887Swnj 			udp_output(inp->inp_fhost->h_addr, ip->inp_fport, m);
1394887Swnj #endif
1404784Swnj 		break;
1414784Swnj 
1424784Swnj 	case PRU_ABORT:
1434887Swnj 		in_pcbfree(inp);
1444887Swnj 		sofree(so);
1454887Swnj 		soisdisconnected(so);
1464784Swnj 		break;
1474784Swnj 
1484784Swnj 	case PRU_CONTROL:
1494887Swnj 		return (EOPNOTSUPP);
1504784Swnj 
1514784Swnj 	default:
1524784Swnj 		panic("udp_usrreq");
1534805Swnj 	}
1544887Swnj 	return (0);
1554784Swnj }
1564805Swnj 
1574805Swnj udp_sense()
1584805Swnj {
1594805Swnj 
1604805Swnj }
161