515

I want to store the data returned by $_SERVER["REMOTE_ADDR"] in PHP into a DB field, pretty simple task, really. The problem is that I can't find any proper information about the maximum length of the textual representation of an IPv6 address, which is what a webserver provides through $_SERVER["REMOTE_ADDR"].

I'm not interested in converting the textual representation into the 128 bits the address is usually encoded in, I just want to know how many characters maximum are needed to store any IPv6 address returned by $_SERVER["REMOTE_ADDR"].

Mark Amery
  • 127,031
  • 74
  • 384
  • 431
Gilles
  • 6,907
  • 3
  • 20
  • 24

6 Answers6

719

45 characters.

You might expect an address to be

0000:0000:0000:0000:0000:0000:0000:0000

8 * 4 + 7 = 39

8 groups of 4 digits with 7 : between them.

But if you have an IPv4-mapped IPv6 address, the last two groups can be written in base 10 separated by ., eg. [::ffff:192.168.100.228]. Written out fully:

0000:0000:0000:0000:0000:ffff:192.168.100.228

(6 * 4 + 5) + 1 + (4 * 3 + 3) = 29 + 1 + 15 = 45

Note, this is an input/display convention - it's still a 128 bit address and for storage it would probably be best to standardise on the raw colon separated format, i.e. [0000:0000:0000:0000:0000:ffff:c0a8:64e4] for the address above.

Community
  • 1
  • 1
Matthew Scharley
  • 121,977
  • 51
  • 194
  • 218
  • 272
    Header files define INET6_ADDRSTRLEN to be 46, which fits with 45 chars plus a trailing null. – wisnij Jan 22 '10 at 16:33
  • 8
    Worth noting that the IPv6 address might also contain the scope zone http://stackoverflow.com/questions/5746082/ipv6-link-local-address-format, e.g. you get that from RemoteEndpointMessageProperty.Address – Rory Jun 18 '12 at 10:26
  • aren't ipv4 adresses written like ::ffff:127.0.0.1? – graywolf Sep 10 '12 at 14:17
  • @Paladin: That's the shorthand version I believe, yes. They still expand out to full addresses with zeros as above though which means you need to be able to account for that as well. – Matthew Scharley Sep 10 '12 at 23:03
  • @MatthewScharley well... you don't need to account for that.. you can just put it into db like that.. so you can use 39 chars instead of 45 chars. – graywolf Sep 11 '12 at 08:26
  • I have recently seen some IP4 addresses with double dots, like 183.60..244.37 from some malicious probes. So I think making it 50 would be better than 45 to be able to track bad IPs. – Elliptical view Feb 09 '14 at 03:16
  • 1
    does this take into account of percentage sign in ipv6 address? Refer - https://superuser.com/questions/99746/why-is-there-a-percent-sign-in-the-ipv6-address – Gaurav Dec 13 '18 at 10:18
  • @Ellipticalview No matter how large you make the buffer a malicious actor can always come up with a longer malformed string. It makes more sense to make the buffer large enough to hold the longest valid value and deal with bad input in other ways. – kasperd Feb 06 '19 at 09:29
  • @kasperd, Good point. I guess I was looking at a special use case: size needed to block malicious ips, and you're right that size could grow more. I needed a way to record and block a list of bad actors. – Elliptical view Feb 06 '19 at 18:13
  • @Ellipticalview If you log client IP addresses you are supposed to use trusted code on your own end to do the conversion from wire format to textual representation. In that case it isn't possible for a malicious actor to cause a malformed IP address to show up in your log. It's still sensible to validate input to guard against too long strings, but at that point you are defending against your own bugs not a malicious actor. – kasperd Feb 10 '19 at 13:30
111

On Linux, see constant INET6_ADDRSTRLEN (include <arpa/inet.h>, see man inet_ntop). On my system (header "in.h"):

#define INET6_ADDRSTRLEN 46

The last character is for terminating NULL, as I belive, so the max length is 45, as other answers.

Yury
  • 2,792
  • 2
  • 23
  • 24
14

Answered my own question:

IPv6 addresses are normally written as eight groups of four hexadecimal digits, where each group is separated by a colon (:).

So that's 39 characters max.

Gilles
  • 6,907
  • 3
  • 20
  • 24
  • 13
    However there's apparently a caveat, see http://stackoverflow.com/a/7477384/3787376 ("Max length for client ip address") - Quote: "For IPv4 mapped IPv6 addresses, the string can be longer than 39 characters.". It says that an "IPv4-mapped IPv6" is 45 characters and is in the format "NNNN:NNNN:NNNN:NNNN:NNNN:NNNN:192.168.158.190". The maximum should therefore be 45 characters. The answer at http://stackoverflow.com/a/166157/3787376 (this question) also seems to demonstrate this point. – Edward Apr 17 '16 at 12:26
11

As indicated a standard ipv6 address is at most 45 chars, but an ipv6 address can also include an ending % followed by a "scope" or "zone" string, which has no fixed length but is generally a small positive integer or a network interface name, so in reality it can be bigger than 45 characters. Network interface names are typically "eth0", "eth1", "wlan0", so choosing 50 as the limit is likely good enough. The max interface name length in linux is 15 chars, so choosing 60 bytes will cover unusually long interface names on linux.

Sean F
  • 3,868
  • 14
  • 25
  • 5
    True, but this is only link-local addresses, and you aren't going to see any of those once your website is running on the Internet (and hopefully not even while developing it). – Michael Hampton Mar 05 '17 at 19:36
  • This answer deserves more attention. It's best to add 5 more characters than to debug such a weird issue for an hour, just to find out such exception. So, for people who want to know the true max amount of characters, this answer is the best of all. – Akito Aug 10 '21 at 11:20
  • Network interface naming conventions state that names cannot exceed more than 15 characters. Might as well add 45 + 1 (terminating null character) + 15 = 61 characters. Pad it by 3 more characters (for struct byte alignment) and we get 64 characters. – tom_mai78101 Apr 01 '22 at 13:38
7

I think @Deepak answer in this link is more close to correct answer. Max length for client ip address. So correct size is 45 not 39. Sometimes we try to scrounge in fields size but it seems to better if we prepare enough storage size.

Community
  • 1
  • 1
QMaster
  • 3,518
  • 3
  • 40
  • 55
2

Watch out for certain headers such as HTTP_X_FORWARDED_FOR that appear to contain a single IP address. They may actually contain multiple addresses (a chain of proxies I assume).

They will appear to be comma delimited - and can be a lot longer than 45 characters total - so check before storing in DB.

Simon_Weaver
  • 130,769
  • 75
  • 612
  • 659
  • 4
    A slightly conflicted -1 (conflicted because I've fallen into this trap before, and I guess this answer contains info relevant to some people who will be arriving on this page) because nonetheless this clearly isn't an answer to the question asked. It would probably be better as a comment on the question. – Mark Amery Apr 11 '17 at 21:16