added PTR parsing.
added string to skad conversion functions
This commit is contained in:
parent
51865ceaa8
commit
73eff3822b
@ -608,7 +608,6 @@ static void on_dnc_resolve(mio_svc_dnc_t* dnc, mio_dns_msg_t* reqmsg, mio_errnum
|
|||||||
{
|
{
|
||||||
mio_dns_pkt_info_t* pi = MIO_NULL;
|
mio_dns_pkt_info_t* pi = MIO_NULL;
|
||||||
|
|
||||||
|
|
||||||
if (data) // status == MIO_ENOERR
|
if (data) // status == MIO_ENOERR
|
||||||
{
|
{
|
||||||
mio_uint32_t i;
|
mio_uint32_t i;
|
||||||
@ -660,7 +659,7 @@ static void on_dnc_resolve(mio_svc_dnc_t* dnc, mio_dns_msg_t* reqmsg, mio_errnum
|
|||||||
{
|
{
|
||||||
no_valid_reply:
|
no_valid_reply:
|
||||||
if (status == MIO_ETMOUT) printf ("XXXXXXXXXXXXXXXX TIMED OUT XXXXXXXXXXXXXXXXX\n");
|
if (status == MIO_ETMOUT) printf ("XXXXXXXXXXXXXXXX TIMED OUT XXXXXXXXXXXXXXXXX\n");
|
||||||
else printf ("XXXXXXXXXXXXXXXXx NO REPLY XXXXXXXXXXXXXXXXXXXXXXXXX\n");
|
else printf ("XXXXXXXXXXXXXXXXx NO VALID REPLY XXXXXXXXXXXXXXXXXXXXXXXXX\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
@ -698,6 +697,10 @@ static void on_dnc_resolve_brief (mio_svc_dnc_t* dnc, mio_dns_msg_t* reqmsg, mio
|
|||||||
{
|
{
|
||||||
printf ("^^^ SIMPLE -> NS [%s] %d\n", brr->dptr, (int)brr->dlen);
|
printf ("^^^ SIMPLE -> NS [%s] %d\n", brr->dptr, (int)brr->dlen);
|
||||||
}
|
}
|
||||||
|
else if (brr->rrtype == MIO_DNS_RRT_PTR)
|
||||||
|
{
|
||||||
|
printf ("^^^ SIMPLE -> PTR [%s] %d\n", brr->dptr, (int)brr->dlen);
|
||||||
|
}
|
||||||
else if (brr->rrtype == MIO_DNS_RRT_SOA)
|
else if (brr->rrtype == MIO_DNS_RRT_SOA)
|
||||||
{
|
{
|
||||||
mio_dns_brrd_soa_t* soa = brr->dptr;
|
mio_dns_brrd_soa_t* soa = brr->dptr;
|
||||||
@ -711,7 +714,7 @@ static void on_dnc_resolve_brief (mio_svc_dnc_t* dnc, mio_dns_msg_t* reqmsg, mio
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (status == MIO_ETMOUT) printf ("QQQQQQQQQQQQQQQQQQQ TIMED OUT QQQQQQQQQQQQQQQQQ\n");
|
if (status == MIO_ETMOUT) printf ("QQQQQQQQQQQQQQQQQQQ TIMED OUT QQQQQQQQQQQQQQQQQ\n");
|
||||||
else printf ("QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ NO REPLY QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQq\n");
|
else printf ("QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ NO VALID REPLY QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQq - %d\n", mio_geterrnum(mio_svc_dnc_getmio(dnc)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1014,6 +1017,11 @@ if (!mio_svc_dnc_resolve(dnc, "code.miflux.com", MIO_DNS_RRT_A, MIO_SVC_DNC_RESO
|
|||||||
printf ("resolve attempt failure ---> code.miflux.com\n");
|
printf ("resolve attempt failure ---> code.miflux.com\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!mio_svc_dnc_resolve(dnc, "1.1.1.1.in-addr.arpa", MIO_DNS_RRT_PTR, MIO_SVC_DNC_RESOLVE_FLAG_BRIEF, on_dnc_resolve_brief, 0))
|
||||||
|
{
|
||||||
|
printf ("resolve attempt failure ---> 1.1.1.1.in-addr.arpa\n");
|
||||||
|
}
|
||||||
|
|
||||||
//if (!mio_svc_dnc_resolve(dnc, "ipv6.google.com", MIO_DNS_RRT_AAAA, MIO_SVC_DNC_RESOLVE_FLAG_BRIEF, on_dnc_resolve_brief, 0))
|
//if (!mio_svc_dnc_resolve(dnc, "ipv6.google.com", MIO_DNS_RRT_AAAA, MIO_SVC_DNC_RESOLVE_FLAG_BRIEF, on_dnc_resolve_brief, 0))
|
||||||
if (!mio_svc_dnc_resolve(dnc, "google.com", MIO_DNS_RRT_SOA, MIO_SVC_DNC_RESOLVE_FLAG_BRIEF, on_dnc_resolve_brief, 0))
|
if (!mio_svc_dnc_resolve(dnc, "google.com", MIO_DNS_RRT_SOA, MIO_SVC_DNC_RESOLVE_FLAG_BRIEF, on_dnc_resolve_brief, 0))
|
||||||
//if (!mio_svc_dnc_resolve(dnc, "google.com", MIO_DNS_RRT_NS, MIO_SVC_DNC_RESOLVE_FLAG_BRIEF, on_dnc_resolve_brief, 0))
|
//if (!mio_svc_dnc_resolve(dnc, "google.com", MIO_DNS_RRT_NS, MIO_SVC_DNC_RESOLVE_FLAG_BRIEF, on_dnc_resolve_brief, 0))
|
||||||
|
@ -221,7 +221,7 @@ static int dnc_on_read (mio_dev_sck_t* dev, const void* data, mio_iolen_t dlen,
|
|||||||
mio_dns_msg_t* reqmsg;
|
mio_dns_msg_t* reqmsg;
|
||||||
mio_uint16_t id;
|
mio_uint16_t id;
|
||||||
|
|
||||||
if (dlen < MIO_SIZEOF(*pkt))
|
if (MIO_UNLIKELY(dlen < MIO_SIZEOF(*pkt)))
|
||||||
{
|
{
|
||||||
MIO_DEBUG0 (mio, "dns packet too small from ....\n"); /* TODO: add source packet */
|
MIO_DEBUG0 (mio, "dns packet too small from ....\n"); /* TODO: add source packet */
|
||||||
return 0; /* drop */
|
return 0; /* drop */
|
||||||
@ -450,21 +450,6 @@ mio_dns_msg_t* mio_svc_dnc_sendmsg (mio_svc_dnc_t* dnc, mio_dns_bhdr_t* bdns, mi
|
|||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
mio_dns_msg_t* mio_svc_dnc_resendmsg (mio_svc_dnc_t* dnc, mio_dns_msg_t* msg)
|
|
||||||
{
|
|
||||||
if (mio_dev_sck_write(dnc->sck, mio_dns_msg_to_pkt(msg), msg->pktlen, msg, &dnc->serveraddr) <= -1)
|
|
||||||
{
|
|
||||||
release_dns_msg (dnc, msg);
|
|
||||||
return MIO_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
msg->no_release = 1; ????
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
mio_dns_msg_t* mio_svc_dnc_sendreq (mio_svc_dnc_t* dnc, mio_dns_bhdr_t* bdns, mio_dns_bqr_t* qr, mio_dns_bedns_t* edns, mio_svc_dnc_on_reply_t on_reply, mio_oow_t xtnsize)
|
mio_dns_msg_t* mio_svc_dnc_sendreq (mio_svc_dnc_t* dnc, mio_dns_bhdr_t* bdns, mio_dns_bqr_t* qr, mio_dns_bedns_t* edns, mio_svc_dnc_on_reply_t on_reply, mio_oow_t xtnsize)
|
||||||
{
|
{
|
||||||
/* send a request without resource records */
|
/* send a request without resource records */
|
||||||
@ -497,9 +482,17 @@ typedef struct dnc_dns_msg_resolve_xtn_t dnc_dns_msg_resolve_xtn_t;
|
|||||||
static void on_dnc_resolve (mio_svc_dnc_t* dnc, mio_dns_msg_t* reqmsg, mio_errnum_t status, const void* data, mio_oow_t dlen)
|
static void on_dnc_resolve (mio_svc_dnc_t* dnc, mio_dns_msg_t* reqmsg, mio_errnum_t status, const void* data, mio_oow_t dlen)
|
||||||
{
|
{
|
||||||
mio_t* mio = mio_svc_dnc_getmio(dnc);
|
mio_t* mio = mio_svc_dnc_getmio(dnc);
|
||||||
|
mio_dns_pkt_t* pkt;
|
||||||
mio_dns_pkt_info_t* pi = MIO_NULL;
|
mio_dns_pkt_info_t* pi = MIO_NULL;
|
||||||
dnc_dns_msg_resolve_xtn_t* reqmsgxtn = dnc_dns_msg_resolve_getxtn(reqmsg);
|
dnc_dns_msg_resolve_xtn_t* reqmsgxtn = dnc_dns_msg_resolve_getxtn(reqmsg);
|
||||||
|
|
||||||
|
MIO_ASSERT (mio, dlen >= MIO_SIZEOF(*pkt)); /* this is guaranteed by the dnc_on_read() */
|
||||||
|
pkt = (mio_dns_pkt_t*)data;
|
||||||
|
if (pkt->tc && (reqmsgxtn->flags & MIO_SVC_DNC_RESOLVE_FLAG_TCP_IF_TC)) /* truncated */
|
||||||
|
{
|
||||||
|
/* TODO: */
|
||||||
|
}
|
||||||
|
|
||||||
if (!(reqmsgxtn->flags & MIO_SVC_DNC_RESOLVE_FLAG_BRIEF))
|
if (!(reqmsgxtn->flags & MIO_SVC_DNC_RESOLVE_FLAG_BRIEF))
|
||||||
{
|
{
|
||||||
/* the full reply packet is requested. no transformation is required */
|
/* the full reply packet is requested. no transformation is required */
|
||||||
@ -799,11 +792,12 @@ static int parse_answer_rr (mio_t* mio, mio_dns_rr_part_t rr_part, mio_oow_t pos
|
|||||||
|
|
||||||
case MIO_DNS_RRT_CNAME:
|
case MIO_DNS_RRT_CNAME:
|
||||||
case MIO_DNS_RRT_NS:
|
case MIO_DNS_RRT_NS:
|
||||||
|
case MIO_DNS_RRT_PTR:
|
||||||
{
|
{
|
||||||
#if !defined(MIO_BUILD_RELEASE)
|
#if !defined(MIO_BUILD_RELEASE)
|
||||||
mio_uint8_t* xptr = pi->_ptr;
|
mio_uint8_t* xptr = pi->_ptr;
|
||||||
#endif
|
#endif
|
||||||
if (parse_domain_name(mio, pi) <= -1) return -1;
|
if (parse_domain_name(mio, pi) <= -1) goto oops;
|
||||||
MIO_ASSERT (mio, pi->_ptr == xptr + dlen);
|
MIO_ASSERT (mio, pi->_ptr == xptr + dlen);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -822,10 +816,10 @@ static int parse_answer_rr (mio_t* mio, mio_dns_rr_part_t rr_part, mio_oow_t pos
|
|||||||
pi->_rrdptr += MIO_SIZEOF(*soa);
|
pi->_rrdptr += MIO_SIZEOF(*soa);
|
||||||
|
|
||||||
soa->mname = (mio_bch_t*)pi->_rrdptr;
|
soa->mname = (mio_bch_t*)pi->_rrdptr;
|
||||||
if (parse_domain_name(mio, pi) <= -1) return -1;
|
if (parse_domain_name(mio, pi) <= -1) goto oops;
|
||||||
|
|
||||||
soa->rname = (mio_bch_t*)pi->_rrdptr;
|
soa->rname = (mio_bch_t*)pi->_rrdptr;
|
||||||
if (parse_domain_name(mio, pi) <= -1) return -1;
|
if (parse_domain_name(mio, pi) <= -1) goto oops;
|
||||||
|
|
||||||
MIO_MEMCPY (&soa->serial, pi->_ptr, 20);
|
MIO_MEMCPY (&soa->serial, pi->_ptr, 20);
|
||||||
soa->serial = mio_ntoh32(soa->serial);
|
soa->serial = mio_ntoh32(soa->serial);
|
||||||
@ -836,9 +830,10 @@ static int parse_answer_rr (mio_t* mio, mio_dns_rr_part_t rr_part, mio_oow_t pos
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (parse_domain_name(mio, pi) <= -1) return -1;
|
if (parse_domain_name(mio, pi) <= -1) goto oops;
|
||||||
if (parse_domain_name(mio, pi) <= -1) return -1;
|
if (parse_domain_name(mio, pi) <= -1) goto oops;
|
||||||
}
|
}
|
||||||
|
if (MIO_UNLIKELY(pi->_end - pi->_ptr) < 20) goto oops;
|
||||||
pi->_ptr += 20;
|
pi->_ptr += 20;
|
||||||
|
|
||||||
MIO_ASSERT (mio, pi->_ptr == xptr + dlen);
|
MIO_ASSERT (mio, pi->_ptr == xptr + dlen);
|
||||||
@ -966,14 +961,13 @@ void mio_dns_free_packet_info (mio_t* mio, mio_dns_pkt_info_t* pi)
|
|||||||
|
|
||||||
/* ----------------------------------------------------------------------- */
|
/* ----------------------------------------------------------------------- */
|
||||||
|
|
||||||
static mio_oow_t encode_rdata_in_dns_msg (mio_t* mio, const mio_dns_brr_t* rr, mio_dns_rrtr_t* rrtr)
|
static mio_oow_t encode_rrdata_in_dns_msg (mio_t* mio, const mio_dns_brr_t* rr, mio_dns_rrtr_t* rrtr)
|
||||||
{
|
{
|
||||||
switch (rr->rrtype)
|
switch (rr->rrtype)
|
||||||
{
|
{
|
||||||
case MIO_DNS_RRT_A:
|
case MIO_DNS_RRT_A:
|
||||||
break;
|
break;
|
||||||
case MIO_DNS_RRT_AAAA:
|
case MIO_DNS_RRT_AAAA:
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -993,6 +987,7 @@ static mio_oow_t encode_rdata_in_dns_msg (mio_t* mio, const mio_dns_brr_t* rr, m
|
|||||||
case MIO_DNS_RRT_NS:
|
case MIO_DNS_RRT_NS:
|
||||||
case MIO_DNS_RRT_PTR:
|
case MIO_DNS_RRT_PTR:
|
||||||
/* just a normal domain name */
|
/* just a normal domain name */
|
||||||
|
/* TODO: take a null-terminated string and encode it using to_dn() */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@ -1130,7 +1125,7 @@ mio_dns_msg_t* mio_dns_make_msg (mio_t* mio, mio_dns_bhdr_t* bhdr, mio_dns_bqr_t
|
|||||||
rrtr->rrclass = mio_hton16(rr[i].rrclass);
|
rrtr->rrclass = mio_hton16(rr[i].rrclass);
|
||||||
rrtr->ttl = mio_hton32(rr[i].ttl);
|
rrtr->ttl = mio_hton32(rr[i].ttl);
|
||||||
|
|
||||||
rdata_len = encode_rdata_in_dns_msg(mio, &rr[i], rrtr);
|
rdata_len = encode_rrdata_in_dns_msg(mio, &rr[i], rrtr);
|
||||||
dn = (mio_uint8_t*)(rrtr + 1) + rdata_len;
|
dn = (mio_uint8_t*)(rrtr + 1) + rdata_len;
|
||||||
|
|
||||||
match_count++;
|
match_count++;
|
||||||
|
@ -391,7 +391,8 @@ typedef void (*mio_svc_dnc_on_resolve_t) (
|
|||||||
|
|
||||||
enum mio_svc_dnc_resolve_flag_t
|
enum mio_svc_dnc_resolve_flag_t
|
||||||
{
|
{
|
||||||
MIO_SVC_DNC_RESOLVE_FLAG_BRIEF = (1 << 0)
|
MIO_SVC_DNC_RESOLVE_FLAG_BRIEF = (1 << 0),
|
||||||
|
MIO_SVC_DNC_RESOLVE_FLAG_TCP_IF_TC = (1 << 1)
|
||||||
};
|
};
|
||||||
typedef enum mio_svc_dnc_resolve_flag_t mio_svc_dnc_resolve_flag_t;
|
typedef enum mio_svc_dnc_resolve_flag_t mio_svc_dnc_resolve_flag_t;
|
||||||
|
|
||||||
|
@ -67,6 +67,44 @@ typedef struct mio_skad_t mio_skad_t;
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
MIO_EXPORT int mio_ucharstoskad (
|
||||||
|
mio_t* mio,
|
||||||
|
const mio_uch_t* str,
|
||||||
|
mio_oow_t len,
|
||||||
|
mio_skad_t* skad
|
||||||
|
);
|
||||||
|
|
||||||
|
MIO_EXPORT int mio_bcharstoskad (
|
||||||
|
mio_t* mio,
|
||||||
|
const mio_bch_t* str,
|
||||||
|
mio_oow_t len,
|
||||||
|
mio_skad_t* skad
|
||||||
|
);
|
||||||
|
|
||||||
|
MIO_EXPORT mio_oow_t mio_skadtoucstr (
|
||||||
|
mio_t* mio,
|
||||||
|
const mio_skad_t* skad,
|
||||||
|
mio_uch_t* buf,
|
||||||
|
mio_oow_t len,
|
||||||
|
int flags
|
||||||
|
);
|
||||||
|
|
||||||
|
MIO_EXPORT mio_oow_t mio_skadtobcstr (
|
||||||
|
mio_t* mio,
|
||||||
|
const mio_skad_t* skad,
|
||||||
|
mio_bch_t* buf,
|
||||||
|
mio_oow_t len,
|
||||||
|
int flags
|
||||||
|
);
|
||||||
|
|
||||||
|
#if defined(MIO_OOCH_IS_UCH)
|
||||||
|
# define mio_oocharstoskad mio_ucharstoskad
|
||||||
|
# define mio_skadtooocstr mio_skadtoucstr
|
||||||
|
#else
|
||||||
|
# define mio_oocharstoskad mio_bcharstoskad
|
||||||
|
# define mio_skadtooocstr mio_skadtobcstr
|
||||||
|
#endif
|
||||||
|
|
||||||
MIO_EXPORT int mio_skad_family (
|
MIO_EXPORT int mio_skad_family (
|
||||||
const mio_skad_t* skad
|
const mio_skad_t* skad
|
||||||
);
|
);
|
||||||
|
410
mio/lib/skad.c
410
mio/lib/skad.c
@ -62,12 +62,54 @@ union mio_skad_alt_t
|
|||||||
typedef union mio_skad_alt_t mio_skad_alt_t;
|
typedef union mio_skad_alt_t mio_skad_alt_t;
|
||||||
|
|
||||||
|
|
||||||
static int str_to_ipv4 (const mio_ooch_t* str, mio_oow_t len, struct in_addr* inaddr)
|
static int uchars_to_ipv4 (const mio_uch_t* str, mio_oow_t len, struct in_addr* inaddr)
|
||||||
{
|
{
|
||||||
const mio_ooch_t* end;
|
const mio_uch_t* end;
|
||||||
int dots = 0, digits = 0;
|
int dots = 0, digits = 0;
|
||||||
mio_uint32_t acc = 0, addr = 0;
|
mio_uint32_t acc = 0, addr = 0;
|
||||||
mio_ooch_t c;
|
mio_uch_t c;
|
||||||
|
|
||||||
|
end = str + len;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (str >= end)
|
||||||
|
{
|
||||||
|
if (dots < 3 || digits == 0) return -1;
|
||||||
|
addr = (addr << 8) | acc;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = *str++;
|
||||||
|
|
||||||
|
if (c >= '0' && c <= '9')
|
||||||
|
{
|
||||||
|
if (digits > 0 && acc == 0) return -1;
|
||||||
|
acc = acc * 10 + (c - '0');
|
||||||
|
if (acc > 255) return -1;
|
||||||
|
digits++;
|
||||||
|
}
|
||||||
|
else if (c == '.')
|
||||||
|
{
|
||||||
|
if (dots >= 3 || digits == 0) return -1;
|
||||||
|
addr = (addr << 8) | acc;
|
||||||
|
dots++; acc = 0; digits = 0;
|
||||||
|
}
|
||||||
|
else return -1;
|
||||||
|
}
|
||||||
|
while (1);
|
||||||
|
|
||||||
|
inaddr->s_addr = mio_hton32(addr);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bchars_to_ipv4 (const mio_bch_t* str, mio_oow_t len, struct in_addr* inaddr)
|
||||||
|
{
|
||||||
|
const mio_bch_t* end;
|
||||||
|
int dots = 0, digits = 0;
|
||||||
|
mio_uint32_t acc = 0, addr = 0;
|
||||||
|
mio_bch_t c;
|
||||||
|
|
||||||
end = str + len;
|
end = str + len;
|
||||||
|
|
||||||
@ -105,14 +147,14 @@ static int str_to_ipv4 (const mio_ooch_t* str, mio_oow_t len, struct in_addr* in
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if (MIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
|
#if (MIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
|
||||||
static int str_to_ipv6 (const mio_ooch_t* src, mio_oow_t len, struct in6_addr* inaddr)
|
static int uchars_to_ipv6 (const mio_uch_t* src, mio_oow_t len, struct in6_addr* inaddr)
|
||||||
{
|
{
|
||||||
mio_uint8_t* tp, * endp, * colonp;
|
mio_uint8_t* tp, * endp, * colonp;
|
||||||
const mio_ooch_t* curtok;
|
const mio_uch_t* curtok;
|
||||||
mio_ooch_t ch;
|
mio_uch_t ch;
|
||||||
int saw_xdigit;
|
int saw_xdigit;
|
||||||
unsigned int val;
|
unsigned int val;
|
||||||
const mio_ooch_t* src_end;
|
const mio_uch_t* src_end;
|
||||||
|
|
||||||
src_end = src + len;
|
src_end = src + len;
|
||||||
|
|
||||||
@ -177,7 +219,117 @@ static int str_to_ipv6 (const mio_ooch_t* src, mio_oow_t len, struct in6_addr* i
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ch == '.' && ((tp + MIO_SIZEOF(struct in_addr)) <= endp) &&
|
if (ch == '.' && ((tp + MIO_SIZEOF(struct in_addr)) <= endp) &&
|
||||||
str_to_ipv4(curtok, src_end - curtok, (struct in_addr*)tp) == 0)
|
uchars_to_ipv4(curtok, src_end - curtok, (struct in_addr*)tp) == 0)
|
||||||
|
{
|
||||||
|
tp += MIO_SIZEOF(struct in_addr*);
|
||||||
|
saw_xdigit = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (saw_xdigit)
|
||||||
|
{
|
||||||
|
if (tp + MIO_SIZEOF(mio_uint16_t) > endp) return -1;
|
||||||
|
*tp++ = (mio_uint8_t)(val >> 8) & 0xff;
|
||||||
|
*tp++ = (mio_uint8_t)val & 0xff;
|
||||||
|
}
|
||||||
|
if (colonp != MIO_NULL)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Since some memmove()'s erroneously fail to handle
|
||||||
|
* overlapping regions, we'll do the shift by hand.
|
||||||
|
*/
|
||||||
|
mio_oow_t n = tp - colonp;
|
||||||
|
mio_oow_t i;
|
||||||
|
|
||||||
|
for (i = 1; i <= n; i++)
|
||||||
|
{
|
||||||
|
endp[-i] = colonp[n - i];
|
||||||
|
colonp[n - i] = 0;
|
||||||
|
}
|
||||||
|
tp = endp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tp != endp) return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bchars_to_ipv6 (const mio_bch_t* src, mio_oow_t len, struct in6_addr* inaddr)
|
||||||
|
{
|
||||||
|
mio_uint8_t* tp, * endp, * colonp;
|
||||||
|
const mio_bch_t* curtok;
|
||||||
|
mio_bch_t ch;
|
||||||
|
int saw_xdigit;
|
||||||
|
unsigned int val;
|
||||||
|
const mio_bch_t* src_end;
|
||||||
|
|
||||||
|
src_end = src + len;
|
||||||
|
|
||||||
|
MIO_MEMSET (inaddr, 0, MIO_SIZEOF(*inaddr));
|
||||||
|
tp = &inaddr->s6_addr[0];
|
||||||
|
endp = &inaddr->s6_addr[MIO_COUNTOF(inaddr->s6_addr)];
|
||||||
|
colonp = MIO_NULL;
|
||||||
|
|
||||||
|
/* Leading :: requires some special handling. */
|
||||||
|
if (src < src_end && *src == ':')
|
||||||
|
{
|
||||||
|
src++;
|
||||||
|
if (src >= src_end || *src != ':') return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
curtok = src;
|
||||||
|
saw_xdigit = 0;
|
||||||
|
val = 0;
|
||||||
|
|
||||||
|
while (src < src_end)
|
||||||
|
{
|
||||||
|
int v1;
|
||||||
|
|
||||||
|
ch = *src++;
|
||||||
|
|
||||||
|
if (ch >= '0' && ch <= '9')
|
||||||
|
v1 = ch - '0';
|
||||||
|
else if (ch >= 'A' && ch <= 'F')
|
||||||
|
v1 = ch - 'A' + 10;
|
||||||
|
else if (ch >= 'a' && ch <= 'f')
|
||||||
|
v1 = ch - 'a' + 10;
|
||||||
|
else v1 = -1;
|
||||||
|
if (v1 >= 0)
|
||||||
|
{
|
||||||
|
val <<= 4;
|
||||||
|
val |= v1;
|
||||||
|
if (val > 0xffff) return -1;
|
||||||
|
saw_xdigit = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ch == ':')
|
||||||
|
{
|
||||||
|
curtok = src;
|
||||||
|
if (!saw_xdigit)
|
||||||
|
{
|
||||||
|
if (colonp) return -1;
|
||||||
|
colonp = tp;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (src >= src_end)
|
||||||
|
{
|
||||||
|
/* a colon can't be the last character */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*tp++ = (mio_uint8_t)(val >> 8) & 0xff;
|
||||||
|
*tp++ = (mio_uint8_t)val & 0xff;
|
||||||
|
saw_xdigit = 0;
|
||||||
|
val = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ch == '.' && ((tp + MIO_SIZEOF(struct in_addr)) <= endp) &&
|
||||||
|
bchars_to_ipv4(curtok, src_end - curtok, (struct in_addr*)tp) == 0)
|
||||||
{
|
{
|
||||||
tp += MIO_SIZEOF(struct in_addr*);
|
tp += MIO_SIZEOF(struct in_addr*);
|
||||||
saw_xdigit = 0;
|
saw_xdigit = 0;
|
||||||
@ -216,12 +368,14 @@ static int str_to_ipv6 (const mio_ooch_t* src, mio_oow_t len, struct in6_addr* i
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int mio_oocharstoskad (mio_t* mio, const mio_ooch_t* str, mio_oow_t len, mio_skad_t* _skad)
|
/* ---------------------------------------------------------- */
|
||||||
|
|
||||||
|
int mio_ucharstoskad (mio_t* mio, const mio_uch_t* str, mio_oow_t len, mio_skad_t* _skad)
|
||||||
{
|
{
|
||||||
mio_skad_alt_t* skad = (mio_skad_alt_t*)_skad;
|
mio_skad_alt_t* skad = (mio_skad_alt_t*)_skad;
|
||||||
const mio_ooch_t* p;
|
const mio_uch_t* p;
|
||||||
const mio_ooch_t* end;
|
const mio_uch_t* end;
|
||||||
mio_oocs_t tmp;
|
mio_ucs_t tmp;
|
||||||
|
|
||||||
p = str;
|
p = str;
|
||||||
end = str + len;
|
end = str + len;
|
||||||
@ -237,14 +391,10 @@ int mio_oocharstoskad (mio_t* mio, const mio_ooch_t* str, mio_oow_t len, mio_ska
|
|||||||
#if defined(AF_UNIX)
|
#if defined(AF_UNIX)
|
||||||
if (*p == '/' && len >= 2)
|
if (*p == '/' && len >= 2)
|
||||||
{
|
{
|
||||||
#if defined(MIO_OOCH_IS_BCH)
|
|
||||||
mio_copy_bcstr (skad->un.sun_path, MIO_COUNTOF(skad->un.sun_path), str);
|
|
||||||
#else
|
|
||||||
mio_oow_t dstlen;
|
mio_oow_t dstlen;
|
||||||
dstlen = MIO_COUNTOF(skad->un.sun_path) - 1;
|
dstlen = MIO_COUNTOF(skad->un.sun_path) - 1;
|
||||||
if (mio_convutobchars(mio, p, &len, skad->un.sun_path, &dstlen) <= -1) return -1;
|
if (mio_convutobchars(mio, p, &len, skad->un.sun_path, &dstlen) <= -1) return -1;
|
||||||
skad->un.sun_path[dstlen] = '\0';
|
skad->un.sun_path[dstlen] = '\0';
|
||||||
#endif
|
|
||||||
skad->un.sun_family = AF_UNIX;
|
skad->un.sun_family = AF_UNIX;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -254,7 +404,7 @@ int mio_oocharstoskad (mio_t* mio, const mio_ooch_t* str, mio_oow_t len, mio_ska
|
|||||||
if (*p == '[')
|
if (*p == '[')
|
||||||
{
|
{
|
||||||
/* IPv6 address */
|
/* IPv6 address */
|
||||||
tmp.ptr = (mio_ooch_t*)++p; /* skip [ and remember the position */
|
tmp.ptr = (mio_uch_t*)++p; /* skip [ and remember the position */
|
||||||
while (p < end && *p != '%' && *p != ']') p++;
|
while (p < end && *p != '%' && *p != ']') p++;
|
||||||
|
|
||||||
if (p >= end) goto no_rbrack;
|
if (p >= end) goto no_rbrack;
|
||||||
@ -294,7 +444,7 @@ int mio_oocharstoskad (mio_t* mio, const mio_ooch_t* str, mio_oow_t len, mio_ska
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* interface name as a scope id? */
|
/* interface name as a scope id? */
|
||||||
const mio_ooch_t* stmp = p;
|
const mio_uch_t* stmp = p;
|
||||||
unsigned int index;
|
unsigned int index;
|
||||||
do p++; while (p < end && *p != ']');
|
do p++; while (p < end && *p != ']');
|
||||||
if (mio_ucharstoifindex(mio, stmp, p - stmp, &index) <= -1) return -1;
|
if (mio_ucharstoifindex(mio, stmp, p - stmp, &index) <= -1) return -1;
|
||||||
@ -305,18 +455,18 @@ int mio_oocharstoskad (mio_t* mio, const mio_ooch_t* str, mio_oow_t len, mio_ska
|
|||||||
}
|
}
|
||||||
p++; /* skip ] */
|
p++; /* skip ] */
|
||||||
|
|
||||||
if (str_to_ipv6(tmp.ptr, tmp.len, &skad->in6.sin6_addr) <= -1) goto unrecog;
|
if (uchars_to_ipv6(tmp.ptr, tmp.len, &skad->in6.sin6_addr) <= -1) goto unrecog;
|
||||||
skad->in6.sin6_family = AF_INET6;
|
skad->in6.sin6_family = AF_INET6;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
/* IPv4 address */
|
/* IPv4 address */
|
||||||
tmp.ptr = (mio_ooch_t*)p;
|
tmp.ptr = (mio_uch_t*)p;
|
||||||
while (p < end && *p != ':') p++;
|
while (p < end && *p != ':') p++;
|
||||||
tmp.len = p - tmp.ptr;
|
tmp.len = p - tmp.ptr;
|
||||||
|
|
||||||
if (str_to_ipv4(tmp.ptr, tmp.len, &skad->in4.sin_addr) <= -1)
|
if (uchars_to_ipv4(tmp.ptr, tmp.len, &skad->in4.sin_addr) <= -1)
|
||||||
{
|
{
|
||||||
#if (MIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
|
#if (MIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
|
||||||
/* check if it is an IPv6 address not enclosed in [].
|
/* check if it is an IPv6 address not enclosed in [].
|
||||||
@ -327,11 +477,10 @@ int mio_oocharstoskad (mio_t* mio, const mio_ooch_t* str, mio_oow_t len, mio_ska
|
|||||||
goto unrecog;
|
goto unrecog;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
while (p < end && *p != '%') p++;
|
while (p < end && *p != '%') p++;
|
||||||
tmp.len = p - tmp.ptr;
|
tmp.len = p - tmp.ptr;
|
||||||
|
|
||||||
if (str_to_ipv6(tmp.ptr, tmp.len, &skad->in6.sin6_addr) <= -1) goto unrecog;
|
if (uchars_to_ipv6(tmp.ptr, tmp.len, &skad->in6.sin6_addr) <= -1) goto unrecog;
|
||||||
|
|
||||||
if (p < end && *p == '%')
|
if (p < end && *p == '%')
|
||||||
{
|
{
|
||||||
@ -367,7 +516,7 @@ int mio_oocharstoskad (mio_t* mio, const mio_ooch_t* str, mio_oow_t len, mio_ska
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* interface name as a scope id? */
|
/* interface name as a scope id? */
|
||||||
const mio_ooch_t* stmp = p;
|
const mio_uch_t* stmp = p;
|
||||||
unsigned int index;
|
unsigned int index;
|
||||||
do p++; while (p < end);
|
do p++; while (p < end);
|
||||||
if (mio_ucharstoifindex(mio, stmp, p - stmp, &index) <= -1) return -1;
|
if (mio_ucharstoifindex(mio, stmp, p - stmp, &index) <= -1) return -1;
|
||||||
@ -396,7 +545,218 @@ int mio_oocharstoskad (mio_t* mio, const mio_ooch_t* str, mio_oow_t len, mio_ska
|
|||||||
|
|
||||||
p++; /* skip : */
|
p++; /* skip : */
|
||||||
|
|
||||||
tmp.ptr = (mio_ooch_t*)p;
|
tmp.ptr = (mio_uch_t*)p;
|
||||||
|
while (p < end && *p >= '0' && *p <= '9')
|
||||||
|
{
|
||||||
|
port = port * 10 + (*p - '0');
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp.len = p - tmp.ptr;
|
||||||
|
if (tmp.len <= 0 || tmp.len >= 6 ||
|
||||||
|
port > MIO_TYPE_MAX(mio_uint16_t))
|
||||||
|
{
|
||||||
|
mio_seterrbfmt (mio, MIO_EINVAL, "port number blank or too large");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (MIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
|
||||||
|
if (skad->in4.sin_family == AF_INET)
|
||||||
|
skad->in4.sin_port = mio_hton16(port);
|
||||||
|
else
|
||||||
|
skad->in6.sin6_port = mio_hton16(port);
|
||||||
|
#else
|
||||||
|
skad->in4.sin_port = mio_hton16(port);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
unrecog:
|
||||||
|
mio_seterrbfmt (mio, MIO_EINVAL, "unrecognized address");
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
no_rbrack:
|
||||||
|
mio_seterrbfmt (mio, MIO_EINVAL, "missing right bracket");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------- */
|
||||||
|
|
||||||
|
int mio_bcharstoskad (mio_t* mio, const mio_bch_t* str, mio_oow_t len, mio_skad_t* _skad)
|
||||||
|
{
|
||||||
|
mio_skad_alt_t* skad = (mio_skad_alt_t*)_skad;
|
||||||
|
const mio_bch_t* p;
|
||||||
|
const mio_bch_t* end;
|
||||||
|
mio_bcs_t tmp;
|
||||||
|
|
||||||
|
p = str;
|
||||||
|
end = str + len;
|
||||||
|
|
||||||
|
if (p >= end)
|
||||||
|
{
|
||||||
|
mio_seterrbfmt (mio, MIO_EINVAL, "blank address");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
MIO_MEMSET (skad, 0, MIO_SIZEOF(*skad));
|
||||||
|
|
||||||
|
#if defined(AF_UNIX)
|
||||||
|
if (*p == '/' && len >= 2)
|
||||||
|
{
|
||||||
|
mio_copy_bcstr (skad->un.sun_path, MIO_COUNTOF(skad->un.sun_path), str);
|
||||||
|
skad->un.sun_family = AF_UNIX;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (MIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
|
||||||
|
if (*p == '[')
|
||||||
|
{
|
||||||
|
/* IPv6 address */
|
||||||
|
tmp.ptr = (mio_bch_t*)++p; /* skip [ and remember the position */
|
||||||
|
while (p < end && *p != '%' && *p != ']') p++;
|
||||||
|
|
||||||
|
if (p >= end) goto no_rbrack;
|
||||||
|
|
||||||
|
tmp.len = p - tmp.ptr;
|
||||||
|
if (*p == '%')
|
||||||
|
{
|
||||||
|
/* handle scope id */
|
||||||
|
mio_uint32_t x;
|
||||||
|
|
||||||
|
p++; /* skip % */
|
||||||
|
|
||||||
|
if (p >= end)
|
||||||
|
{
|
||||||
|
/* premature end */
|
||||||
|
mio_seterrbfmt (mio, MIO_EINVAL, "scope id blank");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*p >= '0' && *p <= '9')
|
||||||
|
{
|
||||||
|
/* numeric scope id */
|
||||||
|
skad->in6.sin6_scope_id = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
x = skad->in6.sin6_scope_id * 10 + (*p - '0');
|
||||||
|
if (x < skad->in6.sin6_scope_id)
|
||||||
|
{
|
||||||
|
mio_seterrbfmt (mio, MIO_EINVAL, "scope id too large");
|
||||||
|
return -1; /* overflow */
|
||||||
|
}
|
||||||
|
skad->in6.sin6_scope_id = x;
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
while (p < end && *p >= '0' && *p <= '9');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* interface name as a scope id? */
|
||||||
|
const mio_bch_t* stmp = p;
|
||||||
|
unsigned int index;
|
||||||
|
do p++; while (p < end && *p != ']');
|
||||||
|
if (mio_bcharstoifindex(mio, stmp, p - stmp, &index) <= -1) return -1;
|
||||||
|
skad->in6.sin6_scope_id = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p >= end || *p != ']') goto no_rbrack;
|
||||||
|
}
|
||||||
|
p++; /* skip ] */
|
||||||
|
|
||||||
|
if (bchars_to_ipv6(tmp.ptr, tmp.len, &skad->in6.sin6_addr) <= -1) goto unrecog;
|
||||||
|
skad->in6.sin6_family = AF_INET6;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
/* IPv4 address */
|
||||||
|
tmp.ptr = (mio_bch_t*)p;
|
||||||
|
while (p < end && *p != ':') p++;
|
||||||
|
tmp.len = p - tmp.ptr;
|
||||||
|
|
||||||
|
if (bchars_to_ipv4(tmp.ptr, tmp.len, &skad->in4.sin_addr) <= -1)
|
||||||
|
{
|
||||||
|
#if (MIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
|
||||||
|
/* check if it is an IPv6 address not enclosed in [].
|
||||||
|
* the port number can't be specified in this format. */
|
||||||
|
if (p >= end || *p != ':')
|
||||||
|
{
|
||||||
|
/* without :, it can't be an ipv6 address */
|
||||||
|
goto unrecog;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
while (p < end && *p != '%') p++;
|
||||||
|
tmp.len = p - tmp.ptr;
|
||||||
|
|
||||||
|
if (bchars_to_ipv6(tmp.ptr, tmp.len, &skad->in6.sin6_addr) <= -1) goto unrecog;
|
||||||
|
|
||||||
|
if (p < end && *p == '%')
|
||||||
|
{
|
||||||
|
/* handle scope id */
|
||||||
|
mio_uint32_t x;
|
||||||
|
|
||||||
|
p++; /* skip % */
|
||||||
|
|
||||||
|
if (p >= end)
|
||||||
|
{
|
||||||
|
/* premature end */
|
||||||
|
mio_seterrbfmt (mio, MIO_EINVAL, "scope id blank");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*p >= '0' && *p <= '9')
|
||||||
|
{
|
||||||
|
/* numeric scope id */
|
||||||
|
skad->in6.sin6_scope_id = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
x = skad->in6.sin6_scope_id * 10 + (*p - '0');
|
||||||
|
if (x < skad->in6.sin6_scope_id)
|
||||||
|
{
|
||||||
|
mio_seterrbfmt (mio, MIO_EINVAL, "scope id too large");
|
||||||
|
return -1; /* overflow */
|
||||||
|
}
|
||||||
|
skad->in6.sin6_scope_id = x;
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
while (p < end && *p >= '0' && *p <= '9');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* interface name as a scope id? */
|
||||||
|
const mio_bch_t* stmp = p;
|
||||||
|
unsigned int index;
|
||||||
|
do p++; while (p < end);
|
||||||
|
if (mio_bcharstoifindex(mio, stmp, p - stmp, &index) <= -1) return -1;
|
||||||
|
skad->in6.sin6_scope_id = index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p < end) goto unrecog; /* some gargage after the end? */
|
||||||
|
|
||||||
|
skad->in6.sin6_family = AF_INET6;
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
goto unrecog;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
skad->in4.sin_family = AF_INET;
|
||||||
|
#if (MIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (p < end && *p == ':')
|
||||||
|
{
|
||||||
|
/* port number */
|
||||||
|
mio_uint32_t port = 0;
|
||||||
|
|
||||||
|
p++; /* skip : */
|
||||||
|
|
||||||
|
tmp.ptr = (mio_bch_t*)p;
|
||||||
while (p < end && *p >= '0' && *p <= '9')
|
while (p < end && *p >= '0' && *p <= '9')
|
||||||
{
|
{
|
||||||
port = port * 10 + (*p - '0');
|
port = port * 10 + (*p - '0');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user