/** Calls a callback function once for each option returned by a DHCP server. * * @param[in] data - The DHCP response data buffer to parse. * @param[in] datasz - The length of @p data. * @param[in] dhcpInfoCB - The callback function to call for each option. * @param[in] context - Callback context data. * * @return Zero on success; non-zero on failure, with errno set to * ENOTCONN (error during read), ETIMEDOUT (read timed out), * ENOMEM (out of memory error), or EINVAL (parse error). * * @internal */ static int dhcpProcessOptions(unsigned char * data, size_t datasz, DHCPInfoCallBack * dhcpInfoCB, void * context) { int err, taglen; unsigned char tag; /* validate vendor data header */ if (datasz < 4 || *data++ != DHCP_COOKIE1 || *data++ != DHCP_COOKIE2 || *data++ != DHCP_COOKIE3 || *data++ != DHCP_COOKIE4) return -1; /* invalid dhcp response */ datasz -= 4; /* account for DHCP cookie values */ /* validate and process each tag in the vendor data */ while (datasz-- > 0 && (tag = *data++) != TAG_END) { if (tag != TAG_PAD) { if (!datasz-- || (taglen = *data++) > (int)datasz) return -1; /* tag length greater than total data length */ if ((err = dhcpInfoCB(tag, data, taglen, context)) != 0) return err; datasz -= taglen; data += taglen; } } return 0; }
/*=========================================================================*/ static int dhcpProcessOptions(unsigned char *data, size_t datasz, DHCPInfoCallBack *dhcpInfoCB, void *context) /* Calls dhcpInfoCB once for each option returned by the dhcp server. Returns - zero on success, non-zero on failure errno ENOTCONN error during read ETIME read timed out ENOMEM out of memory EINVAL parse error =========================================================================*/ { int err, taglen; unsigned char tag; /* validate vendor data header */ if(datasz < 4 || *data++ != DHCP_COOKIE1 || *data++ != DHCP_COOKIE2 || *data++ != DHCP_COOKIE3 || *data++ != DHCP_COOKIE4) return -1; /* invalid dhcp response */ datasz -= 4; /* account for DHCP cookie values */ /* validate and process each tag in the vendor data */ while(datasz-- > 0 && (tag = *data++) != TAG_END) { if(tag != TAG_PAD) { if(!datasz-- || (taglen = *data++) > (int)datasz) return -1; /* tag length greater than total data length */ if((err = dhcpInfoCB(tag, data, taglen, context))) return err; datasz -= taglen; data += taglen; } } return 0; }