added qse_dhcp4_delete_option().
fixed bugs in qse_dhcp4_find_option()
This commit is contained in:
parent
84d1c4c55f
commit
fcd2c4f68b
@ -167,7 +167,7 @@ am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/ac/ar-lib \
|
||||
$(top_srcdir)/ac/compile $(top_srcdir)/ac/config.guess \
|
||||
$(top_srcdir)/ac/config.sub $(top_srcdir)/ac/install-sh \
|
||||
$(top_srcdir)/ac/ltmain.sh $(top_srcdir)/ac/missing \
|
||||
$(top_srcdir)/pkgs/qse.spec.in README ac/ar-lib ac/compile \
|
||||
$(top_srcdir)/pkgs/qse.spec.in ac/ar-lib ac/compile \
|
||||
ac/config.guess ac/config.sub ac/depcomp ac/install-sh \
|
||||
ac/ltmain.sh ac/missing
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
|
@ -179,6 +179,11 @@ QSE_EXPORT int qse_dhcp4_add_option (
|
||||
qse_uint8_t olen /**< option data length */
|
||||
);
|
||||
|
||||
QSE_EXPORT int qse_dhcp4_delete_option (
|
||||
qse_dhcp4_pktbuf_t* pkt,
|
||||
int code
|
||||
);
|
||||
|
||||
QSE_EXPORT void qse_dhcp4_compact_options (
|
||||
qse_dhcp4_pktbuf_t* pkt
|
||||
);
|
||||
|
@ -77,6 +77,33 @@ int qse_dhcp4_add_option (qse_dhcp4_pktbuf_t* pkt, int code, void* optr, qse_uin
|
||||
return 0;
|
||||
}
|
||||
|
||||
int qse_dhcp4_delete_option (qse_dhcp4_pktbuf_t* pkt, int code)
|
||||
{
|
||||
qse_dhcp4_opt_hdr_t* ohdr;
|
||||
qse_size_t olen;
|
||||
qse_uint8_t* ovend;
|
||||
|
||||
ohdr = qse_dhcp4_find_option((qse_dhcp4_pktinf_t*)pkt, code);
|
||||
if (!ohdr) return -1;
|
||||
|
||||
olen = (code == QSE_DHCP4_OPT_PADDING || code == QSE_DHCP4_OPT_END)? 1: (ohdr->len) + QSE_SIZEOF(*ohdr);
|
||||
|
||||
if ((ohdr >= pkt->hdr->file && ohdr < (ovend = (qse_uint8_t*)pkt->hdr->file + QSE_SIZEOF(pkt->hdr->file))) ||
|
||||
(ohdr >= pkt->hdr->sname && ohdr < (ovend = (qse_uint8_t*)pkt->hdr->sname + QSE_SIZEOF(pkt->hdr->sname))))
|
||||
{
|
||||
/* the option resides in the overload area */
|
||||
QSE_MEMMOVE (ohdr, (qse_uint8_t*)ohdr + olen, ovend - ((qse_uint8_t*)ohdr + olen));
|
||||
QSE_MEMSET (ovend - olen, 0, olen);
|
||||
/* packet length remains unchanged */
|
||||
}
|
||||
else
|
||||
{
|
||||
QSE_MEMMOVE (ohdr, (qse_uint8_t*)ohdr + olen, ((qse_uint8_t*)pkt->hdr + pkt->len) - ((qse_uint8_t*)ohdr + olen));
|
||||
pkt->len -= olen;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void qse_dhcp4_compact_options (qse_dhcp4_pktbuf_t* pkt)
|
||||
{
|
||||
/* TODO: move some optiosn to sname or file fields if they are not in use. */
|
||||
@ -167,7 +194,7 @@ qse_dhcp4_opt_hdr_t* qse_dhcp4_find_option (const qse_dhcp4_pktinf_t* pkt, int c
|
||||
int i;
|
||||
|
||||
optptr[0] = get_option_start(pkt->hdr, pkt->len, &optlen[0]);
|
||||
if (optptr[0] == QSE_NULL) return QSE_NULL;
|
||||
if (!optptr[0]) return QSE_NULL;
|
||||
|
||||
optptr[1] = (const qse_uint8_t*)pkt->hdr->file;
|
||||
optptr[2] = (const qse_uint8_t*)pkt->hdr->sname;
|
||||
@ -184,38 +211,43 @@ qse_dhcp4_opt_hdr_t* qse_dhcp4_find_option (const qse_dhcp4_pktinf_t* pkt, int c
|
||||
/* option code */
|
||||
qse_dhcp4_opt_hdr_t* opthdr;
|
||||
|
||||
if (opt + QSE_SIZEOF(*opthdr) >= end)
|
||||
/* at least 1 byte is available. the check is because of PADDING or END */
|
||||
if (*opt == QSE_DHCP4_OPT_PADDING) continue;
|
||||
if (*opt == QSE_DHCP4_OPT_END)
|
||||
{
|
||||
/*return QSE_NULL; */
|
||||
if (code == QSE_DHCP4_OPT_END)
|
||||
{
|
||||
/* the caller must handle END specially becuase it is only 1 byte long
|
||||
* for no length part in the header */
|
||||
return (qse_dhcp4_opt_hdr_t*)opt;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (opt + QSE_SIZEOF(*opthdr) > end) break;
|
||||
|
||||
opthdr = (qse_dhcp4_opt_hdr_t*)opt;
|
||||
opt += QSE_SIZEOF(*opthdr);
|
||||
|
||||
if (opthdr->code == QSE_DHCP4_OPT_PADDING) continue;
|
||||
if (opthdr->code == QSE_DHCP4_OPT_END) break;
|
||||
|
||||
/* option length */
|
||||
|
||||
if (opthdr->code == code)
|
||||
{
|
||||
if (opt + opthdr->len >= end)
|
||||
{
|
||||
/*return QSE_NULL; */
|
||||
break;
|
||||
}
|
||||
|
||||
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 == QSE_DHCP4_OPT_OVERLOAD)
|
||||
{
|
||||
if (opthdr->len != 1)
|
||||
{
|
||||
/*return QSE_NULL; */
|
||||
break;
|
||||
}
|
||||
|
||||
if (opthdr->len != 1) break;
|
||||
if (*opt & QSE_DHCP4_OPT_OVERLOAD_FILE) optlen[1] = QSE_SIZEOF(pkt->hdr->file);
|
||||
if (*opt & QSE_DHCP4_OPT_OVERLOAD_SNAME) optlen[2] = QSE_SIZEOF(pkt->hdr->sname);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user