/* udp_usrreq.c 4.8 81/11/23 */
#include "../h/protosw.h"
#include "../h/socketvar.h"
#include "../net/inet_pcb.h"
#include "../net/inet_systm.h"
#include "../net/ip_var.h"
#include "../net/udp_var.h"
* UDP protocol implementation.
* Per RFC 768, August, 1980.
udb
.inp_next
= udb
.inp_prev
= &udb
;
struct sockaddr_in udp_in
= { AF_INET
};
register struct udpiphdr
*ui
;
register struct inpcb
*inp
;
* Get ip and udp header together in first mbuf.
if (m
->m_len
< sizeof (struct udpiphdr
) &&
m_pullup(m
, sizeof (struct udpiphdr
)) == 0) {
printf("hdrop m_len %d\n", m
->m_len
);
ui
= mtod(m
, struct udpiphdr
*);
if (ui
->ui_len
> sizeof (struct ip
))
ip_stripoptions((struct ip
*)ui
, (char *)0);
* Make mbuf data length reflect udp length.
* If not enough data to reflect udp length, drop.
ulen
= ntohs((u_short
)ui
->ui_ulen
);
len
= sizeof (struct udpiphdr
) + ulen
;
printf("ulen %d, len %d\n", ulen
, len
);
if (((struct ip
*)ui
)->ip_len
!= len
) {
if (len
> ((struct ip
*)ui
)->ip_len
) {
m_adj(m
, ((struct ip
*)ui
)->ip_len
- len
);
/* (struct ip *)ui->ip_len = len; */
* Checksum extended udp header and data.
ui
->ui_next
= ui
->ui_prev
= 0;
ui
->ui_len
= htons((u_short
)(sizeof (struct udpiphdr
) + ulen
));
if ((ui
->ui_sum
= inet_cksum(m
, len
)) != 0xffff) {
printf("udp cksum %x\n", ui
->ui_sum
);
* Convert addresses and ports to host format.
* Locate pcb for datagram.
printf("src %x dst %x sport %x dport %x\n",
ui
->ui_src
.s_addr
, ui
->ui_dst
.s_addr
, ui
->ui_sport
, ui
->ui_dport
);
ui
->ui_src
, ui
->ui_sport
, ui
->ui_dst
, ui
->ui_dport
);
printf("pcb not found\n");
* Construct sockaddr format source address.
* Stuff source address and datagram in user buffer.
udp_in
.sin_port
= ui
->ui_sport
;
udp_in
.sin_addr
= ui
->ui_src
;
m
->m_len
-= sizeof (struct udpiphdr
);
m
->m_off
+= sizeof (struct udpiphdr
);
if (sbappendaddr(&inp
->inp_socket
->so_rcv
, (struct sockaddr
*)&udp_in
, m
) == 0)
sorwakeup(inp
->inp_socket
);
printf("udp_ctlinput\n");
register struct udpiphdr
*ui
;
* Calculate data length and get a mbuf
* for udp and ip headers.
for (m
= m0
; m
; m
= m
->m_next
)
printf("udp_output len %d: ", len
);
* Fill in mbuf with extended udp header
* and addresses and length put into network format.
m
->m_off
= MMAXOFF
- sizeof (struct udpiphdr
);
m
->m_len
= sizeof (struct udpiphdr
);
ui
= mtod(m
, struct udpiphdr
*);
ui
->ui_next
= ui
->ui_prev
= 0;
ui
->ui_len
= sizeof (struct udpiphdr
) + len
;
ui
->ui_src
= inp
->inp_laddr
;
ui
->ui_dst
= inp
->inp_faddr
;
ui
->ui_sport
= inp
->inp_lport
;
ui
->ui_dport
= inp
->inp_fport
;
ui
->ui_ulen
= htons((u_short
)len
);
printf("src %x dst %x sport %x dport %x",
ui
->ui_src
.s_addr
, ui
->ui_dst
.s_addr
, ui
->ui_sport
, ui
->ui_dport
);
* Stuff checksum and output datagram.
ui
->ui_sum
= inet_cksum(m
, sizeof (struct udpiphdr
) + len
);
printf(" cksum %x\n", ui
->ui_sum
);
((struct ip
*)ui
)->ip_len
= sizeof (struct udpiphdr
) + len
;
((struct ip
*)ui
)->ip_ttl
= MAXTTL
;
udp_usrreq(so
, req
, m
, addr
)
struct inpcb
*inp
= sotoinpcb(so
);
printf("udp_usrreq %x %s\n", inp
, prurequests
[req
]);
if (inp
== 0 && req
!= PRU_ATTACH
) {
printf("inp == 0 not on ATTACH\n");
error
= in_pcballoc(so
, &udb
, 2048, 2048, (struct sockaddr_in
*)addr
);
printf("in_pcballoc failed %d\n", error
);
if (inp
->inp_faddr
.s_addr
)
error
= in_pcbsetpeer(inp
, (struct sockaddr_in
*)addr
);
printf("in_pcbsetpeer failed %d\n", error
);
if (inp
->inp_faddr
.s_addr
== 0)
inp
->inp_faddr
.s_addr
= 0;
if (inp
->inp_faddr
.s_addr
)
error
= in_pcbsetpeer(inp
, (struct sockaddr_in
*)addr
);
printf("send setpeer failed %d\n", error
);
if (inp
->inp_faddr
.s_addr
== 0)
printf("udp send m %x m_len %d * %c (%o)\n",
m
, m
->m_len
, *(mtod(m
, caddr_t
)), *(mtod(m
, caddr_t
)));
inp
->inp_faddr
.s_addr
= 0;