added qse_dhcp4_delete_option().

fixed bugs in qse_dhcp4_find_option()
This commit is contained in:
hyung-hwan 2023-06-29 12:08:27 +09:00
parent 84d1c4c55f
commit fcd2c4f68b
3 changed files with 56 additions and 19 deletions

View File

@ -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)

View File

@ -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
);

View File

@ -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);
}