added many dhcp message functions
This commit is contained in:
parent
481cf38790
commit
0fb45e10d2
@ -71,6 +71,7 @@ lib_LTLIBRARIES = libhio.la
|
||||
libhio_la_SOURCES = \
|
||||
chr.c \
|
||||
dhcp-svr.c \
|
||||
dhcp-msg.c \
|
||||
dns.c \
|
||||
dns-cli.c \
|
||||
ecs.c \
|
||||
|
@ -147,34 +147,34 @@ am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1)
|
||||
libhio_la_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \
|
||||
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
|
||||
$(am__DEPENDENCIES_3) $(am__DEPENDENCIES_4)
|
||||
am__libhio_la_SOURCES_DIST = chr.c dhcp-svr.c dns.c dns-cli.c ecs.c \
|
||||
ecs-imp.h err.c fcgi-cli.c fmt.c fmt-imp.h htb.c htrd.c htre.c \
|
||||
http.c http-cgi.c http-fcgi.c http-file.c http-prv.h \
|
||||
http-prxy.c http-svr.c http-thr.c http-txt.c json.c hio-prv.h \
|
||||
hio.c md5.c nwif.c opt.c opt-imp.h path.c pipe.c pro.c pty.c \
|
||||
rad-msg.c sck.c shw.c skad.c sys.c sys-ass.c sys-err.c \
|
||||
sys-log.c sys-mux.c sys-prv.h sys-tim.c thr.c uch-case.h \
|
||||
uch-prop.h tar.c tmr.c utf8.c utl.c utl-mime.c utl-siph.c \
|
||||
utl-str.c mar.c mar-cli.c
|
||||
am__libhio_la_SOURCES_DIST = chr.c dhcp-svr.c dhcp-msg.c dns.c \
|
||||
dns-cli.c ecs.c ecs-imp.h err.c fcgi-cli.c fmt.c fmt-imp.h \
|
||||
htb.c htrd.c htre.c http.c http-cgi.c http-fcgi.c http-file.c \
|
||||
http-prv.h http-prxy.c http-svr.c http-thr.c http-txt.c json.c \
|
||||
hio-prv.h hio.c md5.c nwif.c opt.c opt-imp.h path.c pipe.c \
|
||||
pro.c pty.c rad-msg.c sck.c shw.c skad.c sys.c sys-ass.c \
|
||||
sys-err.c sys-log.c sys-mux.c sys-prv.h sys-tim.c thr.c \
|
||||
uch-case.h uch-prop.h tar.c tmr.c utf8.c utl.c utl-mime.c \
|
||||
utl-siph.c utl-str.c mar.c mar-cli.c
|
||||
@ENABLE_MARIADB_TRUE@am__objects_1 = libhio_la-mar.lo \
|
||||
@ENABLE_MARIADB_TRUE@ libhio_la-mar-cli.lo
|
||||
am_libhio_la_OBJECTS = libhio_la-chr.lo libhio_la-dhcp-svr.lo \
|
||||
libhio_la-dns.lo libhio_la-dns-cli.lo libhio_la-ecs.lo \
|
||||
libhio_la-err.lo libhio_la-fcgi-cli.lo libhio_la-fmt.lo \
|
||||
libhio_la-htb.lo libhio_la-htrd.lo libhio_la-htre.lo \
|
||||
libhio_la-http.lo libhio_la-http-cgi.lo libhio_la-http-fcgi.lo \
|
||||
libhio_la-http-file.lo libhio_la-http-prxy.lo \
|
||||
libhio_la-http-svr.lo libhio_la-http-thr.lo \
|
||||
libhio_la-http-txt.lo libhio_la-json.lo libhio_la-hio.lo \
|
||||
libhio_la-md5.lo libhio_la-nwif.lo libhio_la-opt.lo \
|
||||
libhio_la-path.lo libhio_la-pipe.lo libhio_la-pro.lo \
|
||||
libhio_la-pty.lo libhio_la-rad-msg.lo libhio_la-sck.lo \
|
||||
libhio_la-shw.lo libhio_la-skad.lo libhio_la-sys.lo \
|
||||
libhio_la-sys-ass.lo libhio_la-sys-err.lo libhio_la-sys-log.lo \
|
||||
libhio_la-sys-mux.lo libhio_la-sys-tim.lo libhio_la-thr.lo \
|
||||
libhio_la-tar.lo libhio_la-tmr.lo libhio_la-utf8.lo \
|
||||
libhio_la-utl.lo libhio_la-utl-mime.lo libhio_la-utl-siph.lo \
|
||||
libhio_la-utl-str.lo $(am__objects_1)
|
||||
libhio_la-dhcp-msg.lo libhio_la-dns.lo libhio_la-dns-cli.lo \
|
||||
libhio_la-ecs.lo libhio_la-err.lo libhio_la-fcgi-cli.lo \
|
||||
libhio_la-fmt.lo libhio_la-htb.lo libhio_la-htrd.lo \
|
||||
libhio_la-htre.lo libhio_la-http.lo libhio_la-http-cgi.lo \
|
||||
libhio_la-http-fcgi.lo libhio_la-http-file.lo \
|
||||
libhio_la-http-prxy.lo libhio_la-http-svr.lo \
|
||||
libhio_la-http-thr.lo libhio_la-http-txt.lo libhio_la-json.lo \
|
||||
libhio_la-hio.lo libhio_la-md5.lo libhio_la-nwif.lo \
|
||||
libhio_la-opt.lo libhio_la-path.lo libhio_la-pipe.lo \
|
||||
libhio_la-pro.lo libhio_la-pty.lo libhio_la-rad-msg.lo \
|
||||
libhio_la-sck.lo libhio_la-shw.lo libhio_la-skad.lo \
|
||||
libhio_la-sys.lo libhio_la-sys-ass.lo libhio_la-sys-err.lo \
|
||||
libhio_la-sys-log.lo libhio_la-sys-mux.lo libhio_la-sys-tim.lo \
|
||||
libhio_la-thr.lo libhio_la-tar.lo libhio_la-tmr.lo \
|
||||
libhio_la-utf8.lo libhio_la-utl.lo libhio_la-utl-mime.lo \
|
||||
libhio_la-utl-siph.lo libhio_la-utl-str.lo $(am__objects_1)
|
||||
libhio_la_OBJECTS = $(am_libhio_la_OBJECTS)
|
||||
AM_V_lt = $(am__v_lt_@AM_V@)
|
||||
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
|
||||
@ -199,6 +199,7 @@ DEFAULT_INCLUDES =
|
||||
depcomp = $(SHELL) $(top_srcdir)/ac/depcomp
|
||||
am__maybe_remake_depfiles = depfiles
|
||||
am__depfiles_remade = ./$(DEPDIR)/libhio_la-chr.Plo \
|
||||
./$(DEPDIR)/libhio_la-dhcp-msg.Plo \
|
||||
./$(DEPDIR)/libhio_la-dhcp-svr.Plo \
|
||||
./$(DEPDIR)/libhio_la-dns-cli.Plo \
|
||||
./$(DEPDIR)/libhio_la-dns.Plo ./$(DEPDIR)/libhio_la-ecs.Plo \
|
||||
@ -474,15 +475,15 @@ include_HEADERS = hio-chr.h hio-cmn.h hio-dhcp.h hio-dns.h hio-ecs.h \
|
||||
hio-sck.h hio-shw.h hio-skad.h hio-spl.h hio-str.h hio-tar.h \
|
||||
hio-thr.h hio-upac.h hio-utl.h hio.h $(am__append_1)
|
||||
lib_LTLIBRARIES = libhio.la
|
||||
libhio_la_SOURCES = chr.c dhcp-svr.c dns.c dns-cli.c ecs.c ecs-imp.h \
|
||||
err.c fcgi-cli.c fmt.c fmt-imp.h htb.c htrd.c htre.c http.c \
|
||||
http-cgi.c http-fcgi.c http-file.c http-prv.h http-prxy.c \
|
||||
http-svr.c http-thr.c http-txt.c json.c hio-prv.h hio.c md5.c \
|
||||
nwif.c opt.c opt-imp.h path.c pipe.c pro.c pty.c rad-msg.c \
|
||||
sck.c shw.c skad.c sys.c sys-ass.c sys-err.c sys-log.c \
|
||||
sys-mux.c sys-prv.h sys-tim.c thr.c uch-case.h uch-prop.h \
|
||||
tar.c tmr.c utf8.c utl.c utl-mime.c utl-siph.c utl-str.c \
|
||||
$(am__append_2)
|
||||
libhio_la_SOURCES = chr.c dhcp-svr.c dhcp-msg.c dns.c dns-cli.c ecs.c \
|
||||
ecs-imp.h err.c fcgi-cli.c fmt.c fmt-imp.h htb.c htrd.c htre.c \
|
||||
http.c http-cgi.c http-fcgi.c http-file.c http-prv.h \
|
||||
http-prxy.c http-svr.c http-thr.c http-txt.c json.c hio-prv.h \
|
||||
hio.c md5.c nwif.c opt.c opt-imp.h path.c pipe.c pro.c pty.c \
|
||||
rad-msg.c sck.c shw.c skad.c sys.c sys-ass.c sys-err.c \
|
||||
sys-log.c sys-mux.c sys-prv.h sys-tim.c thr.c uch-case.h \
|
||||
uch-prop.h tar.c tmr.c utf8.c utl.c utl-mime.c utl-siph.c \
|
||||
utl-str.c $(am__append_2)
|
||||
libhio_la_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
|
||||
libhio_la_CFLAGS = $(CFLAGS_LIB_COMMON) $(am__append_3)
|
||||
libhio_la_LDFLAGS = $(LDFLAGS_LIB_COMMON) $(am__append_4)
|
||||
@ -583,6 +584,7 @@ distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhio_la-chr.Plo@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhio_la-dhcp-msg.Plo@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhio_la-dhcp-svr.Plo@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhio_la-dns-cli.Plo@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhio_la-dns.Plo@am__quote@ # am--include-marker
|
||||
@ -675,6 +677,13 @@ libhio_la-dhcp-svr.lo: dhcp-svr.c
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhio_la_CPPFLAGS) $(CPPFLAGS) $(libhio_la_CFLAGS) $(CFLAGS) -c -o libhio_la-dhcp-svr.lo `test -f 'dhcp-svr.c' || echo '$(srcdir)/'`dhcp-svr.c
|
||||
|
||||
libhio_la-dhcp-msg.lo: dhcp-msg.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhio_la_CPPFLAGS) $(CPPFLAGS) $(libhio_la_CFLAGS) $(CFLAGS) -MT libhio_la-dhcp-msg.lo -MD -MP -MF $(DEPDIR)/libhio_la-dhcp-msg.Tpo -c -o libhio_la-dhcp-msg.lo `test -f 'dhcp-msg.c' || echo '$(srcdir)/'`dhcp-msg.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhio_la-dhcp-msg.Tpo $(DEPDIR)/libhio_la-dhcp-msg.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dhcp-msg.c' object='libhio_la-dhcp-msg.lo' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhio_la_CPPFLAGS) $(CPPFLAGS) $(libhio_la_CFLAGS) $(CFLAGS) -c -o libhio_la-dhcp-msg.lo `test -f 'dhcp-msg.c' || echo '$(srcdir)/'`dhcp-msg.c
|
||||
|
||||
libhio_la-dns.lo: dns.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhio_la_CPPFLAGS) $(CPPFLAGS) $(libhio_la_CFLAGS) $(CFLAGS) -MT libhio_la-dns.lo -MD -MP -MF $(DEPDIR)/libhio_la-dns.Tpo -c -o libhio_la-dns.lo `test -f 'dns.c' || echo '$(srcdir)/'`dns.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhio_la-dns.Tpo $(DEPDIR)/libhio_la-dns.Plo
|
||||
@ -1156,6 +1165,7 @@ clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
|
||||
|
||||
distclean: distclean-am
|
||||
-rm -f ./$(DEPDIR)/libhio_la-chr.Plo
|
||||
-rm -f ./$(DEPDIR)/libhio_la-dhcp-msg.Plo
|
||||
-rm -f ./$(DEPDIR)/libhio_la-dhcp-svr.Plo
|
||||
-rm -f ./$(DEPDIR)/libhio_la-dns-cli.Plo
|
||||
-rm -f ./$(DEPDIR)/libhio_la-dns.Plo
|
||||
@ -1250,6 +1260,7 @@ installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
-rm -f ./$(DEPDIR)/libhio_la-chr.Plo
|
||||
-rm -f ./$(DEPDIR)/libhio_la-dhcp-msg.Plo
|
||||
-rm -f ./$(DEPDIR)/libhio_la-dhcp-svr.Plo
|
||||
-rm -f ./$(DEPDIR)/libhio_la-dns-cli.Plo
|
||||
-rm -f ./$(DEPDIR)/libhio_la-dns.Plo
|
||||
|
354
lib/dhcp-msg.c
Normal file
354
lib/dhcp-msg.c
Normal file
@ -0,0 +1,354 @@
|
||||
/*
|
||||
Copyright (c) 2016-2020 Chung, Hyung-Hwan. All rights reserved.
|
||||
|
||||
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.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <hio-dhcp.h>
|
||||
#include "hio-prv.h"
|
||||
|
||||
#include <hio-pac1.h>
|
||||
struct magic_cookie_t
|
||||
{
|
||||
hio_uint32_t value;
|
||||
};
|
||||
typedef struct magic_cookie_t magic_cookie_t;
|
||||
#include <hio-upac.h>
|
||||
|
||||
|
||||
int hio_dhcp4_init_pktbuf (hio_dhcp4_pktbuf_t* pkt, void* buf, hio_oow_t capa)
|
||||
{
|
||||
if (capa < HIO_SIZEOF(*pkt->hdr)) return -1;
|
||||
pkt->hdr = (hio_dhcp4_pkt_hdr_t*)buf;
|
||||
pkt->len = HIO_SIZEOF(*pkt->hdr);
|
||||
pkt->capa = capa;
|
||||
HIO_MEMSET (pkt->hdr, 0, HIO_SIZEOF(*pkt->hdr));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hio_dhcp4_add_option (hio_dhcp4_pktbuf_t* pkt, int code, void* optr, hio_uint8_t olen)
|
||||
{
|
||||
hio_dhcp4_opt_hdr_t* opthdr;
|
||||
magic_cookie_t* cookie;
|
||||
int optlen;
|
||||
|
||||
/* TODO: support to override sname and file */
|
||||
if (pkt->len < HIO_SIZEOF(*pkt->hdr) || pkt->capa < pkt->len)
|
||||
{
|
||||
/* the pktbuf_t structure got messy */
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pkt->len == HIO_SIZEOF(*pkt->hdr))
|
||||
{
|
||||
/* the first option is being added */
|
||||
if (pkt->capa - pkt->len < HIO_SIZEOF(*cookie)) return -1;
|
||||
cookie = (magic_cookie_t*)((hio_uint8_t*)pkt->hdr + pkt->len);
|
||||
cookie->value = HIO_CONST_HTON32(HIO_DHCP4_MAGIC_COOKIE);
|
||||
pkt->len += HIO_SIZEOF(*cookie);
|
||||
}
|
||||
else if (pkt->len < HIO_SIZEOF(*pkt->hdr) + HIO_SIZEOF(*cookie))
|
||||
{
|
||||
/* no space for cookie */
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
cookie = (magic_cookie_t*)(pkt->hdr + 1);
|
||||
if (cookie->value != HIO_CONST_HTON32(HIO_DHCP4_MAGIC_COOKIE)) return -1;
|
||||
}
|
||||
|
||||
/* do i need to disallow adding a new option if END is found? */
|
||||
|
||||
if (code == HIO_DHCP4_OPT_PADDING || code == HIO_DHCP4_OPT_END)
|
||||
{
|
||||
optlen = 1; /* no length field in the header and no option palyload */
|
||||
if (pkt->capa - pkt->len < optlen) return -1;
|
||||
opthdr = (hio_dhcp4_opt_hdr_t*)((hio_uint8_t*)pkt->hdr + pkt->len);
|
||||
}
|
||||
else
|
||||
{
|
||||
optlen = HIO_SIZEOF(*opthdr) + olen;
|
||||
|
||||
if (pkt->capa - pkt->len < optlen) return -1;
|
||||
opthdr = (hio_dhcp4_opt_hdr_t*)((hio_uint8_t*)pkt->hdr + pkt->len);
|
||||
|
||||
opthdr->len = olen;
|
||||
if (olen > 0) HIO_MEMCPY (opthdr + 1, optr, olen);
|
||||
}
|
||||
|
||||
opthdr->code = code;
|
||||
pkt->len += optlen;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hio_dhcp4_delete_option (hio_dhcp4_pktbuf_t* pkt, int code)
|
||||
{
|
||||
hio_dhcp4_opt_hdr_t* ohdr;
|
||||
hio_oow_t olen;
|
||||
hio_uint8_t* ovend;
|
||||
|
||||
ohdr = hio_dhcp4_find_option((hio_dhcp4_pktinf_t*)pkt, code);
|
||||
if (!ohdr) return -1;
|
||||
|
||||
olen = (code == HIO_DHCP4_OPT_PADDING || code == HIO_DHCP4_OPT_END)? 1: (ohdr->len) + HIO_SIZEOF(*ohdr);
|
||||
|
||||
if ((ohdr >= pkt->hdr->file && ohdr < (ovend = (hio_uint8_t*)pkt->hdr->file + HIO_SIZEOF(pkt->hdr->file))) ||
|
||||
(ohdr >= pkt->hdr->sname && ohdr < (ovend = (hio_uint8_t*)pkt->hdr->sname + HIO_SIZEOF(pkt->hdr->sname))))
|
||||
{
|
||||
/* the option resides in the overload area */
|
||||
HIO_MEMMOVE (ohdr, (hio_uint8_t*)ohdr + olen, ovend - ((hio_uint8_t*)ohdr + olen));
|
||||
HIO_MEMSET (ovend - olen, 0, olen);
|
||||
/* packet length remains unchanged */
|
||||
}
|
||||
else
|
||||
{
|
||||
HIO_MEMMOVE (ohdr, (hio_uint8_t*)ohdr + olen, ((hio_uint8_t*)pkt->hdr + pkt->len) - ((hio_uint8_t*)ohdr + olen));
|
||||
pkt->len -= olen;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hio_dhcp4_compact_options (hio_dhcp4_pktbuf_t* pkt)
|
||||
{
|
||||
/* TODO: move some optiosn to sname or file fields if they are not in use. */
|
||||
}
|
||||
|
||||
static hio_uint8_t* get_option_start (const hio_dhcp4_pkt_hdr_t* pkt, hio_oow_t len, hio_oow_t* olen)
|
||||
{
|
||||
magic_cookie_t* cookie;
|
||||
hio_oow_t optlen;
|
||||
|
||||
/* check if a packet is large enough to hold the known header */
|
||||
if (len < HIO_SIZEOF(hio_dhcp4_pkt_hdr_t)) return HIO_NULL;
|
||||
|
||||
/* get the length of option fields */
|
||||
optlen = len - HIO_SIZEOF(hio_dhcp4_pkt_hdr_t);
|
||||
|
||||
/* check if a packet is large enough to have a magic cookie */
|
||||
if (optlen < HIO_SIZEOF(*cookie)) return HIO_NULL;
|
||||
|
||||
/* get the pointer to the beginning of options */
|
||||
cookie = (magic_cookie_t*)(pkt + 1);
|
||||
|
||||
/* check if the packet contains the right magic cookie */
|
||||
if (cookie->value != HIO_CONST_HTON32(HIO_DHCP4_MAGIC_COOKIE)) return HIO_NULL;
|
||||
|
||||
*olen = optlen - HIO_SIZEOF(*cookie);
|
||||
return (hio_uint8_t*)(cookie + 1);
|
||||
}
|
||||
|
||||
int hio_dhcp4_walk_options (const hio_dhcp4_pktinf_t* pkt, hio_dhcp4_opt_walker_t walker)
|
||||
{
|
||||
const hio_uint8_t* optptr[3];
|
||||
hio_oow_t optlen[3];
|
||||
int i;
|
||||
|
||||
optptr[0] = get_option_start(pkt->hdr, pkt->len, &optlen[0]);
|
||||
if (optptr[0] == HIO_NULL) return -1;
|
||||
|
||||
optptr[1] = (const hio_uint8_t*)pkt->hdr->file;
|
||||
optptr[2] = (const hio_uint8_t*)pkt->hdr->sname;
|
||||
optlen[1] = 0;
|
||||
optlen[2] = 0;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
const hio_uint8_t* opt = optptr[i];
|
||||
const hio_uint8_t* end = opt + optlen[i];
|
||||
|
||||
while (opt < end)
|
||||
{
|
||||
/* option code */
|
||||
hio_dhcp4_opt_hdr_t* opthdr;
|
||||
|
||||
if (opt + HIO_SIZEOF(*opthdr) >= end) return -1;
|
||||
opthdr = (hio_dhcp4_opt_hdr_t*)opt;
|
||||
opt += HIO_SIZEOF(*opthdr);
|
||||
|
||||
/* no len field exists for PADDING and END */
|
||||
if (opthdr->code == HIO_DHCP4_OPT_PADDING) continue;
|
||||
if (opthdr->code == HIO_DHCP4_OPT_END) break;
|
||||
|
||||
if (opt + opthdr->len >= end) return -1; /* the length field is wrong */
|
||||
|
||||
if (opthdr->code == HIO_DHCP4_OPT_OVERLOAD)
|
||||
{
|
||||
if (opthdr->len != 1) return -1;
|
||||
if (*opt & HIO_DHCP4_OPT_OVERLOAD_FILE) optlen[1] = HIO_SIZEOF(pkt->hdr->file);
|
||||
if (*opt & HIO_DHCP4_OPT_OVERLOAD_SNAME) optlen[2] = HIO_SIZEOF(pkt->hdr->sname);
|
||||
}
|
||||
else
|
||||
{
|
||||
int n;
|
||||
if ((n = walker(opthdr)) <= -1) return -1;
|
||||
if (n == 0) break; /* stop */
|
||||
}
|
||||
|
||||
opt += opthdr->len;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
hio_dhcp4_opt_hdr_t* hio_dhcp4_find_option (const hio_dhcp4_pktinf_t* pkt, int code)
|
||||
{
|
||||
const hio_uint8_t* optptr[3];
|
||||
hio_oow_t optlen[3];
|
||||
int i;
|
||||
|
||||
optptr[0] = get_option_start(pkt->hdr, pkt->len, &optlen[0]);
|
||||
if (!optptr[0]) return HIO_NULL;
|
||||
|
||||
optptr[1] = (const hio_uint8_t*)pkt->hdr->file;
|
||||
optptr[2] = (const hio_uint8_t*)pkt->hdr->sname;
|
||||
optlen[1] = 0;
|
||||
optlen[2] = 0;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
const hio_uint8_t* opt = optptr[i];
|
||||
const hio_uint8_t* end = opt + optlen[i];
|
||||
|
||||
while (opt < end)
|
||||
{
|
||||
/* option code */
|
||||
hio_dhcp4_opt_hdr_t* opthdr;
|
||||
|
||||
/* at least 1 byte is available. the check is because of PADDING or END */
|
||||
if (*opt == HIO_DHCP4_OPT_PADDING)
|
||||
{
|
||||
opt++;
|
||||
continue;
|
||||
}
|
||||
if (*opt == HIO_DHCP4_OPT_END)
|
||||
{
|
||||
if (code == HIO_DHCP4_OPT_END)
|
||||
{
|
||||
/* the caller must handle END specially becuase it is only 1 byte long
|
||||
* for no length part in the header */
|
||||
return (hio_dhcp4_opt_hdr_t*)opt;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (opt + HIO_SIZEOF(*opthdr) > end) break;
|
||||
|
||||
opthdr = (hio_dhcp4_opt_hdr_t*)opt;
|
||||
opt += HIO_SIZEOF(*opthdr);
|
||||
|
||||
/* option length */
|
||||
|
||||
if (opthdr->code == code)
|
||||
{
|
||||
if (opt + opthdr->len > end) break;
|
||||
return opthdr;
|
||||
}
|
||||
|
||||
/*
|
||||
* If option overload is used, the SName and/or File fields are read and
|
||||
* interpreted in the same way as the Options field, after all options in
|
||||
* the Option field are parsed. If the message actually does need to carry
|
||||
* a server name or boot file, these are included as separate options
|
||||
* (number 66 and number 67, respectively), which are variable-length and
|
||||
* can therefore be made exactly the length needed.
|
||||
*/
|
||||
if (opthdr->code == HIO_DHCP4_OPT_OVERLOAD)
|
||||
{
|
||||
if (opthdr->len != 1) break;
|
||||
if (*opt & HIO_DHCP4_OPT_OVERLOAD_FILE) optlen[1] = HIO_SIZEOF(pkt->hdr->file);
|
||||
if (*opt & HIO_DHCP4_OPT_OVERLOAD_SNAME) optlen[2] = HIO_SIZEOF(pkt->hdr->sname);
|
||||
}
|
||||
|
||||
opt += opthdr->len;
|
||||
}
|
||||
}
|
||||
|
||||
return HIO_NULL;
|
||||
}
|
||||
|
||||
hio_uint8_t* hio_dhcp4_get_relay_suboption (const hio_uint8_t* ptr, hio_uint8_t len, int code, hio_uint8_t* olen)
|
||||
{
|
||||
const hio_uint8_t* end = ptr + len;
|
||||
|
||||
while (ptr < end)
|
||||
{
|
||||
hio_uint8_t oc, ol;
|
||||
|
||||
oc = *ptr++;
|
||||
|
||||
if (ptr >= end) break;
|
||||
ol = *ptr++;
|
||||
|
||||
if (oc == code)
|
||||
{
|
||||
*olen = ol;
|
||||
return (hio_uint8_t*)ptr;
|
||||
}
|
||||
|
||||
ptr += ol;
|
||||
}
|
||||
|
||||
return HIO_NULL;
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
hio_dhcp6_opt_hdr_t* hio_dhcp6_find_option (const hio_dhcp6_pktinf_t* pkt, int code)
|
||||
{
|
||||
hio_dhcp6_opt_hdr_t* opt;
|
||||
hio_oow_t rem, opt_len;
|
||||
|
||||
if (pkt->len < HIO_SIZEOF(hio_dhcp6_pkt_hdr_t)) return HIO_NULL;
|
||||
|
||||
if (pkt->hdr->msgtype == HIO_DHCP6_MSG_RELAYFORW || pkt->hdr->msgtype == HIO_DHCP6_MSG_RELAYREPL)
|
||||
{
|
||||
if (pkt->len < HIO_SIZEOF(hio_dhcp6_relay_hdr_t)) return HIO_NULL;
|
||||
|
||||
rem = pkt->len - HIO_SIZEOF(hio_dhcp6_relay_hdr_t);
|
||||
opt = (hio_dhcp6_opt_hdr_t*)(((hio_dhcp6_relay_hdr_t*)pkt->hdr) + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
rem = pkt->len - HIO_SIZEOF(hio_dhcp6_pkt_hdr_t);
|
||||
opt = (hio_dhcp6_opt_hdr_t*)(pkt->hdr + 1);
|
||||
}
|
||||
|
||||
while (rem >= HIO_SIZEOF(hio_dhcp6_opt_hdr_t))
|
||||
{
|
||||
if (hio_ntoh16(opt->code) == code)
|
||||
{
|
||||
if (rem - HIO_SIZEOF(hio_dhcp6_opt_hdr_t) < hio_ntoh16(opt->len)) return HIO_NULL; /* probably the packet is ill-formed */
|
||||
return opt;
|
||||
}
|
||||
|
||||
opt_len = HIO_SIZEOF(hio_dhcp6_opt_hdr_t) + hio_ntoh16(opt->len);
|
||||
if (rem < opt_len) break;
|
||||
rem -= opt_len;
|
||||
opt = (hio_dhcp6_opt_hdr_t*)((hio_uint8_t*)(opt + 1) + hio_ntoh16(opt->len));
|
||||
|
||||
}
|
||||
|
||||
return HIO_NULL;
|
||||
}
|
245
lib/hio-dhcp.h
245
lib/hio-dhcp.h
@ -28,6 +28,167 @@
|
||||
#include <hio.h>
|
||||
#include <hio-sck.h>
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
#define HIO_DHCP4_SERVER_PORT (67)
|
||||
#define HIO_DHCP4_CLIENT_PORT (68)
|
||||
#define HIO_DHCP4_MAGIC_COOKIE (0x63825363)
|
||||
|
||||
/* operation code */
|
||||
enum hio_dhcp4_op_t
|
||||
{
|
||||
HIO_DHCP4_OP_BOOTREQUEST = 1,
|
||||
HIO_DHCP4_OP_BOOTREPLY = 2
|
||||
};
|
||||
|
||||
enum hio_dhcp4_htype_t
|
||||
{
|
||||
HIO_DHCP4_HTYPE_ETHERNET = 1,
|
||||
HIO_DHCP4_HTYPE_IEEE802 = 6,
|
||||
HIO_DHCP4_HTYPE_ARCNET = 7,
|
||||
HIO_DHCP4_HTYPE_APPLETALK = 8,
|
||||
HIO_DHCP4_HTYPE_HDLC = 17,
|
||||
HIO_DHCP4_HTYPE_ATM = 19,
|
||||
HIO_DHCP4_HTYPE_INFINIBAND = 32
|
||||
};
|
||||
|
||||
/* option codes (partial) */
|
||||
enum hio_dhcp4_opt_t
|
||||
{
|
||||
HIO_DHCP4_OPT_PADDING = 0x00,
|
||||
HIO_DHCP4_OPT_SUBNET = 0x01,
|
||||
HIO_DHCP4_OPT_TIME_OFFSET = 0x02,
|
||||
HIO_DHCP4_OPT_ROUTER = 0x03,
|
||||
HIO_DHCP4_OPT_TIME_SERVER = 0x04,
|
||||
HIO_DHCP4_OPT_NAME_SERVER = 0x05,
|
||||
HIO_DHCP4_OPT_DNS_SERVER = 0x06,
|
||||
HIO_DHCP4_OPT_LOG_SERVER = 0x07,
|
||||
HIO_DHCP4_OPT_COOKIE_SERVER = 0x08,
|
||||
HIO_DHCP4_OPT_LPR_SERVER = 0x09,
|
||||
HIO_DHCP4_OPT_HOST_NAME = 0x0c,
|
||||
HIO_DHCP4_OPT_BOOT_SIZE = 0x0d,
|
||||
HIO_DHCP4_OPT_DOMAIN_NAME = 0x0f,
|
||||
HIO_DHCP4_OPT_SWAP_SERVER = 0x10,
|
||||
HIO_DHCP4_OPT_ROOT_PATH = 0x11,
|
||||
HIO_DHCP4_OPT_IP_TTL = 0x17,
|
||||
HIO_DHCP4_OPT_MTU = 0x1a,
|
||||
HIO_DHCP4_OPT_BROADCAST = 0x1c,
|
||||
HIO_DHCP4_OPT_NTP_SERVER = 0x2a,
|
||||
HIO_DHCP4_OPT_WINS_SERVER = 0x2c,
|
||||
HIO_DHCP4_OPT_REQUESTED_IPADDR = 0x32,
|
||||
HIO_DHCP4_OPT_LEASE_TIME = 0x33,
|
||||
HIO_DHCP4_OPT_OVERLOAD = 0x34, /* overload sname or file */
|
||||
HIO_DHCP4_OPT_MESSAGE_TYPE = 0x35,
|
||||
HIO_DHCP4_OPT_SERVER_ID = 0x36,
|
||||
HIO_DHCP4_OPT_PARAM_REQ = 0x37,
|
||||
HIO_DHCP4_OPT_MESSAGE = 0x38,
|
||||
HIO_DHCP4_OPT_MAX_SIZE = 0x39,
|
||||
HIO_DHCP4_OPT_T1 = 0x3a,
|
||||
HIO_DHCP4_OPT_T2 = 0x3b,
|
||||
HIO_DHCP4_OPT_VENDOR = 0x3c,
|
||||
HIO_DHCP4_OPT_CLIENT_ID = 0x3d,
|
||||
HIO_DHCP4_OPT_RELAY = 0x52,
|
||||
HIO_DHCP4_OPT_SUBNET_SELECTION = 0x76,
|
||||
HIO_DHCP4_OPT_END = 0xFF
|
||||
};
|
||||
|
||||
/* flags for HIO_DHCP4_OPT_OVERLOAD */
|
||||
enum hio_dhcp4_opt_overload_t
|
||||
{
|
||||
HIO_DHCP4_OPT_OVERLOAD_FILE = (1 << 0),
|
||||
HIO_DHCP4_OPT_OVERLOAD_SNAME = (1 << 1)
|
||||
};
|
||||
|
||||
/* flags for HIO_DHCP4_OPT_OVERLOAD */
|
||||
enum hio_dhcp4_opt_relay_t
|
||||
{
|
||||
HIO_DHCP4_OPT_RELAY_CIRCUIT_ID = 1,
|
||||
HIO_DHCP4_OPT_RELAY_REMOTE_ID = 2
|
||||
};
|
||||
|
||||
/* message type */
|
||||
enum hio_dhcp4_msg_t
|
||||
{
|
||||
HIO_DHCP4_MSG_DISCOVER = 1,
|
||||
HIO_DHCP4_MSG_OFFER = 2,
|
||||
HIO_DHCP4_MSG_REQUEST = 3,
|
||||
HIO_DHCP4_MSG_DECLINE = 4,
|
||||
HIO_DHCP4_MSG_ACK = 5,
|
||||
HIO_DHCP4_MSG_NAK = 6,
|
||||
HIO_DHCP4_MSG_RELEASE = 7,
|
||||
HIO_DHCP4_MSG_INFORM = 8,
|
||||
|
||||
/*HIO_DHCP4_MSG_RENEW = 9,*/
|
||||
|
||||
HIO_DHCP4_MSG_LEASE_QUERY = 10,
|
||||
HIO_DHCP4_MSG_LEASE_UNASSIGNED = 11,
|
||||
HIO_DHCP4_MSG_LEASE_UNKNOWN = 12,
|
||||
HIO_DHCP4_MSG_LEASE_ACTIVE = 13,
|
||||
|
||||
HIO_DHCP4_MSG_BULK_LEASE_QUERY = 14,
|
||||
HIO_DHCP4_MSG_LEASE_QUERY_DONE = 15
|
||||
};
|
||||
|
||||
/* --------------------------------------------------- */
|
||||
#include <hio-pac1.h>
|
||||
/* --------------------------------------------------- */
|
||||
|
||||
struct hio_dhcp4_pkt_hdr_t
|
||||
{
|
||||
hio_uint8_t op;
|
||||
hio_uint8_t htype;
|
||||
hio_uint8_t hlen;
|
||||
hio_uint8_t hops;
|
||||
hio_uint32_t xid; /* transaction id */
|
||||
hio_uint16_t secs; /* seconds elapsed */
|
||||
hio_uint16_t flags; /* bootp flags */
|
||||
hio_uint32_t ciaddr; /* client ip */
|
||||
hio_uint32_t yiaddr; /* your ip */
|
||||
hio_uint32_t siaddr; /* next server ip */
|
||||
hio_uint32_t giaddr; /* relay agent ip */
|
||||
hio_uint8_t chaddr[16]; /* client mac */
|
||||
|
||||
char sname[64]; /* server host name */
|
||||
char file[128]; /* boot file name */
|
||||
|
||||
/* options are placed after the header.
|
||||
* the first four bytes of the options compose a magic cookie
|
||||
* 0x63 0x82 0x53 0x63 */
|
||||
};
|
||||
typedef struct hio_dhcp4_pkt_hdr_t hio_dhcp4_pkt_hdr_t;
|
||||
|
||||
struct hio_dhcp4_opt_hdr_t
|
||||
{
|
||||
hio_uint8_t code;
|
||||
hio_uint8_t len;
|
||||
};
|
||||
typedef struct hio_dhcp4_opt_hdr_t hio_dhcp4_opt_hdr_t;
|
||||
|
||||
/* --------------------------------------------------- */
|
||||
#include <hio-upac.h>
|
||||
/* --------------------------------------------------- */
|
||||
|
||||
|
||||
typedef int (*hio_dhcp4_opt_walker_t) (hio_dhcp4_opt_hdr_t* opt);
|
||||
|
||||
struct hio_dhcp4_pktinf_t
|
||||
{
|
||||
hio_dhcp4_pkt_hdr_t* hdr;
|
||||
hio_oow_t len;
|
||||
};
|
||||
typedef struct hio_dhcp4_pktinf_t hio_dhcp4_pktinf_t;
|
||||
|
||||
struct hio_dhcp4_pktbuf_t
|
||||
{
|
||||
hio_dhcp4_pkt_hdr_t* hdr;
|
||||
hio_oow_t len;
|
||||
hio_oow_t capa;
|
||||
};
|
||||
typedef struct hio_dhcp4_pktbuf_t hio_dhcp4_pktbuf_t;
|
||||
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
#define HIO_DHCP6_SERVER_PORT (547)
|
||||
#define HIO_DHCP6_CLIENT_PORT (546)
|
||||
#define HIO_DHCP6_HOP_COUNT_LIMIT (32)
|
||||
@ -52,15 +213,26 @@ typedef enum hio_dhcp6_msg_t hio_dhcp6_msg_t;
|
||||
|
||||
enum hio_dhcp6_opt_t
|
||||
{
|
||||
HIO_DHCP6_OPT_CLIENTID = 1,
|
||||
HIO_DHCP6_OPT_SERVERID = 2,
|
||||
HIO_DHCP6_OPT_IA_NA = 3,
|
||||
HIO_DHCP6_OPT_IA_TA = 4,
|
||||
HIO_DHCP6_OPT_IAADDR = 5,
|
||||
HIO_DHCP6_OPT_PREFERENCE = 7,
|
||||
HIO_DHCP6_OPT_ELAPSED_TIME = 8,
|
||||
HIO_DHCP6_OPT_RELAY_MESSAGE = 9,
|
||||
HIO_DHCP6_OPT_INTERFACE_ID = 18
|
||||
HIO_DHCP6_OPT_RAPID_COMMIT = 14,
|
||||
HIO_DHCP6_OPT_USER_CLASS = 15,
|
||||
HIO_DHCP6_OPT_VENDOR_CLASS = 16,
|
||||
HIO_DHCP6_OPT_INTERFACE_ID = 18,
|
||||
HIO_DHCP6_OPT_IA_PD = 25,
|
||||
HIO_DHCP6_OPT_IAPREFIX = 26
|
||||
};
|
||||
typedef enum hio_dhcp6_opt_t hio_dhcp6_opt_t;
|
||||
|
||||
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* --------------------------------------------------- */
|
||||
#include <hio-pac1.h>
|
||||
/* --------------------------------------------------- */
|
||||
|
||||
struct hio_dhcp6_pkt_hdr_t
|
||||
{
|
||||
@ -85,8 +257,9 @@ struct hio_dhcp6_opt_hdr_t
|
||||
};
|
||||
typedef struct hio_dhcp6_opt_hdr_t hio_dhcp6_opt_hdr_t;
|
||||
|
||||
/* --------------------------------------------------- */
|
||||
#include <hio-upac.h>
|
||||
|
||||
/* --------------------------------------------------- */
|
||||
|
||||
struct hio_dhcp6_pktinf_t
|
||||
{
|
||||
@ -95,6 +268,7 @@ struct hio_dhcp6_pktinf_t
|
||||
};
|
||||
typedef struct hio_dhcp6_pktinf_t hio_dhcp6_pktinf_t;
|
||||
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
typedef struct hio_svc_dhcs_t hio_svc_dhcs_t;
|
||||
@ -105,6 +279,66 @@ typedef struct hio_svc_dhcs_t hio_svc_dhcs_t;
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
HIO_EXPORT int hio_dhcp4_init_pktbuf (
|
||||
hio_dhcp4_pktbuf_t* pkt,
|
||||
void* buf,
|
||||
hio_oow_t capa
|
||||
);
|
||||
|
||||
HIO_EXPORT int hio_dhcp4_add_option (
|
||||
hio_dhcp4_pktbuf_t* pkt,
|
||||
int code,
|
||||
void* optr, /**< option data pointer */
|
||||
hio_uint8_t olen /**< option data length */
|
||||
);
|
||||
|
||||
HIO_EXPORT int hio_dhcp4_delete_option (
|
||||
hio_dhcp4_pktbuf_t* pkt,
|
||||
int code
|
||||
);
|
||||
|
||||
HIO_EXPORT void hio_dhcp4_compact_options (
|
||||
hio_dhcp4_pktbuf_t* pkt
|
||||
);
|
||||
|
||||
#if 0
|
||||
HIO_EXPORT int hio_dhcp4_add_options (
|
||||
hio_dhcp4_pkt_hdr_t* pkt,
|
||||
hio_oow_t len,
|
||||
hio_oow_t max,
|
||||
int code,
|
||||
hio_uint8_t* optr, /* option data */
|
||||
hio_uint8_t olen /* option length */
|
||||
);
|
||||
#endif
|
||||
|
||||
HIO_EXPORT int hio_dhcp4_walk_options (
|
||||
const hio_dhcp4_pktinf_t* pkt,
|
||||
hio_dhcp4_opt_walker_t walker
|
||||
);
|
||||
|
||||
HIO_EXPORT hio_dhcp4_opt_hdr_t* hio_dhcp4_find_option (
|
||||
const hio_dhcp4_pktinf_t* pkt,
|
||||
int code
|
||||
);
|
||||
|
||||
HIO_EXPORT hio_uint8_t* hio_dhcp4_get_relay_suboption (
|
||||
const hio_uint8_t* ptr,
|
||||
hio_uint8_t len,
|
||||
int code,
|
||||
hio_uint8_t* olen
|
||||
);
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
HIO_EXPORT hio_dhcp6_opt_hdr_t* hio_dhcp6_find_option (
|
||||
const hio_dhcp6_pktinf_t* pkt,
|
||||
int code
|
||||
);
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
|
||||
HIO_EXPORT hio_svc_dhcs_t* hio_svc_dhcs_start (
|
||||
hio_t* hio,
|
||||
const hio_skad_t* local_binds,
|
||||
@ -119,7 +353,6 @@ HIO_EXPORT void hio_svc_dhcs_stop (
|
||||
static HIO_INLINE hio_t* hio_svc_dhcs_gethio(hio_svc_dhcs_t* svc) { return hio_svc_gethio((hio_svc_t*)svc); }
|
||||
#else
|
||||
#define hio_svc_dhcs_gethio(svc) hio_svc_gethio(svc)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user