static ssize_t bootprecv(struct iodesc *d, void *pkt, size_t len, saseconds_t tleft) { ssize_t n; struct bootp *bp; #ifdef BOOTP_DEBUGx if (debug) printf("bootp_recvoffer: called\n"); #endif n = readudp(d, pkt, len, tleft); if (n == -1 || (size_t)n < sizeof(struct bootp) - BOOTP_VENDSIZE) goto bad; bp = (struct bootp *)pkt; #ifdef BOOTP_DEBUG if (debug) printf("bootprecv: checked. bp = 0x%lx, n = %d\n", (long)bp, (int)n); #endif if (bp->bp_xid != htonl(d->xid)) { #ifdef BOOTP_DEBUG if (debug) { printf("bootprecv: expected xid 0x%lx, got 0x%x\n", d->xid, ntohl(bp->bp_xid)); } #endif goto bad; } /* protect against bogus addresses sent by DHCP servers */ if (bp->bp_yiaddr.s_addr == INADDR_ANY || bp->bp_yiaddr.s_addr == INADDR_BROADCAST) goto bad; #ifdef BOOTP_DEBUG if (debug) printf("bootprecv: got one!\n"); #endif /* Suck out vendor info */ if (memcmp(vm_rfc1048, bp->bp_vend, sizeof(vm_rfc1048)) == 0) { if (vend_rfc1048(bp->bp_vend, sizeof(bp->bp_vend)) != 0) goto bad; } #ifdef BOOTP_VEND_CMU else if (memcmp(vm_cmu, bp->bp_vend, sizeof(vm_cmu)) == 0) vend_cmu(bp->bp_vend); #endif else printf("bootprecv: unknown vendor 0x%lx\n", (long)bp->bp_vend); return n; bad: errno = 0; return -1; }
static ssize_t bootprecv(struct iodesc *d, void *pkt, size_t len, time_t tleft) { ssize_t n; struct bootp *bp; #ifdef BOOTP_DEBUGx if (debug) printf("bootp_recvoffer: called\n"); #endif n = readudp(d, pkt, len, tleft); if (n == -1 || n < sizeof(struct bootp) - BOOTP_VENDSIZE) goto bad; bp = (struct bootp *)pkt; #ifdef BOOTP_DEBUG if (debug) printf("bootprecv: checked. bp = 0x%lx, n = %d\n", (long)bp, (int)n); #endif if (bp->bp_xid != htonl(d->xid)) { #ifdef BOOTP_DEBUG if (debug) { printf("bootprecv: expected xid 0x%lx, got 0x%x\n", d->xid, ntohl(bp->bp_xid)); } #endif goto bad; } #ifdef BOOTP_DEBUG if (debug) printf("bootprecv: got one!\n"); #endif /* Suck out vendor info */ if (bcmp(vm_rfc1048, bp->bp_vend, sizeof(vm_rfc1048)) == 0) { if(vend_rfc1048(bp->bp_vend, sizeof(bp->bp_vend)) != 0) goto bad; } #ifdef BOOTP_VEND_CMU else if (bcmp(vm_cmu, bp->bp_vend, sizeof(vm_cmu)) == 0) vend_cmu(bp->bp_vend); #endif else printf("bootprecv: unknown vendor 0x%lx\n", (long)bp->bp_vend); return(n); bad: errno = 0; return (-1); }
static errno_t bootprecv( struct bootp_state *bstate, void *udp_sock, struct bootp *bp, size_t len, size_t *retlen ) { SHOW_FLOW0( 3, "bootp_recv"); sockaddr dest_addr; dest_addr.port = IPPORT_BOOTPS; // dest port dest_addr.addr.len = 4; dest_addr.addr.type = ADDR_TYPE_IP; // INADDR_BROADCAST //NETADDR_TO_IPV4(dest_addr.addr) = IPV4_DOTADDR_TO_ADDR(0xFF, 0xFF, 0xFF, 0xFF); NETADDR_TO_IPV4(dest_addr.addr) = IPV4_DOTADDR_TO_ADDR(0, 0, 0, 0); int n = udp_recvfrom(udp_sock, bp, len, &dest_addr, SOCK_FLAG_TIMEOUT, 2000000l); if( 0 >= n ) { SHOW_ERROR( 0, "UDP recv err = %d", n); return ETIMEDOUT; // TODO errno } if (n == -1 || n < (int)(sizeof(struct bootp) - BOOTP_VENDSIZE)) goto bad; SHOW_FLOW( 3, "bootprecv: recv %d bytes", n); if (bp->bp_xid != htonl(xid)) { SHOW_ERROR( 1, "bootprecv: expected xid 0x%x, got 0x%x", xid, ntohl(bp->bp_xid)); goto bad; } SHOW_FLOW0( 3, "bootprecv: got one!"); /* Suck out vendor info */ if (bcmp(vm_rfc1048, bp->bp_vend, sizeof(vm_rfc1048)) == 0) { if(vend_rfc1048(bstate, bp->bp_vend, sizeof(bp->bp_vend)) != 0) goto bad; } #ifdef BOOTP_VEND_CMU else if (bcmp(vm_cmu, bp->bp_vend, sizeof(vm_cmu)) == 0) vend_cmu(bstate,bp->bp_vend); #endif else SHOW_ERROR( 0, "bootprecv: unknown vendor 0x%lx", (long)bp->bp_vend); if(retlen) *retlen = n; return 0; bad: //errno = 0; return EINVAL; }
/* Returns 0 if this is the packet we're waiting for else -1 (and errno == 0) */ static ssize_t bootprecv(struct iodesc *d, void *pkt, size_t len, time_t tleft) { ssize_t n; struct bootp *bp; #ifdef BOOTP_DEBUG if (debug) printf("bootprecv: called\n"); #endif n = readudp(d, pkt, len, tleft); if (n < 0 || (size_t)n < sizeof(struct bootp)) goto bad; bp = (struct bootp *)pkt; #ifdef BOOTP_DEBUG if (debug) printf("bootprecv: checked. bp = 0x%x, n = %d\n", (unsigned)bp, n); #endif if (bp->bp_xid != htonl(d->xid)) { #ifdef BOOTP_DEBUG if (debug) { printf("bootprecv: expected xid 0x%lx, got 0x%lx\n", d->xid, ntohl(bp->bp_xid)); } #endif goto bad; } #ifdef BOOTP_DEBUG if (debug) printf("bootprecv: got one!\n"); #endif /* Pick up our ip address (and natural netmask) */ myip = d->myip = bp->bp_yiaddr; #ifdef BOOTP_DEBUG if (debug) printf("our ip address is %s\n", inet_ntoa(d->myip)); #endif if (IN_CLASSA(d->myip.s_addr)) nmask = IN_CLASSA_NET; else if (IN_CLASSB(d->myip.s_addr)) nmask = IN_CLASSB_NET; else nmask = IN_CLASSC_NET; #ifdef BOOTP_DEBUG if (debug) printf("'native netmask' is %s\n", intoa(nmask)); #endif /* Pick up root or swap server address and file spec. */ if (bp->bp_siaddr.s_addr != 0) rootip = bp->bp_siaddr; if (bp->bp_file[0] != '\0') { strncpy(bootfile, (char *)bp->bp_file, sizeof(bootfile)); bootfile[sizeof(bootfile) - 1] = '\0'; } /* Suck out vendor info */ if (bcmp(vm_cmu, bp->bp_vend, sizeof(vm_cmu)) == 0) vend_cmu(bp->bp_vend); else if (bcmp(vm_rfc1048, bp->bp_vend, sizeof(vm_rfc1048)) == 0) vend_rfc1048(bp->bp_vend, sizeof(bp->bp_vend)); else printf("bootprecv: unknown vendor 0x%lx\n", (long)bp->bp_vend); /* Check subnet mask against net mask; toss if bogus */ if ((nmask & smask) != nmask) { #ifdef BOOTP_DEBUG if (debug) printf("subnet mask (%s) bad\n", intoa(smask)); #endif smask = 0; } /* Get subnet (or natural net) mask */ netmask = nmask; if (smask) netmask = smask; #ifdef BOOTP_DEBUG if (debug) printf("mask: %s\n", intoa(netmask)); #endif /* We need a gateway if root or swap is on a different net */ if (!SAMENET(d->myip, rootip, netmask)) { #ifdef BOOTP_DEBUG if (debug) printf("need gateway for root ip\n"); #endif } if (!SAMENET(d->myip, swapip, netmask)) { #ifdef BOOTP_DEBUG if (debug) printf("need gateway for swap ip\n"); #endif } /* Toss gateway if on a different net */ if (!SAMENET(d->myip, gateip, netmask)) { #ifdef BOOTP_DEBUG if (debug) printf("gateway ip (%s) bad\n", inet_ntoa(gateip)); #endif gateip.s_addr = 0; } return (n); bad: errno = 0; return (-1); }