aboutsummaryrefslogtreecommitdiff
path: root/lib/libstand/udp.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libstand/udp.c')
-rw-r--r--lib/libstand/udp.c136
1 files changed, 19 insertions, 117 deletions
diff --git a/lib/libstand/udp.c b/lib/libstand/udp.c
index 2eba7a18eefc..02ac62571fb7 100644
--- a/lib/libstand/udp.c
+++ b/lib/libstand/udp.c
@@ -62,9 +62,8 @@ ssize_t
sendudp(struct iodesc *d, void *pkt, size_t len)
{
ssize_t cc;
- struct ip *ip;
+ struct udpiphdr *ui;
struct udphdr *uh;
- u_char *ea;
#ifdef NET_DEBUG
if (debug) {
@@ -78,52 +77,31 @@ sendudp(struct iodesc *d, void *pkt, size_t len)
}
#endif
- uh = (struct udphdr *)pkt - 1;
- ip = (struct ip *)uh - 1;
- len += sizeof(*ip) + sizeof(*uh);
-
- bzero(ip, sizeof(*ip) + sizeof(*uh));
+ ui = (struct udpiphdr *)pkt - 1;
+ bzero(ui, sizeof(*ui));
- ip->ip_v = IPVERSION; /* half-char */
- ip->ip_hl = sizeof(*ip) >> 2; /* half-char */
- ip->ip_len = htons(len);
- ip->ip_p = IPPROTO_UDP; /* char */
- ip->ip_ttl = IPDEFTTL; /* char */
- ip->ip_src = d->myip;
- ip->ip_dst = d->destip;
- ip->ip_sum = in_cksum(ip, sizeof(*ip)); /* short, but special */
+ uh = (struct udphdr *)pkt - 1;
+ len += sizeof(*uh);
uh->uh_sport = d->myport;
uh->uh_dport = d->destport;
- uh->uh_ulen = htons(len - sizeof(*ip));
+ uh->uh_ulen = htons(len);
-#ifndef UDP_NO_CKSUM
- {
- struct udpiphdr *ui;
- struct ip tip;
+ ui->ui_pr = IPPROTO_UDP;
+ ui->ui_len = uh->uh_ulen;
+ ui->ui_src = d->myip;
+ ui->ui_dst = d->destip;
- /* Calculate checksum (must save and restore ip header) */
- tip = *ip;
- ui = (struct udpiphdr *)ip;
- bzero(&ui->ui_x1, sizeof(ui->ui_x1));
- ui->ui_len = uh->uh_ulen;
- uh->uh_sum = in_cksum(ui, len);
- *ip = tip;
- }
+#ifndef UDP_NO_CKSUM
+ uh->uh_sum = in_cksum(ui, len + sizeof (struct ip));
#endif
- if (ip->ip_dst.s_addr == INADDR_BROADCAST || ip->ip_src.s_addr == 0 ||
- netmask == 0 || SAMENET(ip->ip_src, ip->ip_dst, netmask))
- ea = arpwhohas(d, ip->ip_dst);
- else
- ea = arpwhohas(d, gateip);
-
- cc = sendether(d, ip, len, ea, ETHERTYPE_IP);
+ cc = sendip(d, uh, len, IPPROTO_UDP);
if (cc == -1)
return (-1);
if (cc != len)
panic("sendudp: bad write (%zd != %zd)", cc, len);
- return (cc - (sizeof(*ip) + sizeof(*uh)));
+ return (cc - sizeof(*uh));
}
/*
@@ -133,10 +111,7 @@ ssize_t
readudp(struct iodesc *d, void **pkt, void **payload, time_t tleft)
{
ssize_t n;
- size_t hlen;
- struct ip *ip;
struct udphdr *uh;
- uint16_t etype; /* host order */
void *ptr;
#ifdef NET_DEBUG
@@ -144,84 +119,14 @@ readudp(struct iodesc *d, void **pkt, void **payload, time_t tleft)
printf("readudp: called\n");
#endif
- ip = NULL;
+ uh = NULL;
ptr = NULL;
- n = readether(d, &ptr, (void **)&ip, tleft, &etype);
- if (n == -1 || n < sizeof(*ip) + sizeof(*uh)) {
+ n = readip(d, &ptr, (void **)&uh, tleft, IPPROTO_UDP);
+ if (n == -1 || n < sizeof(*uh) || n != ntohs(uh->uh_ulen)) {
free(ptr);
return (-1);
}
- /* Ethernet address checks now in readether() */
-
- /* Need to respond to ARP requests. */
- if (etype == ETHERTYPE_ARP) {
- struct arphdr *ah = (void *)ip;
- if (ah->ar_op == htons(ARPOP_REQUEST)) {
- /* Send ARP reply */
- arp_reply(d, ah);
- }
- free(ptr);
- return (-1);
- }
-
- if (etype != ETHERTYPE_IP) {
-#ifdef NET_DEBUG
- if (debug)
- printf("readudp: not IP. ether_type=%x\n", etype);
-#endif
- free(ptr);
- return (-1);
- }
-
- /* Check ip header */
- if (ip->ip_v != IPVERSION ||
- ip->ip_p != IPPROTO_UDP) { /* half char */
-#ifdef NET_DEBUG
- if (debug)
- printf("readudp: IP version or not UDP. ip_v=%d ip_p=%d\n", ip->ip_v, ip->ip_p);
-#endif
- free(ptr);
- return (-1);
- }
-
- hlen = ip->ip_hl << 2;
- if (hlen < sizeof(*ip) ||
- in_cksum(ip, hlen) != 0) {
-#ifdef NET_DEBUG
- if (debug)
- printf("readudp: short hdr or bad cksum.\n");
-#endif
- free(ptr);
- return (-1);
- }
- if (n < ntohs(ip->ip_len)) {
-#ifdef NET_DEBUG
- if (debug)
- printf("readudp: bad length %d < %d.\n",
- (int)n, ntohs(ip->ip_len));
-#endif
- free(ptr);
- return (-1);
- }
- if (d->myip.s_addr && ip->ip_dst.s_addr != d->myip.s_addr) {
-#ifdef NET_DEBUG
- if (debug) {
- printf("readudp: bad saddr %s != ", inet_ntoa(d->myip));
- printf("%s\n", inet_ntoa(ip->ip_dst));
- }
-#endif
- free(ptr);
- return (-1);
- }
-
- uh = (struct udphdr *)((uintptr_t)ip + sizeof (*ip));
- /* If there were ip options, make them go away */
- if (hlen != sizeof(*ip)) {
- bcopy(((u_char *)ip) + hlen, uh, uh->uh_ulen - hlen);
- ip->ip_len = htons(sizeof(*ip));
- n -= hlen - sizeof(*ip);
- }
if (uh->uh_dport != d->myport) {
#ifdef NET_DEBUG
if (debug)
@@ -235,16 +140,13 @@ readudp(struct iodesc *d, void **pkt, void **payload, time_t tleft)
#ifndef UDP_NO_CKSUM
if (uh->uh_sum) {
struct udpiphdr *ui;
+ struct ip *ip;
struct ip tip;
n = ntohs(uh->uh_ulen) + sizeof(*ip);
- if (n > RECV_SIZE - ETHER_SIZE) {
- printf("readudp: huge packet, udp len %d\n", (int)n);
- free(ptr);
- return (-1);
- }
/* Check checksum (must save and restore ip header) */
+ ip = (struct ip *)uh - 1;
tip = *ip;
ui = (struct udpiphdr *)ip;
bzero(&ui->ui_x1, sizeof(ui->ui_x1));