开发者

Can you explain how this ip_to_string function works?

开发者 https://www.devze.com 2022-12-29 20:19 出处:网络
#define IPTOSBUFFERS12 char *iptos(u_long in) { static char output[IPTOSBUFFERS][3*4+3+1]; static short which;
#define IPTOSBUFFERS    12
char *iptos(u_long in)
{
    static char output[IPTOSBUFFERS][3*4+3+1];
    static short which;
 开发者_开发知识库   u_char *p;

    p = (u_char *)∈
    which = (which + 1 == IPTOSBUFFERS ? 0 : which + 1);
    _snprintf_s(output[which], sizeof(output[which]), sizeof(output[which]),"%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
    return output[which];
}

Is there something I'm missing to understand it?


Annotated below for your enjoyment:

// This is the number of IP string buffers.
#define IPTOSBUFFERS 12

char *iptos(u_long in)
{
    // 12 buffers, each big enough to hold maximum-sized IP address
    //   and nul terminator.
    static char output[IPTOSBUFFERS][3*4+3+1];

    // Last buffer used.
    static short which;

    // Get uns. char pointer to IP address.
    u_char *p;
    p = (u_char *)∈

    // Move to next string buffer, wrapping if necessary.
    which = (which + 1 == IPTOSBUFFERS ? 0 : which + 1);

    // Output IP address by accessing individual unsigned chars in it.
    _snprintf_s(output[which], sizeof(output[which]), sizeof(output[which]),
        "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);

    // Return the current buffer.
    return output[which];
}

It works because the representation of an IPv4 address is a 32-bit value in memory and each of the four segments occupies one octet each. So it's a relatively simple matter to cast the address of the 32-bit integer to a four-char array then use that array to extract the individual segments. This is, of course, predicated on the data types having specific bit widths so it's not that portable.

The bizarre thing is the 12-IP-Address circular queue. Maybe that was so you could get up to 12 IP addresses at a time without the strings being overwritten although I don't think I've ever encountered a situation where more than two (maybe three for a proxy or pass-thru server) was required at the same time. I don't think it's for thread safety since the modification to which is inherently dangerous in a threaded environment.


Here's an answer, based on what seems to be confusing from the comments.

An IP address is often represented internally as 32 bits. It's often presented as 4 decimal fields, ranging from 0 to 255. To convert from the decimal representation to the 32-bit representation, simple convert the fields from decimal to binary (or hex) from left to right, and concatenate them.

Thus, 1.2.3.4 becomes the fields 0x01, 0x02, 0x03, and 0x04. Thus, the 32-bit (unsigned long) representation of them is: 0x01020304. Of course, this is subject to the byte ordering as well...

To print an 32-bit address as a string, just look at each of the four sets of 8 bits that compose it, and print them as decimal integers with dots in between.

0

精彩评论

暂无评论...
验证码 换一张
取 消