diff --git a/include/resolv.h b/include/resolv.h new file mode 100644 index 0000000000..5ea6dadfbb --- /dev/null +++ b/include/resolv.h @@ -0,0 +1,49 @@ +/**************************************************************************** + * include/resolv.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __INCLUDE_RESOLV_H +#define __INCLUDE_RESOLV_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#if defined(__cplusplus) +extern "C" +{ +#endif + +int b64_ntop(FAR const unsigned char *src, size_t srclen, + FAR char *target, size_t targsize); + +int b64_pton(FAR const char *src, + FAR unsigned char *target, size_t targsize); + +#if defined(__cplusplus) +} +#endif + +#endif /* __INCLUDE_RESOLV_H */ diff --git a/libs/libc/net/Make.defs b/libs/libc/net/Make.defs index cc96901e2b..4820b9df63 100644 --- a/libs/libc/net/Make.defs +++ b/libs/libc/net/Make.defs @@ -35,7 +35,7 @@ # Add the networking C files to the build -CSRCS += lib_addrconfig.c lib_htons.c lib_htonl.c +CSRCS += lib_addrconfig.c lib_base64.c lib_htons.c lib_htonl.c CSRCS += lib_inetaddr.c lib_inetaton.c lib_inetntoa.c CSRCS += lib_inetntop.c lib_inetpton.c CSRCS += lib_etherntoa.c lib_etheraton.c diff --git a/libs/libc/net/lib_base64.c b/libs/libc/net/lib_base64.c new file mode 100644 index 0000000000..97e360212d --- /dev/null +++ b/libs/libc/net/lib_base64.c @@ -0,0 +1,226 @@ +/**************************************************************************** + * libs/libc/net/lib_base64.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const char g_base64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static const char g_pad64 = '='; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int b64_ntop(FAR const unsigned char *src, size_t srclen, + FAR char *target, size_t targsize) +{ + size_t datalen = 0; + + while (srclen >= 3) + { + if ((datalen += 4) >= targsize) + { + return -1; + } + + *target++ = g_base64[src[0] >> 2]; + *target++ = g_base64[((src[0] & 0x03) << 4) + (src[1] >> 4)]; + *target++ = g_base64[((src[1] & 0x0f) << 2) + (src[2] >> 6)]; + *target++ = g_base64[src[2] & 0x3f]; + + src += 3; + srclen -= 3; + } + + if (srclen != 0) + { + if ((datalen += 4) >= targsize) + { + return -1; + } + + *target++ = g_base64[src[0] >> 2]; + if (srclen == 1) + { + *target++ = g_base64[(src[0] & 0x03) << 4]; + *target++ = g_pad64; + } + else + { + *target++ = g_base64[((src[0] & 0x03) << 4) + (src[1] >> 4)]; + *target++ = g_base64[(src[1] & 0x0f) << 2]; + } + + *target++ = g_pad64; + } + + *target = '\0'; + return datalen; +} + +int b64_pton(FAR const char *src, + FAR unsigned char *target, size_t targsize) +{ + FAR char *pos; + size_t datalen = 0; + int state = 0; + int ch; + + while ((ch = *src++) != '\0') + { + if (isspace(ch)) + { + continue; + } + + if (ch == g_pad64) + { + break; + } + + pos = strchr(g_base64, ch); + if (pos == NULL) + { + return -1; + } + + switch (state) + { + case 0: + if (target) + { + if (datalen >= targsize) + { + return -1; + } + + *target = (pos - g_base64) << 2; + } + + state = 1; + break; + + case 1: + if (target) + { + if ((datalen += 1) >= targsize) + { + return -1; + } + + *target++ |= (pos - g_base64) >> 4; + *target = ((pos - g_base64) & 0x0f) << 4; + } + + state = 2; + break; + + case 2: + if (target) + { + if ((datalen += 1) >= targsize) + { + return -1; + } + + *target++ |= (pos - g_base64) >> 2; + *target = ((pos - g_base64) & 0x03) << 6; + } + + state = 3; + break; + + case 3: + if (target) + { + *target++ |= pos - g_base64; + } + + datalen++; + state = 0; + break; + + default: + return -1; + } + } + + if (ch == g_pad64) + { + ch = *src++; + switch (state) + { + case 0: + case 1: + return -1; + + case 2: + for (; ch != '\0'; ch = *src++) + { + if (!isspace(ch)) + { + break; + } + } + + if (ch != g_pad64) + { + return -1; + } + + ch = *src++; + + /* FALLTHROUGH */ + + case 3: + for (; ch != '\0'; ch = *src++) + { + if (!isspace(ch)) + { + return -1; + } + } + + if (target && *target != 0) + { + return -1; + } + } + } + else + { + if (state != 0) + { + return -1; + } + } + + return datalen; +}