/* This function provides a "select" implementation. This is added to * map the SO_RCVTIMEO functionality required for wolfSSL. */ static int nucleus_select(int sd, word32 timeout) { FD_SET readfs; /* Initialize fs data for this socket. */ NU_FD_Init(&readfs); NU_FD_Set(sd, &readfs); /* Wait for data on this socket. */ return NU_Select((sd + 1), &readfs, NU_NULL, NU_NULL, (timeout * NU_TICKS_PER_SECOND)); }
int BOOTP_Process_Packets(int16 socketd, BOOTP_STRUCT *bp, uint16 timeout) { int ret; sint x, items, len; int16 flen; char *inbuf; int16 found = 0; uint8 bootp_cookie[4] = BOOTP_COOKIE; uint32 vend_cookie; ulint local_xid; BOOTPLAYER *bootp_ptr; /* Bootp struct pointer*/ FD_SET readfs, writefs, exceptfs; STATUS status; struct addr_struct fromaddr; uchar *ptr; uint8 message[80]; /* Allocate Memory for input Buffer */ status = NU_Allocate_Memory(&System_Memory, (VOID **)&inbuf, IOSIZE, (UNSIGNED)NU_NO_SUSPEND); /* Check if an error occured during NU_Allocate_Memory */ if (status != NU_SUCCESS) { NU_Tcp_Log_Error( DHCP_NO_MEMORY, TCP_FATAL, __FILE__, __LINE__); return (NU_NO_SOCK_MEMORY); } /* Do While to process received data */ do { /* do while */ NU_FD_Init(&readfs); NU_FD_Set(socketd, &readfs); ret = NU_Select(NSOCKETS, &readfs, &writefs, &exceptfs, (timeout * TICKS_PER_SECOND)); if( ret == NU_NO_DATA ) break; if(NU_FD_Check(socketd, &readfs) == NU_FALSE) break; fromaddr.family = NU_FAMILY_IP; fromaddr.port = 0; ret = NU_Recv_From(socketd, inbuf, IOSIZE, 0, &fromaddr, &flen); if( ret < 0 ) { NU_Tcp_Log_Error( BOOTP_RECV_FAILED, TCP_FATAL, __FILE__, __LINE__); break; } /* get pointer to BOOTP packet. */ bootp_ptr = (BOOTPLAYER *)inbuf; /* Retrieve the unique ID from the packet */ memcpy(&local_xid, &bootp_ptr->bp_xid, sizeof(ulint) ); /* see if packet is the returning response to the packet I sent */ if( local_xid != bootp_xid ) continue; /* Accept the very first packet */ /* Get the Server address */ bp->bp_siaddr[0] = bootp_ptr->bp_siaddr.is_ip_addrs[0]; bp->bp_siaddr[1] = bootp_ptr->bp_siaddr.is_ip_addrs[1]; bp->bp_siaddr[2] = bootp_ptr->bp_siaddr.is_ip_addrs[2]; bp->bp_siaddr[3] = bootp_ptr->bp_siaddr.is_ip_addrs[3]; /* Get the gateway address */ bp->bp_giaddr[0] = bootp_ptr->bp_giaddr.is_ip_addrs[0]; bp->bp_giaddr[1] = bootp_ptr->bp_giaddr.is_ip_addrs[1]; bp->bp_giaddr[2] = bootp_ptr->bp_giaddr.is_ip_addrs[2]; bp->bp_giaddr[3] = bootp_ptr->bp_giaddr.is_ip_addrs[3]; /* Get my IP address */ bp->bp_yiaddr[0] = bootp_ptr->bp_yiaddr.is_ip_addrs[0]; bp->bp_yiaddr[1] = bootp_ptr->bp_yiaddr.is_ip_addrs[1]; bp->bp_yiaddr[2] = bootp_ptr->bp_yiaddr.is_ip_addrs[2]; bp->bp_yiaddr[3] = bootp_ptr->bp_yiaddr.is_ip_addrs[3]; /* Get the Server Name */ memcpy(bp->bp_sname, bootp_ptr->bp_sname, sizeof(bp->bp_sname) ); /* Get the Bootp file name. */ memcpy(bp->bp_file, bootp_ptr->bp_file, sizeof(bp->bp_file) ); /* Get the Vnedor specific cookie. */ memcpy( &vend_cookie, bootp_ptr->bp_vend, 4); /* test to see if cookie is a vendor cookie */ if (comparen (bootp_ptr->bp_vend, VM_RFC1048,4)) { if( vend_cookie == *(uint32 *)bootp_cookie ) { /* Now loop thur vendor options, passing them to user */ /* callback function. */ ptr = bootp_ptr->bp_vend + 4; found = 1; while ((*ptr != 255) && ((ptr - bootp_ptr->bp_vend) < 64)) { switch (*ptr) { case BOOTP_PAD: /* nop padding, used to align fields to word */ ptr++; /* boundries. */ break; case BOOTP_SUBNET: /* subnet mask */ len = (*(ptr + 1)); ptr += 2; bp->bp_net_mask[0] = (*ptr); bp->bp_net_mask[1] = (*(ptr + 1)); bp->bp_net_mask[2] = (*(ptr + 2)); bp->bp_net_mask[3] = (*(ptr + 3)); ptr += len; break; case BOOTP_TIMEOFF: /* time offset */ ptr += 3; break; case BOOTP_GATEWAY: /* gateways */ len = (*(ptr + 1)); items = len/4; ptr += 2; for (x = 0; x < items; x++) { ptr += 4; } break; case BOOTP_TIMESERV: /* time servers */ case BOOTP_NAMESERV: /* IEN = 116 name server */ ptr += 3; break; case BOOTP_DOMNAME: /* domain name server */ len = (*(ptr + 1)); items = len / 4; ptr += 2; for (x = 0; x < items; x++) { ptr += 4; } break; case BOOTP_LOGSERV: /* log server */ /* Place your code here. */ case BOOTP_COOKSRV: /* cookie server */ /* Place your code here. */ case BOOTP_LPRSRV: /* lpr server */ /* Place your code here. */ case BOOTP_IMPRSRV: /* impress server */ /* Place your code here. */ case BOOTP_RLPSRV: /* rlp server */ /* Place your code here. */ ptr += 3; break; case BOOTP_HOSTNAME: /* client host name */ len = (*(ptr + 1)); strncpy ((int8 *)message, (const int8 *)ptr + 2, (uint16)len); message[len] = 0; ptr += len+2; break; case BOOTP_BFILSZ: /* Bootp File Size */ ptr += 2; break; case BOOTP_END: break; default: ptr += 3; break; } /* end switch */ } /* end while */ } } } while( found == 0 ); NU_Deallocate_Memory(inbuf); return(found); } /* end BOOTP_Process_Packets */