convert IPv6 to decimal (ip number) - coldfusion

I've been trying to convert all ip addresses (both IPv4 and IPv6) to decimal format (ip number), store those numbers in the database which already contains ip ranges and get country location based on user's IP. Although this can be done easily for IPv4 addresses, I run into a stone wall when it comes to IPv6 ones.
say the fallowing IP should be converted to decimal
2a03:29ff:ffff:ffff:ffff:ffff:ffff:ffff
I tested it through some online services (that convert IPv6 to decimal) simply to check the consistency, namely what my final result should look like.
https://www.ultratools.com/tools/decimalCalc
http://www.ipaddressguide.com/ipv6-to-decimal
both returned the same number - 55844004574745424515003293805316145151
now within my coldfusion code I first removed : from the IP to get hex format and then tried to convert it to decimal with this
<cfset ipv6='2a0329ffffffffffffffffffffffffff'>
<cfoutput>#inputBaseN(ipv6, 16)#</cfoutput>
resulting in error msg
is it possible to achieve this? what do you think about my approach for handling this sort of thing? is there a better way to get country location based on IP? note: do not want to rely on any online service!!

InputBaseN is trying to convert to an Integer, and that value is too big for the maximum Integer value, hence why the error is claiming it is not a valid number.
(The error is actually only thrown for hex values of 8000000000000000 and higher (i.e. 263 or higher, the max for Long) - between 231 and 263-1 the InputBaseN function doesn't tell you it has failed but incorrectly returns zero.)
The solution is to create a BigInteger, which doesn't have a max value, and convert from your base 16 string like so:
BigInt = createObject("java","java.math.BigInteger").init( ipv6 , 16 ).toString()

I think you wont be able to get cf to generate a decimal that large. You need to do it manually as a string.

Related

A Problem in Parsing CNAME with Libpcap: some CNAMEs seems missing TLD

I am writing a DNS reply parser with libpcap and find that some CNAMEs' TLDs seem to be missing from the corresponding DNS packet payload. One example is shown in an example packet's wireshark dissection where wireshark shows the actual CNAME is
prd-push-access-net5-175542503.us-east-1.elb.amazonaws.com
but I can only find
prd-push-access-net5-175542503.us-east-1.elb.amazonaws
(i.e. no ".com") in the corresponding part of payload. I wonder how could one (and how did wireshark) parse the full CNAME (with ".com") out of this payload?
(Also this CNAME seems malformed since per RFC1035, a QNAME in question section should "terminates with the zero length octet for the null label of the root" and I guess the same applies for CNAME?)
DNS packets use name compression, see https://www.rfc-editor.org/rfc/rfc1035 section 4.1.4
In many places (where names appear), each label can be represented by a pointer to a former place in the packet where it appears already, instead of the string.
In your example, we can clearly see com in myfoscam.com earlier in the packet.
So with the content (using only the end because it is tedious to extract data from an image, you should have copied things as text) 03656c6209616d617a6f6e617773c019c02e00 we have to analyze it like this:
03: the following is a string of length 3
656c62: this is the string elb, lenght 3 as advertised
09: the following is a string of length 9
616d617a6f6e617773: this is the string amazonaws
c0 : this has the first two bits as 1 (since it is value 192, so more or equal to 128+64), which means it is a part of a two bytes pointer. Hence c019 is a pointer here at offset 25 in decimal (19 in hexadecimal) into the packet.
So if you start from the whole packet, and switch to offset 25, you should find the sequence 03636f6d which is com (with the prefix of a length of 3).
Or maybe something else, because you have another pointer after in fact: c02e, so this is for offset 46 in the message. Or that part is for something else completely, it really depends on what is pointed by previous pointer, if it finishes with a null label or not (if it is 03636f6d00 at offset 25 or not). See example in the RFC (and/or provide all the packet content as text in your question)
Then it ends with 00 the null label, which means the root (the hidden . at the end of any name).

Can the pub / sub message ID be held as a number?

Pub/sub guarantes that messageId is always unique number. Therefore, i use this id as deviceId and i hold this value on bigquery table. Google documents say this value string. But, messageId return 15-digit number according to my experiments. Should I keep this value as number on bigquery? Does it cause any trouble?
Pubsub Message Format
The issue is the max length of an Integer (10) and not the fact it contains only numeric values.
This is why you should keep the value as String and not as an Integer as defined in the documentation
Pub/sub guarantes that messageId is always unique per topic - not that it is a number (ref)
The data type as stated in the docs is a String, so it can contain any unicode character.
So, as others have said, although it is a 15 digit number now, if at some point in
the future, google generates a non-numeric string, or a number greater than what your low level code can store, then your app will fail.
Google Support Says :
"MessageId consist of the maximum possible digits are 19. As long as an ID hasn't been used before (since they are unique), there can be up to 19 digits, but realistically that amount of digits may not be reached."

Store 32 bit value as C string in most efficient form

I am trying to find the most efficient way to encode 32 bit hashed string values into text strings for transmission/logging in low bandwidth environments. Complex compression can't be used because the hash values need to be contained in human readable text strings when logged and sent between client and host.
Consider the following contrived examples:
given the key/value map
table[0xFE12ABCD] = "models/texture/red.bmp";
table[0x3EF088AD] = "textures/diagnostics/pink.jpg";
and the string formats:
"Loaded asset (0x%08x)"
"Replaced (0x%08x) with (0x%08x)"
they could be printed as:
"Loaded asset models/texture/red.bmp"
"Replaced models/texture/red.bmp with textures/diagnostics/pink.jpg"
Or if the key/value map is known by the client and server:
"Loaded asset (0xFE12ABCD)"
"Replaced (0xFE12ABCD) with (0x3EF088AD)"
The receiver can then scan for the (0xNNNNNNNN) pattern and expand it locally.
This is what I am doing right now but I would like to find a way to represent the 32 bit value more efficiently. A simple step would be to use a better identifying token:
"Loaded asset $FE12ABCD"
"Replaced $1000DEEE with $3EF088AD"
Which already reduces the length of each token - $ is not used anywhere else so it is reasonable.
However, what other options are there to make that 32 bit value even smaller? I can't use an index - it has to be a full 32 bit value because in some cases the generator of the string has the hash and sometimes it has a string it will hash immediately.
A common solution is to use Base-85 coding. You can code four bytes into five Base-85 digits, since 855 > 232. Pick 85 printable characters and assign them to the digit values 0..84. Then do base conversion to go either way. Since there are 94 printable characters in ASCII, it is usually easy to find 85 that are "safe" in whatever constrains your strings to be "readable".

Subtracting Numbers larger than 18 digits in length

Ok this is a tough one or else a stupid one but it has me stumped. I am working with serial numbers in MSSQL and they are stored in the database as nvarchar(50) and to do subtracting calculations on them I use the following query to convert them to the data-type BIGINT and subtract as normal.
SELECT
SUM(
CAST(second_Serial_Nb AS BIGINT)-CAST(Serial_Nb AS BIGINT))
FROM [TEST].[dbo].[Serial_Table]
WHERE ID = '3'
this query works fine for serial numbers up to 18 digits in length, but as soon as I increase there size of the serial numbers to 20 digits in length I get the error that the numbers can not be converted to data-type bigint
Msg 8815, Level 16, State 2, Line 2
Arithmetic overflow error converting expression to data type bigint
Is there a work around using a different number data type like hexi or something. I am also using C++ maybe I could create a function there instead of SQL?
Any comments or suggestions greatly appreciated, Thanks for reading.
BIGINT is just a normal, 64-bit integer. It is not an arbitrary-precision integer.
If you want to store more information, you can either keep it in string form, or use a NUMERIC or DECIMAL type; both solutions are of course much slower than a native, fixed-width integer.

prefix length calculation for ipv6 addresses

I want to calculate the prefix length for Ipv4 and Ipv6 addresses . The subnet mask can be in the form of a string(1 , 32 ,97 etc) or in the dotted format(255.255.0.0) . I want to impose the following conditions.
1)For ipv4 , both the formats should be allowed . But when we cast from the string to an unsigned , the prefix length should not be more than 31
2)For ipv6 only the prefix length is allowed . It should not be more than 127
Although I can do the above calculations pretty easily by passing a sub routine , I have been asked to use boost defined classes and methods for the same .
Can anyone suggest the appropriate boost methods for the above . I've tried to do some searching , but unable to do so.
The paramaters can be the mask in the prefix length string format (16 , 97) or in the dotted format , and maybe the address(string) . The boost methods should be able to determine the prefix length as an unsigned based on the restrictions already mentioned.
Useful boost parts are regex, to analyze what you got, and lexical_cast to turn a string into a number.