xref: /csrg-svn/sys/netinet/udp_usrreq.c (revision 4901)
1 /*	udp_usrreq.c	4.4	81/11/15	*/
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 "../net/inet.h"
11 #include "../net/inet_host.h"
12 #include "../net/inet_pcb.h"
13 #include "../net/inet_systm.h"
14 #include "../net/ip.h"
15 #include "../net/ip_var.h"
16 #include "../net/udp.h"
17 #include "../net/udp_var.h"
18 
19 udp_init()
20 {
21 
22 	udb.inp_next = udb.inp_prev = &udb;
23 }
24 
25 int	udpcksum;
26 
27 udp_input(m)
28 	struct mbuf *m;
29 {
30 	register struct udpiphdr *ui;
31 	register struct inpcb *inp;
32 	u_short lport, fport;
33 	int 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 		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 = inpcb_lookup(&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_advise(m)
72 	struct mbuf *m;
73 {
74 
75 	m_freem(m);
76 }
77 
78 udp_output(raddr, rport, m)
79 	int raddr, rport;
80 	struct mbuf *m;
81 {
82 
83 	/* setup header */
84 	ip_output(m);
85 }
86 
87 udp_usrreq(so, req, m, addr)
88 	struct socket *so;
89 	int req;
90 	struct mbuf *m;
91 	struct in_addr *addr;
92 {
93 	struct inpcb *inp = sotoinpcb(so);
94 	int error;
95 
96 	switch (req) {
97 
98 	case PRU_ATTACH:
99 		if (inp != 0)
100 			return (EINVAL);
101 		inp = inpcb_alloc();
102 		if (inp == NULL)
103 			return (ENOBUFS);
104 		so->so_pcb = (caddr_t)inp;
105 		break;
106 
107 	case PRU_DETACH:
108 		if (inp == 0)
109 			return (ENOTCONN);
110 		sofree(inp->inp_socket);
111 		udp_detach(inp);
112 		break;
113 
114 	case PRU_CONNECT:
115 		if (inp->inp_fhost)
116 			return (EISCONN);
117 		inp->inp_fhost = in_hmake((struct in_addr *)addr, &error);
118 		if (inp->inp_fhost == 0)
119 			return (error);
120 		soisconnected(so);
121 		break;
122 
123 	case PRU_DISCONNECT:
124 		if (inp->inp_fhost == 0)
125 			return (ENOTCONN);
126 		h_free(inp->inp_fhost);
127 		inp->inp_fhost = 0;
128 		soisdisconnected(so);
129 		break;
130 
131 	case PRU_SEND:
132 #if 0
133 		if (addr) {
134 			if (inp->inp_fhost)
135 				return (EISCONN);
136 			udp_output(addr->in_fhost, addr->in_fport, m);
137 		} else
138 			udp_output(inp->inp_fhost->h_addr, ip->inp_fport, m);
139 #endif
140 		break;
141 
142 	case PRU_ABORT:
143 		in_pcbfree(inp);
144 		sofree(so);
145 		soisdisconnected(so);
146 		break;
147 
148 	case PRU_CONTROL:
149 		return (EOPNOTSUPP);
150 
151 	default:
152 		panic("udp_usrreq");
153 	}
154 	return (0);
155 }
156 
157 udp_sense()
158 {
159 
160 }
161