Erlang get string from UDP packet - erlang

I have this udp packet:
P = <<83,65,77,80,188,64,172,85,30,144,105,0,0,0,50,0,7,0,0,0,115,97,109,112,45,114,112,11,0,0,0,149,78,87,149,82,80,149,118,50,46,50,11,0,0,0,83,97,110,32,65,110,100,114,101,97,115>>
14-15 byte is the players var (Byte width - 2)
15-18 byte of it is the length of the server hostname (Byte width - 4)
19 + strlen is the hostname of server (Byte width - strlen)
I get players var so:
<<_:11/bytes, Players:16/integer-big, Max:16/integer-big, _/binary>> = P.
It's 50.
How can I get the hostname?

You can improve the expression to obtain the correct values. Note that server length, as you put it, is 32 bits, and, by the look of it, it seems that it is little endian, not big endian (note how the name is 7 bytes, in this case "samp-rp", and the coding of these bytes is <<7,0,0,0>>, which indicates little endian (maybe your players are also little endian). Also, your numbers seem a little bit off. The expression would then be:
<<_:14/bytes, Players:16/integer-little, HNameLength:32/integer-little, HostNameBinary:HNameLength/binary, _/binary>> = P.
Then, the host name can be converted to a string from the binary with binary_to_list:
HostName = binary_to_list(HostNameBinary).

Related

How does only numbers in URL resolve to a domain?

I've been seeing some examples such as http://38263628 that resolves to a legitimate website https://example.com
When doing dig or nslookup on 38263628, it returns me NXDOMAIN.
How does the redirection or resolution work?
For data protection reasons, I can't give the actual numbers and domain it resolves to.
Thanks!
We usually write IP addresses as four dot-separated numbers like 12.34.56.78 but the address is just a number and it can be written in other ways. For example, 12.34.56.78 can also be written as 12.34.14414 or 12.2242638 or 203569230 or 0xc22384e or 0xc.0x22.0x38.0x4e.
The four-dot-separated form is effectively a base-256 representation of the number, so to convert from a single large number N into the four-dot-separated form A.B.C.D you would calculate these four values:
A = N / 256 / 256 / 256
B = N / 256 / 256 % 256
C = N / 256 % 256
D = N % 256
So your 38263628 is equivalent to 2.71.219.76
dig and nslookup don't work with plain numbers because they treat their arguments as strings, even when the arguments are known to represent IP addresses. (For instance, man dig says that the -x option requires an address in the four-dot form. That's because dig just wants to treat it as a string that can be split on the dots and rearranged into a in-addr.arpa query.)
However, most commands that convert their arguments into actual IP address numbers will accept any of the number formats. Try it with ping (which will helpfully show the address in four-dot format when it shows its results):
$ ping 203569230
PING 203569230 (12.34.56.78): 56 data bytes
...
That also gives you an easy way to convert any number into four-dot form -- just give the number as an argument to ping and let it do the conversion for you.

Length and size of strings in Elixir / Erlang needs explanation

Can someone explain why s is a string with 4096 chars
iex(9)> s = String.duplicate("x", 4096)
... lots of "x"
iex(10)> String.length(s)
4096
but its memory size are a few 6 words?
iex(11)> :erts_debug.size(s)
6 # WHAT?!
And why s2 is a much shorter string than s
iex(13)> s2 = "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20"
"1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20"
iex(14)> String.length(s)
50
but its size has more 3 words than s?
iex(15)> :erts_debug.size(s2)
9 # WHAT!?
And why does the size of these strings does not match their lengths?
Thanks
First clue why this is showing that values can be found in this question. Quoting size/1 docs:
%% size(Term)
%% Returns the size of Term in actual heap words. Shared subterms are
%% counted once. Example: If A = [a,b], B =[A,A] then size(B) returns 8,
%% while flat_size(B) returns 12.
Second clue can be found in Erlang documentation about bitstrings implementation.
So in the first case the string is too big to fit on heap alone, so it uses refc binaries which are stored on stack and on heap there is only pointer to given binary.
In second case string is shorter than 64 bytes and it uses heap binaries which is just array of bytes stored directly in on the heap, so that gives us 8 bytes per word (64-bit) * 9 = 72 and when we check documentation about exact memory overhead in VM we see that Erlang uses 3..6 words per binary + data, where data can be shared.

Direct Mapped Cache of Blocks Example

So i have this question in my homework assignment that i have struggling a bit with. I looked over my lecture content/notes and have been able to utilize those to answer the questions, however, i am not 100% sure that i did everything correctly. There are two parts (part C and D) in the question that i was not able to figure out even after consulting my notes and online sources. I am not looking for a solution for those two parts by any means, but it would be greatly appreciated if i could get, at least, a nudge in the right direction in how i can go about solving it.
I know this is a rather large question, however, i hope someone could possibly check my answers and tell me if all my work and methods of looking at this problem is correct. As always, thank you for any help :)
Alright, so now that we have the formalities out of the way,
--------------------------Here is the Question:--------------------------
Suppose a small direct-mapped cache of blocks with 32 blocks is constructed. Each cache block stores
eight 32-bit words. The main memory—which is byte addressable1—is 16,384 bytes in size. 32-bit words are stored
word aligned in memory, i.e., at an address that is divisible by 4.
(a) How many 32-bit words can the memory store (in decimal)?
(b) How many address bits would be required to address each byte of memory?
(c) What is the range of memory addresses, in hex? That is, what are the addresses of the first and last bytes of
memory? I'll give you a hint: memory addresses are numbered starting at 0.
(d) What would be the address of the last word in memory?
(e) Using the cache mapping scheme discussed in the Chapter 5 lecture notes, how many and which address bits
would be used to form the block offset?
(f) How many and which memory address bits would be used to form the cache index?
(g) How many and which address bits would be used to form the tag field for each cache block?
(h) To which cache block (in decimal) would memory address 0x2A5C map to?
(i) What would be the block offset (in decimal) for 0x2A5C?
(j) How many other main memory words would map to the same block as 0x2A5C?
(k) When the word at 0x2A5C is moved into a cache block, what are the memory addresses (in hex) of the other
words which will also be moved into this block? Express your answer as a range, e.g., [0x0000, 0x0200].
(l) The first word of a main memory block that is mapped to a cache block will always be at an address that is
divisible by __ (in decimal)?
(m) Including the V and tag bits of each cache block, what would be the total size of the cache (in bytes)
(n) what would be the size allocated for the data bits (in bytes)?
----------------------My answers and work-----------------------------------
a) memory = 16384 bytes. 16384 bytes into bits = 131072 bits. 131072/32 = 4096 32-bit words
b) 2^14 (main memory) * 2^2 (4 bits/word) = 2^16. take log(base2)(2^16) = 16 bits
c) couldnt figure this part out (would appreciate some input (NOT A SOLUTION) on how i can go about looking at this problem
d)could not figure this part out either :(
e)8 words in each cache line. 8 * 4(2^2 bits/word) = 32 bits in each cache line. log(base2)(2^5) = 5 bits used for block offset.
f) # of blocks = 2^5 = 32 blocks. log(base2)(2^5) = 5 bits for cache index
g) tag = 16 - 5 - 5 - 2(word alignment) = 4 bits
h) 0x2A5C
0010 10100 10111 00
tag index offset word aligned bits
maps to cache block index = 10100 = 0x14
i) maps to block offset = 10111 = 0x17
j) 4 tag bits, 5 block offset = 2^9 other main memory words
k) it is a permutation of the block offsets. so it maps the memory addresses with the same tag and cache index bits and block offsets of 0x00 0x01 0x02 0x04 0x08 0x10 0x11 0x12 0x14 0x18 0x1C 0x1E 0x1F
l)divisible by 4
m) 2(V+tag+data) = 2(1+4+2^3*2^5) = 522 bits = 65.25 bytes
n)data bits = 2^5 blocks * 2^3 words per block = 256 bits = 32 bytes
Part C:
If a memory has M bytes, and the memory is byte addressable, the the memory addresses range from 0 to M - 1.
For your question, this means that memory addresses range from 0 to 16383, or in hex 0x0 to 0x3FFF.
Part D:
Words are 4 bytes long. So given your answer to C, the last word is at:
(0x3FFFF - 3) -> 0x3FFC.
You can see that this is correct because the lowest 2 bits of the address are 0, which must be true of any 4 byte aligned address.

How to solve memory address problems

Can anyone explain how to solve these problems step by step
Assume a 2^24 byte memory.
Assume the memory is byte addressable. What is the lowest address and highest address? How many bits are needed for the address?
Assume the memory is word addressable, with a 16 bit word. What is the lowest address and highest address? How many bits are needed for the address?
Assume the memory is word addressable, with a 32 bit word. What is the lowest address and highest address? How many bits are needed for the address?
A byte is 8 bits. If it's byteaddressable, you can't reference an address by anything other than the start of some 8 bits. That is, in a 2^2 byte memory, you have 4 bytes. The lowest address starts at 0 bytes, and the highest address starts at 3 bytes. (0, 1, 2, 3 = 4 bytes total)
If the bytes are contiguous (they are juxtaposed- touching each other rather than spread out) then you can fit all 4 bytes into a 4 byte memory perfectly.
a)
If you have 2^24 bytes then you have 2^(24 + 3) bits because you're doing (2^24 * 2^3) = 2^(24+3). Thus you have 134,217,728 total bits.
The highest address would be one byte before the end, so the address at 2^24 - 1. Note that it's 2^24 - 1 and not 2^27 - 1 because you are addressing it by bytes and not bits. Lowest address would be 0.
Lowest address = 0
Highest address = 2^24 - 1
b)
A word just means a grouping of bytes. A 1-byte word is literally the same thing as a byte, it just implies that the word is some meaningful piece of data, whereas a byte is not necessarily a meaningful piece of data.
A 16-bit word == a 2-byte word because 8 bits are in a byte, thus if you have 2^24 bytes available, you only have a total of 2^23 words.
Lowest address = 0
Highest address = max number of words - 1 = 2^23 - 1.
c)
Same thing as with a 4-byte word instead of 2. Thus:
2^22 bytes available to store words.
Lowest address = 0
Highest address = max number of words - 1 = 2^22 - 1.
Feel free to correct me if you see any errors. Hope I helped.

Erlang decode binary data from packet

I get an UDP packet, like so:
<<83,65,77,80,188,64,171,138,30,120,105,0,0,0,10,0,4,0,0,0,84,101,115,116,15,0,0,0,82,101,122,111,110,101,32,82,111,108,101,80,108,97,121,11,0,0,0,83,97,110,32,65,110,100,114,101,97,115>>
How can I decode packet if I know that I can remove first 11 bytes, and the 12-13 byte contains amount of players online on the server (Byte width is 2), how can I get this amount?
UPD
Maybe I send incorrect packet...
SAMP Query
So, I send:
<<$S,$A,$M,$P,188,64,172,136,7808:16,$i>>
For server 188.64.172.136:7808, and I get
<<83,65,77,80,188,64,172,136,30,128,105,0,0,0,10,0,4,0,0,0,84,101,115,116,15,0,0,0,82,101,122,111,110,101,32,82,111,108,101,80,108,97,121,11,0,0,0,83,97,110,32,65,110,100,114,101,97,115>>
You can use the bit syntax and clever pattern matching to get the result:
<<_:11/bytes, NumberOfPlayers:16/integer-big, _/binary>> = <<83,65,77,80,188,64,171,138,30,120,105,0,0,0,10,0,4,0,0,0,84,101,115,116,15,0,0,0,82,101,122,111,110,101,32,82,111,108,101,80,108,97,121,11,0,0,0,83,97,110,32,65,110,100,114,101,97,115>>,
NumberOfPlayers.
If your packet binary is stored in P, you can do something like (assuming big endian):
<<NumberOfPlayersOnline:16/big>> = binary:part(P,11,2).
The result is in NumberOfPlayers.

Resources