📄 dhcpccommonlib.c
字号:
if (msglen > pReqSpec->maxlen) { /* * Option field is full. New option would either exceed MTU size * or overflow the transmit buffer. */ errno = S_dhcpcLib_OPTION_NOT_STORED; return (ERROR); } pReqSpec->reqlist.list [pReqSpec->reqlist.len++] = option; return (OK); }/********************************************************************************* dhcpcOptionAdd - add an option to the client messages** This routine inserts option tags and associated values into the body of* all outgoing messages for the lease indicated by the <pCookie> parameter.* Each lease can accept option data up to the MTU size of the underlying* interface, minus the link-level header size and the additional 283 bytes* required for a minimum DHCP message (including mandatory options).** The <option> parameter specifies an option tag defined in RFC 2132. See* the dhcp/dhcp.h include file for a listing of defined aliases for the* available option tags. This routine will not accept the following <option>* values, which are used for control purposes and cannot be included* arbitrarily:** _DHCP_PAD_TAG* _DHCP_OPT_OVERLOAD_TAG* _DHCP_MSGTYPE_TAG* _DHCP_SERVER_ID_TAG* _DHCP_MAXMSGSIZE_TAG* _DHCP_END_TAG** This routine also will not accept <option> values 62 or 63, which are not* currently defined.** The <length> parameter indicates the number of bytes in the option body* provided by the <pData> parameter. ** The maximum length of the option field in a DHCP message depends on the* MTU size of the associated interface and the maximum DHCP message size set* during the DHCP library initialization. These option settings share that* field with any option request list created through the dhcpcOptionSet()* routine. Options which exceed the limit will not be stored.** Each call to this routine with the same <option> value usually replaces* the value of the existing option, if any. However, the routine will append* the new data for the <option> values which contain variable length lists,* corresponding to tags 3-11, 21, 25, 33, 41-45, 48-49, 55, 65, and 68-76.** WARNING: The _DHCP_REQ_LIST_TAG <option> value (55) will replace* any existing list created with the dhcpcOptionSet() routine.** RETURNS: OK if the option was inserted successfully, or ERROR if the option* is invalid or storage failed.** ERRNO: S_dhcpcLib_BAD_OPTION, S_dhcpcLib_OPTION_NOT_STORED**/STATUS dhcpcOptionAdd ( void * pCookie, /* identifier returned by dhcpcInit() */ UCHAR option, /* RFC 2132 tag of desired option */ int length, /* length of option data */ UCHAR * pData /* option data */ ) { LEASE_DATA * pLeaseData; struct dhcp_reqspec * pReqSpec; char * pDest; struct dhcpcOpts * pOptList; int msglen = 0; /* Length of DHCP message after inserting option */ /* * Use the cookie to access the lease-specific data structures. For now, * just typecast the cookie. This translation could be replaced with a more * sophisticated lookup at some point. */ pLeaseData = (LEASE_DATA *)pCookie; pReqSpec = &pLeaseData->leaseReqSpec; /* Check for restricted or invalid options. */ switch (option) { 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_MAXMSGSIZE_TAG: /* fall-through */ case _DHCP_END_TAG: errno = S_dhcpcLib_BAD_OPTION; return (ERROR); break; default: break; } if (option == 62 || option == 63) { errno = S_dhcpcLib_BAD_OPTION; return (ERROR); } /* * Verify that the option won't exceed the MTU size for a message. * Start with an initial length equal to the UDP and IP headers and * the fixed-length portion of a DHCP message. */ msglen = UDPHL + IPHL + (DFLTDHCPLEN - DFLTOPTLEN); /* Include size of existing options and option request list. */ pOptList = pReqSpec->pOptList; if (pOptList) msglen += pReqSpec->pOptList->optlen; if (option == _DHCP_REQ_LIST_TAG) /* Replacing request list? */ msglen -= pReqSpec->reqlist.len; else msglen += pReqSpec->reqlist.len; /* * Include space for required magic cookie (4 bytes), message * type option (3 bytes), maximum message size (4 bytes), and * server identifier option (6 bytes). */ msglen += 17; /* Include space for required requested IP address option (6 bytes). */ msglen += 6; /* Add size of any other option (don't double-count IP address). */ if (option != _DHCP_REQUEST_IPADDR_TAG) msglen += length + 2; /* +2 includes tag and length values */ if (msglen > dhcpcBufSize) { /* Option field is full. New option would overflow transmit buffer. */ errno = S_dhcpcLib_OPTION_NOT_STORED; return (ERROR); } if (msglen > pReqSpec->maxlen) { /* * Option field is full. New option would either exceed MTU size * or overflow the transmit buffer. */ errno = S_dhcpcLib_OPTION_NOT_STORED; return (ERROR); } if (pData == NULL) { errno = S_dhcpcLib_BAD_OPTION; return (ERROR); } /* Validate the length of each option. */ switch (option) { /* 1 byte values */ case _DHCP_IP_FORWARD_TAG: /* Option Tag 19 */ case _DHCP_NONLOCAL_SRCROUTE_TAG: /* Option Tag 20 */ case _DHCP_DEFAULT_IP_TTL_TAG: /* Option Tag 23 */ case _DHCP_ALL_SUBNET_LOCAL_TAG: /* Option Tag 27 */ case _DHCP_MASK_DISCOVER_TAG: /* Option Tag 29 */ case _DHCP_MASK_SUPPLIER_TAG: /* Option Tag 30 */ case _DHCP_ROUTER_DISCOVER_TAG: /* Option Tag 31 */ case _DHCP_TRAILER_TAG: /* Option Tag 34 */ case _DHCP_ETHER_ENCAP_TAG: /* Option Tag 36 */ case _DHCP_DEFAULT_TCP_TTL_TAG: /* Option Tag 37 */ case _DHCP_KEEPALIVE_GARBAGE_TAG: /* Option Tag 39 */ case _DHCP_NB_NODETYPE_TAG: /* Option Tag 46 */ if (length != 1) { errno = S_dhcpcLib_BAD_OPTION; return (ERROR); } break; /* 2 byte values */ case _DHCP_BOOTSIZE_TAG: /* Option Tag 13 */ case _DHCP_MAX_DGRAM_SIZE_TAG: /* Option Tag 22 */ case _DHCP_IF_MTU_TAG: /* Option Tag 26 */ if (length != 2) { errno = S_dhcpcLib_BAD_OPTION; return (ERROR); } break; /* 4 byte values */ case _DHCP_SUBNET_MASK_TAG: /* Option Tag 1 */ case _DHCP_TIME_OFFSET_TAG: /* Option Tag 2 */ case _DHCP_SWAP_SERVER_TAG: /* Option Tag 16 */ case _DHCP_MTU_AGING_TIMEOUT_TAG: /* Option Tag 24 */ case _DHCP_BRDCAST_ADDR_TAG: /* Option Tag 28 */ case _DHCP_ROUTER_SOLICIT_TAG: /* Option Tag 32 */ case _DHCP_ARP_CACHE_TIMEOUT_TAG: /* Option Tag 35 */ case _DHCP_KEEPALIVE_INTERVAL_TAG: /* Option Tag 38 */ case _DHCP_REQUEST_IPADDR_TAG: /* Option Tag 50 */ case _DHCP_LEASE_TIME_TAG: /* Option Tag 51 */ case _DHCP_T1_TAG: /* Option Tag 58 */ case _DHCP_T2_TAG: /* Option Tag 59 */ if (length != 4) { errno = S_dhcpcLib_BAD_OPTION; return (ERROR); } break; /* Table entries (2 bytes each) */ case _DHCP_MTU_PLATEAU_TABLE_TAG: /* Option Tag 25 */ if (length % 2) { errno = S_dhcpcLib_BAD_OPTION; return (ERROR); } break; /* Address values (4 bytes each) */ case _DHCP_ROUTER_TAG: /* Option Tag 3 */ case _DHCP_TIME_SERVER_TAG: /* Option Tag 4 */ case _DHCP_NAME_SERVER_TAG: /* Option Tag 5 */ case _DHCP_DNS_SERVER_TAG: /* Option Tag 6 */ case _DHCP_LOG_SERVER_TAG: /* Option Tag 7 */ case _DHCP_COOKIE_SERVER_TAG: /* Option Tag 8 */ case _DHCP_LPR_SERVER_TAG: /* Option Tag 9 */ case _DHCP_IMPRESS_SERVER_TAG: /* Option Tag 10 */ case _DHCP_RLS_SERVER_TAG: /* Option Tag 11 */ case _DHCP_NIS_SERVER_TAG: /* Option Tag 41 */ case _DHCP_NTP_SERVER_TAG: /* Option Tag 42 */ case _DHCP_NBN_SERVER_TAG: /* Option Tag 44 */ case _DHCP_NBDD_SERVER_TAG: /* Option Tag 45 */ case _DHCP_XFONT_SERVER_TAG: /* Option Tag 48 */ case _DHCP_XDISPLAY_MANAGER_TAG: /* Option Tag 49 */ case _DHCP_NISP_SERVER_TAG: /* Option Tag 65 */ case _DHCP_MOBILEIP_HA_TAG: /* Option Tag 68 */ case _DHCP_SMTP_SERVER_TAG: /* Option Tag 69 */ case _DHCP_POP3_SERVER_TAG: /* Option Tag 70 */ case _DHCP_NNTP_SERVER_TAG: /* Option Tag 71 */ case _DHCP_DFLT_WWW_SERVER_TAG: /* Option Tag 72 */ case _DHCP_DFLT_FINGER_SERVER_TAG: /* Option Tag 73 */ case _DHCP_DFLT_IRC_SERVER_TAG: /* Option Tag 74 */ case _DHCP_STREETTALK_SERVER_TAG: /* Option Tag 75 */ case _DHCP_STDA_SERVER_TAG: /* Option Tag 76 */ if (length % 4) { errno = S_dhcpcLib_BAD_OPTION; return (ERROR); } break; /* Address pairs or address/mask values (8 bytes each). */ case _DHCP_POLICY_FILTER_TAG: /* Option Tag 21 */ case _DHCP_STATIC_ROUTE_TAG: /* Option Tag 33 */ if (length % 8) { errno = S_dhcpcLib_BAD_OPTION; return (ERROR); } break; /* Variable-length values */ case _DHCP_HOSTNAME_TAG: /* Option Tag 12 */ case _DHCP_MERIT_DUMP_TAG: /* Option Tag 14 */ case _DHCP_DNS_DOMAIN_TAG: /* Option Tag 15 */ case _DHCP_ROOT_PATH_TAG: /* Option Tag 17 */ case _DHCP_EXTENSIONS_PATH_TAG: /* Option Tag 18 */ case _DHCP_NIS_DOMAIN_TAG: /* Option Tag 40 */ case _DHCP_VENDOR_SPEC_TAG: /* Option Tag 43 */ case _DHCP_NB_SCOPE_TAG: /* Option Tag 47 */ case _DHCP_REQ_LIST_TAG: /* Option Tag 55 */ case _DHCP_ERRMSG_TAG: /* Option Tag 56 */ case _DHCP_CLASS_ID_TAG: /* Option Tag 60 */ case _DHCP_CLIENT_ID_TAG: /* Option Tag 61 */ case _DHCP_NISP_DOMAIN_TAG: /* Option Tag 64 */ case _DHCP_TFTP_SERVERNAME_TAG: /* Option Tag 66 */ case _DHCP_BOOTFILE_TAG: /* Option Tag 67 */ if (length < 1 || length > _DHCP_MAX_OPTLEN) { errno = S_dhcpcLib_BAD_OPTION; return (ERROR); } break; } /* Store the option body in the space provided. */ if (pOptList == NULL) { pOptList = malloc (sizeof (struct dhcpcOpts)); if (pOptList == NULL) { errno = S_dhcpcLib_OPTION_NOT_STORED; return (ERROR); } bzero ( (char *)pOptList, sizeof (struct dhcpcOpts)); pReqSpec->pOptList = pOptList; } switch (option) { /* 1 byte values */ case _DHCP_IP_FORWARD_TAG: /* Option Tag 19 */ pOptList->tag19 = *pData; break; case _DHCP_NONLOCAL_SRCROUTE_TAG: /* Option Tag 20 */ pOptList->tag20 = *pData; break; case _DHCP_DEFAULT_IP_TTL_TAG: /* Option Tag 23 */ pOptList->tag23 = *pData; break; case _DHCP_ALL_SUBNET_LOCAL_TAG: /* Option Tag 27 */ pOptList->tag27 = *pData; break; case _DHCP_MASK_DISCOVER_TAG: /* Option Tag 29 */ pOptList->tag29 = *pData; break; case _DHCP_MASK_SUPPLIER_TAG: /* Option Tag 30 */ pOptList->tag30 = *pData; break; case _DHCP_ROUTER_DISCOVER_TAG: /* Option Tag 31 */ pOptList->tag31 = *pData; break; case _DHCP_TRAILER_TAG: /* Option Tag 34 */ pOptList->tag34 = *pData; break; case _DHCP_ETHER_ENCAP_TAG: /* Option Tag 36 */ pOptList->tag36 = *pData; break; case _DHCP_DEFAULT_TCP_TTL_TAG: /* Option Tag 37 */ pOptList->tag37 = *pData; break; case _DHCP_KEEPALIVE_GARBAGE_TAG: /* Option Tag 39 */ pOptList->tag39 = *pData; break; case _DHCP_NB_NODETYPE_TAG: /* Option Tag 46 */ pOptList->tag46 = *pData; break; /* 2 byte values */ case _DHCP_BOOTSIZE_TAG: /* Option Tag 13 */ bcopy (pData, (char *)&pOptList->tag13, sizeof (USHORT));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -