📄 dhcpcbootlib.c
字号:
* for the vendor class identifier.* .IP _DHCP_CLIENT_ID_TAG* The <data> parameter points to <length> bytes used as the value * of a type/value pair.* .IP* The data parameter should be NULL for all other options.** NOTE: With the exception of the _DHCP_ERR_MSG_TAG option, the DHCP * specification forbids changing options after a lease has been * established. Therefore, this routine should not be used after the * dhcpcBootBind() call. Changing any option other than the error message at* that point could have unpredictable results.** RETURNS: OK if option set successfully, or ERROR if option is invalid or * storage failed.** ERRNO: N/A*/STATUS dhcpcBootOptionSet ( int option, /* RFC 1533 tag of desired option */ long value, /* numeric value for option */ long length, /* length of data (if any) or 0 if unused */ char * pData /* option data, or NULL if none */ ) { u_long result; switch (option) /* Check for restricted options. */ { case _DHCP_PAD_TAG: /* fall-through */ case _DHCP_OPT_OVERLOAD_TAG: /* fall-through */ case _DHCP_MSGTYPE_TAG: /* fall-through */ case _DHCP_SERVER_ID_TAG: /* fall-through */ case _DHCP_REQ_LIST_TAG: /* fall-through */ case _DHCP_MAXMSGSIZE_TAG: /* fall-through */ case _DHCP_END_TAG: return (ERROR); break; default: break; } if (option < 0 || option > _DHCP_LAST_OPTION) { return (ERROR); } if (dhcpcBootReqSpec.reqlist.len == _DHCP_MAX_OPTLEN) { switch (option) /* Ignore error for options not in request list. */ { case _DHCP_VENDOR_SPEC_TAG: /* fall-through */ case _DHCP_REQUEST_IPADDR_TAG: /* fall-through */ case _DHCP_LEASE_TIME_TAG: /* fall-through */ case _DHCP_ERRMSG_TAG: /* fall-through */ case _DHCP_CLASS_ID_TAG: /* fall-through */ case _DHCP_CLIENT_ID_TAG: /* fall-through */ break; default: /* Request list is full. */ return (ERROR); break; } } switch (option) { case _DHCP_VENDOR_SPEC_TAG: if (length < 1 || length > _DHCP_MAX_OPTLEN) { return (ERROR); } if (pData == NULL) { return (ERROR); } bcopy (pData, dhcpcBootReqSpec.vendlist.list, (int)length); dhcpcBootReqSpec.vendlist.len = (u_char)length; break; case _DHCP_REQUEST_IPADDR_TAG: result = inet_addr (pData); if (result == ERROR) { return (ERROR); } dhcpcBootReqSpec.ipaddr.s_addr = result; break; case _DHCP_LEASE_TIME_TAG: dhcpcBootReqSpec.lease = value; break; case _DHCP_ERRMSG_TAG: dhcpcBootReqSpec.dhcp_errmsg = pData; break; case _DHCP_CLASS_ID_TAG: if (length < 1 || length > _DHCP_MAX_OPTLEN) { return (ERROR); } if (pData == NULL) { return (ERROR); } dhcpcBootReqSpec.classId = calloc (1, sizeof (struct class_id)); if (dhcpcBootReqSpec.classId == NULL) { return (ERROR); } dhcpcBootReqSpec.classId->id = calloc (length, sizeof(char)); if (dhcpcBootReqSpec.classId->id == NULL) { return (ERROR); } bcopy (pData, dhcpcBootReqSpec.classId->id, (int)length); dhcpcBootReqSpec.classId->len = (u_char)length; break; case _DHCP_CLIENT_ID_TAG: if (length < 1 || length > _DHCP_MAX_OPTLEN) { return (ERROR); } if (pData == NULL) { return (ERROR); } dhcpcBootReqSpec.clid = calloc (1, sizeof (struct class_id)); if (dhcpcBootReqSpec.clid == NULL) { return (ERROR); } dhcpcBootReqSpec.clid->id = calloc (length, sizeof(char)); if (dhcpcBootReqSpec.clid->id == NULL) { return (ERROR); } bcopy (pData, dhcpcBootReqSpec.clid->id, (int)length); dhcpcBootReqSpec.clid->len = (unsigned char)length; dhcpcBootReqSpec.clid->type = (unsigned char)value; break; default: dhcpcBootReqSpec.reqlist.list [dhcpcBootReqSpec.reqlist.len++] = option; break; } return (OK); }/********************************************************************************* dhcpcBootMsgSetup - prepare packets for examination** This routine initializes incoming ethernet traffic for examination by * the WIDE-project DHCP implementation. It is called by internal routines * seeking a particular type of DHCP message.** RETURNS: OK if processing completed, or ERROR if not a DHCP message.** ERRNO: N/A** NOMANUAL*/ LOCAL STATUS dhcpcBootMsgSetup ( char * pInput, /* contents of received packet */ int length /* length of received packet */ ) { struct ether_header * pEtherHdr; /* pointer to ethernet header */ struct ip * pIpHdr; /* pointer to IP header */ struct udphdr * pUdpHdr; /* pointer to UDP header */ pEtherHdr = (struct ether_header *)pInput; pIpHdr = (struct ip *)&pInput [SIZEOF_ETHERHEADER];#if BSD<44 pUdpHdr = (struct udphdr *)&pInput [SIZEOF_ETHERHEADER + (pIpHdr->ip_v_hl & 0xf) * _BYTESPERWORD];#else pUdpHdr = (struct udphdr *) &pInput [SIZEOF_ETHERHEADER + pIpHdr->ip_hl * _BYTESPERWORD];#endif if (length <= SIZEOF_ETHERHEADER) return (ERROR); if (ntohs (pEtherHdr->ether_type) != ETHERTYPE_IP) return (ERROR); if (pIpHdr->ip_p != IPPROTO_UDP) return (ERROR); if (pUdpHdr->uh_dport != dhcpc_port) return (ERROR); /* * Copy the input packet one byte at a time to accomodate board * specific memory access requirements. Use offset to provide * 4-byte alignment of IP header needed by Sun BSP's. */ bcopyBytes (pInput, &pDhcpcRbuf [DHCPC_OFF], length); /* WIDE project DHCP code: initializes pointers. */ msgAlign (&dhcpcRbufMsg, &pDhcpcRbuf [DHCPC_OFF]); return (OK); }/******************************************************************************** dhcpcBootDefaultsSet - assign host requirements defaults for client** This routine fills the client's parameters structure with the default* values specified in the Host Requirements Documents (RFC's 1122 and 1123),* the Path MTU Discovery description (RFC 1191), or the Router Discovery* specification (RFC 1256). This data is assigned before processing a message * received from a DHCP server, so that it can override the defaults.** ERRNO: N/A** RETURNS: N/A** NOMANUAL*/void dhcpcBootDefaultsSet ( struct dhcp_param * newParam ) { /* Default IP layer parameters, per host. */ newParam->ip_forward = FALSE; newParam->nonlocal_srcroute = FALSE; newParam->max_dgram_size = _HRD_MAX_DGRAM; newParam->default_ip_ttl = _HRD_IP_TTL; /* Default IP layer parameters, per interface. */ newParam->intf_mtu = _HRD_MTU; newParam->all_subnet_local = FALSE; newParam->mask_discover = FALSE; newParam->mask_supplier = FALSE; newParam->router_discover = TRUE; newParam->router_solicit.s_addr = _HRD_ROUTER; /* Default link layer parameters, per interface. */ newParam->trailer = FALSE; newParam->arp_cache_timeout = _HRD_ARP_TIME; newParam->ether_encap = FALSE; /* Default link layer parameters, per host. */ newParam->default_tcp_ttl = _HRD_TCP_TTL; newParam->keepalive_inter = _HRD_TCP_TIME; newParam->keepalive_garba = FALSE; }/******************************************************************************** dhcpcBootReplyInputHook - boot time packet filter for ACK and NAK messages** This routine filters out DHCPACK and DHCPNAK messages from incoming Ethernet * traffic. It is called by the network interface driver when a new input frame * comes in from the network. It is attached to the network driver with * `etherHook' routines.** ERRNO: N/A** RETURNS: TRUE if the Ethernet frame is handled by this routine. No further* processing by the network driver is needed.* FALSE if the frame is not a server response. The Ethernet frame is* then handled by the network driver.** NOMANUAL*/ BOOL dhcpcBootReplyInputHook ( struct ifnet * pIf, /* interface where packet was received */ char * pInput, /* contents of received packet */ int length /* length of received packet */ ) { int retVal; /* Return values */ EVENT_DATA newEvent; /* Adjust message size (ignores trailers added by some drivers). */ if (length > DHCP_MSG_SIZE) length = DHCP_MSG_SIZE; retVal = dhcpcBootMsgSetup (pInput, length); if (retVal != OK) return (FALSE); /* * WIDE project DHCP code: check the packet for the correct format. * (Alters received message - must return TRUE to network driver). */ retVal = check_requesting(); if (retVal == 1) { /* Signal WIDE project DHCP code when a valid message arrives. */ newEvent.type = DHCP_MSG_ARRIVED; newEvent.length = length; semTake (dhcpcBootRingSem, WAIT_FOREVER); retVal = rngBufPut (dhcpcBootEventRing, (char *) &newEvent, sizeof(newEvent)); semGive (dhcpcBootRingSem); if (retVal == sizeof (newEvent)) { /* Ignore storage error - notifications with no message are OK. */ rngBufPut (dhcpcBootMsgRing, pInput, length); semGive (dhcpcBootEventSem); } } return (TRUE); }/******************************************************************************** dhcpcBootOfferInputHook - boot time packet filter for DHCPOFFER messages** This routine filters out DHCPOFFER messages from incoming ethernet traffic. * It is called by the network interface driver when a new input frame comes * in from the network. It is attached to the network driver with etherHook * routines.** ERRNO: N/A** RETURNS: TRUE if the ethernet frame is handled by this routine. No further* processing by the network driver is needed.* FALSE if the frame is not a DHCPOFFER. The ethernet frame is then* handled by the network driver.** NOMANUAL*/ BOOL dhcpcBootOfferInputHook ( struct ifnet * pIf, /* interface where packet was received */ char * pInput, /* contents of received packet */ int length /* length of received packet */ ) { int status; /* valid DHCPOFFER message? */ EVENT_DATA newEvent; /* Adjust message size (ignores trailers added by some drivers). */ if (length > DHCP_MSG_SIZE) length = DHCP_MSG_SIZE; status = dhcpcBootMsgSetup (pInput, length); if (status != OK) return (FALSE); /* * WIDE project DHCP code: check the packet for the correct format. */ status = check_wait_offer (); if (status != 0) { /* Signal WIDE project DHCP code when a valid message arrives. */ newEvent.type = DHCP_MSG_ARRIVED; newEvent.length = length; semTake (dhcpcBootRingSem, WAIT_FOREVER); status = rngBufPut (dhcpcBootEventRing, (char *) &newEvent, sizeof(newEvent)); semGive (dhcpcBootRingSem); if (status == sizeof (newEvent)) { /* Ignore storage error - notifications with no message are OK. */ rngBufPut (dhcpcBootMsgRing, pInput, length); semGive (dhcpcBootEventSem); } } return (TRUE); }/******************************************************************************** dhcpcBootArpInputHook - boot time packet filter for ARP replies*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -