X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=net.c;h=ab6a98940b1e920eee7ee5e3f8f6b9bb33cf94b9;hp=9579b7df73f6a2b795cc41de9f647a71ee754ec1;hb=165a3886ab506f4c13eac4f178a58493432a00ec;hpb=b27f3e8dd53af7209626a9f0e98eb4770602c2e7 diff --git a/net.c b/net.c index 9579b7df..ab6a9894 100644 --- a/net.c +++ b/net.c @@ -92,6 +92,47 @@ void disable_crypt(int fd) crypt_data_array[fd].private_data = NULL; } +/** + * Parse and validate IPv4 address/netmask string. + * + * \param cidr Address in CIDR notation + * \param addr Copy of the IPv4 address part of \a cidr + * \param addrlen Size of \a addr in bytes + * \param netmask Value of the netmask part in \a cidr or the + * default of 32 if not specified. + * + * \return Pointer to \a addr if succesful, NULL on error. + * \sa RFC 4632 + */ +char *parse_cidr(const char *cidr, + char *addr, ssize_t addrlen, + int32_t *netmask) +{ + const char *o = cidr; + char *c = addr, *end = c + (addrlen - 1); + + *netmask = 0x20; + + if (cidr == NULL || addrlen < 1) + goto failed; + + for (o = cidr; (*c = *o == '/'? '\0' : *o); c++, o++) + if (c == end) + goto failed; + + if (*o == '/') + if (para_atoi32(++o, netmask) < 0 || + *netmask < 0 || *netmask > 0x20) + goto failed; + + if (is_valid_ipv4_address(addr)) + return addr; +failed: + *addr = '\0'; + return NULL; +} + + /** * Match string as a candidate IPv4 address. * @@ -434,11 +475,31 @@ static char *__get_sock_name(int fd, int (*getname)(int, struct sockaddr*, return host_and_port((struct sockaddr *)&ss, sslen); } +/** + * Look up the local side of a connected socket structure. + * + * \param sockfd The file descriptor of the socket. + * + * \return A pointer to a static buffer containing hostname an port. This + * buffer must not be freed by the caller. + * + * \sa remote_name(). + */ char *local_name(int sockfd) { return __get_sock_name(sockfd, getsockname); } +/** + * Look up the remote side of a connected socket structure. + * + * \param sockfd The file descriptor of the socket. + * + * \return Analogous to the return value of \ref local_name() but for the + * remote side. + * + * \sa local_name(). + */ char *remote_name(int sockfd) { return __get_sock_name(sockfd, getpeername); @@ -456,7 +517,7 @@ struct in_addr extract_v4_addr(const struct sockaddr_storage *ss) struct in_addr ia = {.s_addr = 0}; if (ss->ss_family == AF_INET) - ia.s_addr = ((struct sockaddr_in *)ss)->sin_addr.s_addr; + ia.s_addr = ((struct sockaddr_in *)ss)->sin_addr.s_addr; if (ss->ss_family == AF_INET6) { const struct in6_addr v6_addr = ((struct sockaddr_in6 *)ss)->sin6_addr; @@ -474,8 +535,8 @@ struct in_addr extract_v4_addr(const struct sockaddr_storage *ss) * \param len The length of \a buf. * * Check if encryption is available. If yes, encrypt the given buffer. Send - * out the buffer, encrypted or not, and try to resend the remaing part in case - * of short writes. + * out the buffer, encrypted or not, and try to resend the remaining part in + * case of short writes. * * \return Standard. */