📄 dhcp-com.c
字号:
/* $Header: /cvsroot/dhcp-agent/dhcp-agent/src/dhcp-com.c,v 1.12 2003/06/26 13:55:09 actmodern Exp $ * * Copyright 2002 Thamer Alharbash * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * 3. The names of the authors may not be used to endorse or promote * products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * dhcp object. */#define MODULE_NAME "dhcp-com"#include "dhcp-local.h"#include "dhcp-limits.h"#include "dhcp-libutil.h"#include "dhcp-librawnet.h"#include "dhcp-option.h"#include "dhcp-align.h"static const uint8_t dhcp_magic_cookie[4] = { 99, 130, 83, 99 };/* create new dhcp object. */dhcp_obj *dhcp_create(void){ dhcp_obj *dhcp; dhcp = xcalloc(sizeof(dhcp_obj)); dhcp->options = list_create(); return dhcp;}/* clean out dhcp object so it can be reused again. */void dhcp_purge(dhcp_obj * dhcp){ dhcp_opt_t *option; list_rewind(dhcp->options); while((option = list_next(dhcp->options)) != NULL) { list_remove_by_datum(dhcp->options, option); dhcp_opt_destroy(option); } return;}/* purge and free up dhcp object. */void dhcp_destroy(dhcp_obj * dhcp){ dhcp_purge(dhcp); list_destroy(dhcp->options, NULL); xfree(dhcp); return;}/* copy DHCP option safely. */static dhcp_opt_t *process_next_dhcp_option(const uint8_t *opt_data, int len, uint8_t *optlen){ dhcp_opt_t *option; /* Make sure the current packet length is big enough to hold * the whole option. */ if(len < 2 || (len - 2) < opt_data[1]) return NULL; /* We're in the clear copy out the bytes into a new * dhcp option object. */ *optlen = opt_data[1]; option = dhcp_opt_create_from_network(&opt_data[2], opt_data[1], opt_data[0]); return option;}static int skip_option(const uint8_t *opt_data, int len, uint8_t *optlen){ if(len < 2 || (len - 2) < opt_data[1]) return 1; *optlen = opt_data[1]; return 0;}static void dhcp_read_options_image(dhcp_obj * dhcp, const uint8_t *dhcp_packet, int len){ uint8_t optlen; dhcp_opt_t *option; /* Try and copy all the options. * We do no parsing at this point * since we may not require all * the options (if any). * * From here on in we cannot return an error * even if the options are malformed. * We'll just do our best. * */ while(len > 0) { /* Always skip pads */ if(*dhcp_packet == TAG_DHCP_PAD) { dhcp_packet++; len--; continue; } /* Always stop on end. */ if(*dhcp_packet == TAG_DHCP_END) break; /* ignore options we cannot handle. */ if(*dhcp_packet > MAX_OPTIONS_HANDLED) { if(skip_option(dhcp_packet, len, &optlen)) break; } else { option = process_next_dhcp_option(dhcp_packet, len, &optlen); if(option == NULL) break; list_add_to_end(dhcp->options, option); } len -= (optlen + 2); dhcp_packet += (optlen + 2); } return;}/* read packet image. */int dhcp_read_packet_image(dhcp_obj * dhcp, const uint8_t *dhcp_packet, int len){ /* Get the fixedheader or if not * possible return an error. */ if(len < DHCP_FIXEDHDR_LEN) return -1; else align_dhcphdr(dhcp_packet, &dhcp->fixedheader); len -= DHCP_FIXEDHDR_LEN; dhcp_packet += DHCP_FIXEDHDR_LEN; /* Copy out magic cookie. 4 octets. */ if(len >= 4) memcpy(&dhcp->magic_cookie, dhcp_packet, 4); else { memset(&dhcp->magic_cookie, 0, 4); /* set it to 0 so it doesn't pass test. */ return 0; } len -= 4; dhcp_packet += 4; /* read options placed after cookie. */ dhcp_read_options_image(dhcp, dhcp_packet, len); /* We need to check file before sname to be compliant. */ /* Now check if we have options overload in file field * and read options as necesssary. */ if(dhcp_is_file_overload(dhcp)) dhcp_read_options_image(dhcp, dhcp->fixedheader.file, DHCP_FILE_SIZE); /* Ditto on the sname field. */ if(dhcp_is_sname_overload(dhcp)) dhcp_read_options_image(dhcp, dhcp->fixedheader.sname, DHCP_SNAME_SIZE); return 0;}/* Accessor methods. * * Do conversion for some of the datatypes. * * The exceptions are ipv4 addresses. * We leave those in network order. *//* dhcp op */uint8_t dhcp_get_op(dhcp_obj * dhcp){ return (dhcp->fixedheader.op);}/* dhcp hardware type */uint8_t dhcp_get_htype(dhcp_obj * dhcp){ return (dhcp->fixedheader.htype);}/* dhcp hlen type */uint8_t dhcp_get_hlen(dhcp_obj * dhcp){ return (dhcp->fixedheader.hlen);}/* dhcp hops */uint8_t dhcp_get_hops(dhcp_obj * dhcp){ return (dhcp->fixedheader.hops);}/* dhcp xid: do conversion */uint32_t dhcp_get_xid(dhcp_obj * dhcp){ return (ntohl(dhcp->fixedheader.xid));}/* dhcp secs: do conversion. */uint16_t dhcp_get_secs(dhcp_obj * dhcp){ return (ntohs(dhcp->fixedheader.secs));}/* dhcp flags: do conversion */uint16_t dhcp_get_flags(dhcp_obj * dhcp){ return (ntohs(dhcp->fixedheader.flags));}/* dhcp ciaddr: no conversion necessary */uint32_t dhcp_get_ciaddr(dhcp_obj * dhcp){ return (dhcp->fixedheader.ciaddr);}/* dhcp yiaddr: no conversion necessary */uint32_t dhcp_get_yiaddr(dhcp_obj * dhcp){ return (dhcp->fixedheader.yiaddr);}/* dhcp siaddr: no conversion necessary */uint32_t dhcp_get_siaddr(dhcp_obj * dhcp){ return (dhcp->fixedheader.siaddr);}/* dhcp ciaddr: no conversion necessary */uint32_t dhcp_get_giaddr(dhcp_obj * dhcp){ return (dhcp->fixedheader.giaddr);}/* dhcp chaddr */uint8_t *dhcp_get_chaddr(dhcp_obj * dhcp){ return (dhcp->fixedheader.chaddr);}/* dhcp giaddr */uint8_t *dhcp_get_sname(dhcp_obj * dhcp){ return (dhcp->fixedheader.sname);}/* dhcp file */uint8_t *dhcp_get_filename(dhcp_obj * dhcp){ return (dhcp->fixedheader.file);}/* return magic cookie */uint32_t dhcp_get_magic_cookie(dhcp_obj * dhcp){ return (dhcp->magic_cookie);}/* DHCP set methods. *//* dhcp op */void dhcp_set_op(dhcp_obj * dhcp, uint8_t op){ memcpy(&dhcp->fixedheader.op, &op, 1);}/* dhcp hardware type */void dhcp_set_htype(dhcp_obj * dhcp, uint8_t htype){ memcpy(&dhcp->fixedheader.htype, &htype, 1);}/* dhcp hlen type */void dhcp_set_hlen(dhcp_obj * dhcp, uint8_t hlen){ memcpy(&dhcp->fixedheader.hlen, &hlen, 1);}/* dhcp hops */void dhcp_set_hops(dhcp_obj * dhcp, uint8_t hops){ memcpy(&dhcp->fixedheader.hops, &hops, 1);}/* dhcp xid: do conversion */void dhcp_set_xid(dhcp_obj * dhcp, uint32_t xid){ xid = htonl(xid); memcpy(&dhcp->fixedheader.xid, &xid, 4);}/* dhcp secs: do conversion. */void dhcp_set_secs(dhcp_obj * dhcp, uint16_t secs){ secs = ntohs(secs); memcpy(&dhcp->fixedheader.secs, &secs, 2);}/* dhcp flags: do conversion */void dhcp_set_flag_broadcast(dhcp_obj * dhcp)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -