Byte conversion and padding functions

    In network programming, it is often necessary to convert between the host byte order and the network byte order to ensure that the sending protocol stack and the receiving protocol stack are in the same transmission order of each segment of multi-byte fields such as 32-bit IPv4 addresses. This conversion is achieved using the following four functions.
#include <netinet/in.h>
uint16_t htons(uint16_t host16bitvalue);
uint32_t htonl(uint32_t host32bitvalue);
                           /* Return value: all values ​​in network byte order */
uint16_t ntohs(uint16_t net16bitvalue);
uint32_t ntohl(uint32_t net32bitvalue);
                           /* Return value: all values ​​in host byte order */

    In the names of these functions, h stands for host, n for network, s for short, and l for long. When using these functions, we don't care about the actual value of host byte order and network byte order (big endian or little endian), we just call the appropriate function to convert a given value between host and network byte order . On systems that use the same byte order (big endian) as the Internet Protocol, these four functions are usually defined as empty macros.
   
    There are two sets of functions that operate on multibyte fields that neither interpret the data nor assume that the data is a null-terminated C string. These types of functions are often needed when working with socket address structures, because fields such as IP addresses may contain bytes with a value of 0, but are not C strings.
    The first set of functions whose names begin with b (for bytes) originated in 4.2 BSD. The second group of functions whose names begin with mem (for memory) have their origins in the ANSI C standard.
#include <strings.h>
void bzero(void *dest, size_t nbytes);
void bcopy(const void *src, void *dest, size_t nbytes);
int bcmp(const void *ptr1, const void *ptr2, size_t nbytes);
                                   /* Return value: 0 if equal, non-zero otherwise */

#include <string.h>
void *memset(void *dest, int c, size_t len);
void *memcpy(void *dest, const void *src, size_t nbytes);
int memcmp(const void *ptr1, const void *ptr2, size_t nbytes);
             /* Return value: ptr1==ptr2, return 0; ptr1<ptr2, return a negative number; otherwise return a positive number*/

    bzero Sets the specified number of bytes in the target byte string to 0. This function is often used to initialize a socket address structure to zero. bcopy moves the specified number of bytes from the source bytestring to the destination bytestring. bcmp compares two arbitrary byte strings.
    memset sets the specified number of bytes in the target byte string to c. memcpy is similar to bcopy, but the order of the two pointer arguments is reversed, and when the source byte string overlaps the destination byte string, bcopy can handle it correctly, but the result of the operation of memcpy is not known (in this case, you must use ANSI C's memmove function). memcmp compares two arbitrary byte strings.

    Two sets of address translation functions that convert Internet addresses between ASCII strings and binary values ​​in network byte order are described below.
    1. inet_aton, inet_addr (currently obsolete) and inet_ntoa convert IPv4 addresses between dotted decimal and network byte order.
    2. inet_pton and inet_ntop are applicable to both IPv4 and IPv6 addresses. The p and n in the function name stand for presentation and numeric, respectively. The representation format of the address is usually an ASCII string, and the numerical format is a binary value stored in the socket address mechanism.
#include <arpa/inet.h>

int inet_aton(const char *strptr, struct in_addr *addrptr);
                                   /* Return: 1 if the string is valid, 0 otherwise */
in_addr_t inet_addr(const char *strptr);
           /* Return: IPv4 address in network byte order if the string is valid, otherwise INADDR_NONE */
char * inet_ntoa (struct in_addr inaddr);
                                   /* return: pointer to a dotted decimal string */

int inet_pton(int family, const char *strptr, void *addrptr);
        /* Return: 1 if successful; 0 if input is not a valid expression format; -1 if error */
const char *inet_ntop(int family, const void *addrptr, char *strptr, size_t len);
                            /* return: pointer to result if successful, NULL otherwise */

    inet_aton converts the C string pointed to by strptr into a 32-bit network byte order binary value and stores it through the addrptr pointer. This function has an undocumented feature: if the addrptr pointer is null, the function still performs a validity check on the input string, but does not store any results.
    inet_ntoa Converts a 32-bit network byte order binary IPv4 address to the corresponding dotted decimal. The string pointed to by the return value of this function resides in static memory. This means that the function is not reentrant.
    The family parameter of inte_pton and inet_ntop can be either AF_INET or AF_INET6. Other unsupported values ​​will cause these two functions to return an error and set errno to EAFNOSUPPORT. inet_pton converts the string pointed to by the strptr pointer into a binary value and stores it through the addrptr pointer. inet_ntop does the opposite conversion, from numeric to expressive format. The len parameter is the size of the destination storage unit so that the function does not overflow its caller's buffer. To help specify this size, the following definitions are in <netinet/in.h>:
        #define INET_ADDRSTRLEN 16 // for IPv4 dotted-decimal
        #define INET6_ADDRSTRLEN 46 // for IPv6 hex string
    if len is too small to hold Express the format result (including the trailing null character), then return a null pointer and set errno to ENOSPC.
    The strptr parameter in inet_ntop cannot be a null pointer. The caller must allocate memory for the target storage unit and specify its size. When the call is successful, the pointer is the return value of the function.
    A simple definition of the IPv4-only inet_pton and inet_ntop functions is given below.
int inet_pton(int family, const char *strptr, void *addrptr){
    if (family == AF_INET) {
        struct in_addr in_val;
        if(inet_aton(strptr, &in_val)){
            memcpy(addrptr, &in_val, sizeof(struct in_addr));
            return 1;
        }
        return 0;
    }
    errno = EAFNOSUPPORT;
    return -1;
}

const char *inet_ntop(int family, const void *addrptr, char *strptr, size_t len){
    const u_char *p = (const u_char *)addrptr;
    if (family == AF_INET) {
        char temp[INET_ADDRSTRLEN];
        snprintf(temp, sizeof(temp), "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
        if(strlen(temp) >= len){
            errno = ENOSPC;
            return NULL;
        }
        strcpy(strptr, temp);
        return strptr;
    }
    errno = EAFNOSUPPORT;
    return NULL;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326174898&siteId=291194637