xref: /csrg-svn/sys/netinet/udp_usrreq.c (revision 4912)
1 /*	udp_usrreq.c	4.5	81/11/16	*/
2 
3 #include "../h/param.h"
4 #include "../h/dir.h"
5 #include "../h/user.h"
6 #include "../h/mbuf.h"
7 #include "../h/protosw.h"
8 #include "../h/socket.h"
9 #include "../h/socketvar.h"
10 #include "../h/inaddr.h"
11 #include "../net/inet.h"
12 #include "../net/inet_host.h"
13 #include "../net/inet_pcb.h"
14 #include "../net/inet_systm.h"
15 #include "../net/ip.h"
16 #include "../net/ip_var.h"
17 #include "../net/udp.h"
18 #include "../net/udp_var.h"
19 
20 udp_init()
21 {
22 
23 	udb.inp_next = udb.inp_prev = &udb;
24 }
25 
26 int	udpcksum;
27 
28 udp_input(m)
29 	struct mbuf *m;
30 {
31 	register struct udpiphdr *ui;
32 	register struct inpcb *inp;
33 	u_short lport, fport, ulen;
34 
35 	ui = mtod(m, struct udpiphdr *);
36 	if (ui->ui_len > sizeof (struct ip))		/* XXX */
37 		ip_stripoptions((struct ip *)ui);
38 	ulen = ((struct ip *)ui)->ip_len;
39 	ui->ui_len = htons(ulen);
40 	ui->ui_prev = ui->ui_next = 0;
41 	ui->ui_x1 = 0;
42 	lport = ntohs(ui->ui_dport);
43 	fport = ntohs(ui->ui_sport);
44 	if (sizeof (struct udpiphdr) > m->m_len)
45 	    { printf("udp header overflow\n"); m_freem(m); return; }
46 	if (udpcksum) {
47 		(void) inet_cksum(m, sizeof (struct ip) + ulen);
48 		if (ui->ui_sum) {
49 			printf("udp cksum %x\n", ui->ui_sum);
50 			m_freem(m);
51 			return;
52 		}
53 	}
54 	inp = in_pcblookup(&udb, &ui->ui_src, fport, &ui->ui_dst, lport);
55 	if (inp == 0)
56 		goto notwanted;
57 	/* stuff on queue using some subroutine */
58 	return;
59 notwanted:
60 	m_freem(m);
61 	/* gen icmp? */
62 }
63 
64 udp_ctlinput(m)
65 	struct mbuf *m;
66 {
67 
68 	m_freem(m);
69 }
70 
71 udp_ctlinput(m)
72 	struct mbuf *m;
73 {
74 
75 	m_freem(m);
76 }
77 
78 /*ARGSUSED*/
79 udp_output(raddr, rport, m)
80 	int raddr, rport;
81 	struct mbuf *m;
82 {
83 
84 	/* setup header */
85 	ip_output(m);
86 }
87 
88 /*ARGSUSED*/
89 udp_usrreq(so, req, m, addr)
90 	struct socket *so;
91 	int req;
92 	struct mbuf *m;
93 	caddr_t addr;
94 {
95 	struct inpcb *inp = sotoinpcb(so);
96 	int error;
97 
98 	switch (req) {
99 
100 	case PRU_ATTACH:
101 		if (inp != 0)
102 			return (EINVAL);
103 		inp = in_pcballoc();
104 		if (inp == NULL)
105 			return (ENOBUFS);
106 		so->so_pcb = (caddr_t)inp;
107 		break;
108 
109 	case PRU_DETACH:
110 		if (inp == 0)
111 			return (ENOTCONN);
112 		in_pcbfree(inp);
113 		break;
114 
115 	case PRU_CONNECT:
116 		if (inp->inp_fhost)
117 			return (EISCONN);
118 		inp->inp_fhost = in_hosteval((struct inaddr *)addr, &error);
119 		if (inp->inp_fhost == 0)
120 			return (error);
121 		soisconnected(so);
122 		break;
123 
124 	case PRU_DISCONNECT:
125 		if (inp->inp_fhost == 0)
126 			return (ENOTCONN);
127 		in_hostfree(inp->inp_fhost);
128 		inp->inp_fhost = 0;
129 		soisdisconnected(so);
130 		break;
131 
132 	case PRU_FLUSH:
133 		return (EOPNOTSUPP);
134 
135 	case PRU_SHUTDOWN:
136 		socantsendmore(so);
137 		break;
138 
139 	case PRU_SEND:
140 #if 0
141 		if (addr) {
142 			if (inp->inp_fhost)
143 				return (EISCONN);
144 			udp_output(addr->in_fhost, addr->in_fport, m);
145 		} else
146 #endif
147 			udp_output(inp->inp_fhost->h_addr, ip->inp_fport, m);
148 		break;
149 
150 	case PRU_ABORT:
151 		in_pcbfree(inp);
152 		sofree(so);
153 		soisdisconnected(so);
154 		break;
155 
156 	case PRU_CONTROL:
157 		return (EOPNOTSUPP);
158 
159 	default:
160 		panic("udp_usrreq");
161 	}
162 	return (0);
163 }
164 
165 udp_sense()
166 {
167 
168 }
169