The Angry Ox: IP Question: The Answer
 Ok, you must have answered correctly to have gotten this address. So now, you are wondering, how does it really work? Here's the answer. The simple answer: It's just a number conversion. IP: 70.164.18.44= (70*2563)+(164*2562)+(18*2561)+(44*2560) = 1185157676 [ decimal ]= 0x46a4122c [ hexadecimal ]= 010651011054 [ octal ] Most browsers and Internet-related programs will accept IP addresses in any of these formats: decimal, hex, octal, and our standard dotted decimal! Try these out! Thanks to James Reprogle for finding these beauties! You can even mix it up! Why doesn't binary work? http://0b1000110101001000001001000101100/~beckman/ip/answer/There IS a notation for binary: 0b. So 0b1101 should work, right? Nope. Most web browsers are written in C, and C does NOT support that notation. So browser believes that if it doesn't start with a zero, it is a decimal number. Hexadecimal numbers start with 0x, and octal numbers start with 0. So your browser thinks that the IP you are giving it is either in decimal (1 blah blah blah) or octal (0 blah blah blah). Unless you use a PERL based browser; then it should understand the 0b0101 notation. (Thanks Ryan Cruse!) If you have access to a unix machine, do a man on inet_addr() [man inet_addr]. This function takes an address from the dotted decimal and converts it to the decimal notation!!! From the man pages: gcc [ flag ... ] file ... -lxnet [ library ... ] #include in_addr_t inet_addr(const char *cp); The inet_addr() function converts the string pointed to by cp, in the Internet standard dot notation, to an integer value suitable for use as an Internet address. I tested this using the below C program -- it takes the dotted notation and converts it to decimal. If it is decimal already, it just returns that decimal. NOTE: Compile with this line: gcc -o test test.c -lxnet ```#include main(int argc, char **argv) { if (argc <= 1) { printf("usage: %s [ octal | hex | IPaddr ]\n",argv[0]) && exit(1); } printf("%u\n", inet_addr(argv[1])); } ``` Usage: Run this program with any number as the first argument. Then there is a function called inet_ntoa() that translates the decimal back to the IP dotted notation! From the man pages: gcc [ flag ... ] file ... -lxnet [ library ... ] #include char *inet_ntoa(struct in_addr in); The inet_ntoa() function converts the Internet host address specified by in to a string in the Internet standard dot notation. And I took a look at code from telnet (the ever standard program), and what do you know! (hostp is the command line variable for the host): ``` /* * For setup phase treat the relay host as the target host. */ real_host = hostp; /*** hostp = xxx.xxx.xxx.xxx ***/ hostp = itelnet_host; temp = inet_addr(hostp); /*** temp is now a decimal *** equivalent of IP addr! ***/ /* If temp is an IP address */ if (temp != (unsigned long) -1) { sin.sin_addr.s_addr = temp; sin.sin_family = AF_INET; (void) strcpy(_hostname, hostp); hostname = _hostname; } else { /* If temp is equal to 4294967295 (an unsigned long representation of -1, which is what you get if you pass inet_addr() letters, such as a hostname), do a DNS lookup using gethostbyname() */ ``` Here is the first line we see after telnet has processed our command line host: ```printf("Trying %s...\n", inet_ntoa(sin.sin_addr)); ``` For you C geeks, here is what the sin_addr structure looks like: ```struct in_addr { union { struct { uchar_t s_b1, s_b2, s_b3, s_b4; } _S_un_b; struct { ushort_t s_w1, s_w2; } _S_un_w; in_addr_t _S_addr; } _S_un; #define s_addr _S_un._S_addr /* should be used for all code */ #define s_host _S_un._S_un_b.s_b2 /* OBSOLETE: host on imp */ #define s_net _S_un._S_un_b.s_b1 /* OBSOLETE: network */ #define s_imp _S_un._S_un_w.s_w2 /* OBSOLETE: imp */ #define s_impno _S_un._S_un_b.s_b4 /* OBSOLETE: imp # */ #define s_lh _S_un._S_un_b.s_b3 /* OBSOLETE: logical host */ }; ``` So, now you know why the URL http://3508506659/~beckman/ip/ works!!! Go tell all your friends. But don't tell them the secret entry door! I will have to KILL you! Thanks for watching! I'll try and find more cool stuff to show you as the days go on. Suggestions? Mail me! -Peter IPv6 From RFC 2133...Thanks to Elmer Kuehn for pointing out this RFC. ```6.5. Address Conversion Functions The two functions inet_addr() and inet_ntoa() convert an IPv4 address between binary and text form. IPv6 applications need similar functions. The following two functions convert both IPv6 and IPv4 addresses: #include #include int inet_pton(int af, const char *src, void *dst); const char *inet_ntop(int af, const void *src, char *dst, size_t size); The inet_pton() function converts an address in its standard text presentation form into its numeric binary form. The af argument specifies the family of the address. Currently the AF_INET and AF_INET6 address families are supported. The src argument points to the string being passed in. The dst argument points to a buffer into which the function stores the numeric address. The address is returned in network byte order. Inet_pton() returns 1 if the conversion succeeds, 0 if the input is not a valid IPv4 dotteddecimal string or a valid IPv6 address string, or -1 with errno set to EAFNOSUPPORT if the af argument is unknown. The calling application must ensure that the buffer referred to by dst is large enough to hold the numeric address (e.g., 4 bytes for AF_INET or 16 bytes for AF_INET6). If the af argument is AF_INET, the function accepts a string in the standard IPv4 dotted-decimal form: ddd.ddd.ddd.ddd where ddd is a one to three digit decimal number between 0 and 255. Note that many implementations of the existing inet_addr() and inet_aton() functions accept nonstandard input: octal numbers, hexadecimal numbers, and fewer than four numbers. inet_pton() does not accept these formats. If the af argument is AF_INET6, then the function accepts a string in one of the standard IPv6 text forms defined in Section 2.2 of the addressing architecture specification [2]. The inet_ntop() function converts a numeric address into a text string suitable for presentation. The af argument specifies the family of the address. This can be AF_INET or AF_INET6. The src argument points to a buffer holding an IPv4 address if the af argument is AF_INET, or an IPv6 address if the af argument is AF_INET6. The dst argument points to a buffer where the function will store the resulting text string. The size argument specifies the size of this buffer. The application must specify a non-NULL dst argument. For IPv6 addresses, the buffer must be at least 46-octets. For IPv4 addresses, the buffer must be at least 16-octets. In order to allow applications to easily declare buffers of the proper size to store IPv4 and IPv6 addresses in string form, the following two constants are defined in : #define INET_ADDRSTRLEN 16 #define INET6_ADDRSTRLEN 46 The inet_ntop() function returns a pointer to the buffer containing the text string if the conversion succeeds, and NULL otherwise. Upon failure, errno is set to EAFNOSUPPORT if the af argument is invalid or ENOSPC if the size of the result buffer is inadequate. ```

home | contact | resume | store | aup
Copywright [sic] ©1996-2008 by Peter Beckman, AngryOx Industries