Converting decimal number to flag values - lua

I have some constraints like so:
interesting = 0x1
choked = 0x2
remote_interested = 0x4
remote_choked = 0x8
supports_extensions = 0x10
local_connection = 0x20
handshake = 0x40
connecting = 0x80
queued = 0x100
on_parole = 0x200
seed = 0x400
optimistic_unchoke = 0x800
rc4_encrypted = 0x100000
plaintext_encrypted = 0x200000
and the documentation tells me 'The flags attribute tells you in which state the peer is in. It is set to any combination of the enums above' so basically I call the dll and it fills in the structure with a decimal number representing the flag values, a few examples:
2086227
170
2098227
106
How do I from the decimal determine the flags?

In order to determine which flags were set, you need to use the bitwise AND operation (bit32.band() in Lua 5.2). For example:
function hasFlags(int, ...)
local all = bit32.bor(...)
return bit32.band(int, all) == all
end
if hasFlags(2086227, interesting, local_connection) then
-- do something that has interesting and local_connection
end

Related

Displaying the bits values of a number in Wireshark Postdissector

I am writing a wireshark dissector of a custom protocol using LUA.For this custom protocol,there are no underlying TCP port or UDP port hence i have written a postdissector.
I am able to capture the payload from the below layers and convert it into a string.
local io_b = tostring(customprotocol)
After this, io_b has the following data
io_b = 10:10:10:10:01:0f:00:0d:00:00:00:00:01:00:00:00:00:20:0a:00:00
At first I split this string with : as the seperator and copy the elements into an array/table.
datafields = {}
index = 1
for value in string.gmatch(io_b, "[^:]+") do
datafields[index] = value
index = index + 1
end
Then I read each element of the datafield array as a uint8 value and check if a bit is set in that datafield element.How to make sure that each element of the table is uint8?
function lshift(x, by)
return x * 2 ^ by
end
--checks if a bit is set at a position
function IsBitSet( b, pos)
if b ~= nil then
return tostring(bit32.band(tonumber(b),lshift(1,pos)) ~= 0)
else
return "nil"
end
end
Then I want to display the value of each bit in the wireshark.I dont care about the first four bytes. The script displays each bit of the 5th byte(which is the 1st considered byte) correctly but displays all the bits value of the 6th byte and other remaining bytes as "nil".
local data_in_2 = subtree:add(customprotocol,"secondbyte")
data_in_2:add(firstbit,(IsBitSet((datafields[6]),7)))
data_in_2:add(secondbit,(IsBitSet((datafields[6]),6)))
data_in_2:add(thirdbit,(IsBitSet((datafields[6]),5)))
data_in_2:add(fourbit,(IsBitSet((datafields[6]),4)))
data_in_2:add(fivebit,(IsBitSet((datafields[6]),3)))
data_in_2:add(sixbit,(IsBitSet((datafields[6]),2)))
data_in_2:add(sevenbit,(IsBitSet((datafields[6]),1)))
data_in_2:add(eightbit,(IsBitSet((datafields[6]),0)))
What am i doing wrong?
Maybe i am wrong but it seems you can do it simpler with...
io_b = '10:10:10:10:01:0f:00:0d:00:00:00:00:01:00:00:00:00:20:0a:00:00'
-- Now replace all : on the fly with nothing and convert it with #Egor' comment tip
-- Simply by using string method gsub() from within io_b
b_num = tonumber(io_b:gsub('%:', ''), 16)
print(b_num)
-- Output: 537526272
#shakingwindow - I cant comment so i ask here...
Do you mean...
io_b = '10:10:10:10:01:0f:00:0d:00:00:00:00:01:00:00:00:00:20:0a:00:00'
-- Converting HEX to string - Replacing : with ,
io_hex = io_b:gsub('[%x]+', '"%1"'):gsub(':', ',')
-- Converting string to table
io_hex_tab = load('return {' .. io_hex .. '}')()
-- Put out key/value pairs by converting HEX value string to a number on the fly
for key, value in pairs(io_hex_tab) do
print(key, '=', tonumber(value, 16))
end
...that puts out...
1 = 16
2 = 16
3 = 16
4 = 16
5 = 1
6 = 15
7 = 0
8 = 13
9 = 0
10 = 0
11 = 0
12 = 0
13 = 1
14 = 0
15 = 0
16 = 0
17 = 0
18 = 32
19 = 10
20 = 0
21 = 0
...?

Handle special characters in lua file path (umlauts)

I have a small lua function to check if a file exists
function file_exists( filePath )
local handler = io.open( filePath )
if handler then
io.close( handler )
return true
end
return false
end
However, this will always return false when the file path contains special chars such as German umlauts (äöü). Is there any way around this?
Thanks a lot!
utf8_to_cp1252 = (
function(cp1252_description)
local unicode_to_1252 = {}
for code, unicode in cp1252_description:gmatch'\n0x(%x%x)%s+0x(%x+)' do
unicode_to_1252[tonumber(unicode, 16)] = tonumber(code, 16)
end
local undefined = ('?'):byte()
return
function (utf8str)
local pos, result = 1, {}
while pos <= #utf8str do
local code, size = utf8str:byte(pos, pos), 1
if code >= 0xC0 and code < 0xFE then
local mask = 64
code = code - 128
repeat
local next_byte = utf8str:byte(pos+size, pos+size) or 0
if next_byte >= 0x80 and next_byte < 0xC0 then
code, size = (code - mask - 2) * 64 + next_byte, size+1
else
code, size = utf8str:byte(pos, pos), 1
end
mask = mask * 32
until code < mask
end
pos = pos + size
table.insert(result,
string.char(unicode_to_1252[code] or undefined))
end
return table.concat(result)
end
end
)[[
download
http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1252.TXT
and insert the whole text here:
#
# Name: cp1252 to Unicode table
# Unicode version: 2.0
# Table version: 2.01
..................................
0xFD 0x00FD #LATIN SMALL LETTER Y WITH ACUTE
0xFE 0x00FE #LATIN SMALL LETTER THORN
0xFF 0x00FF #LATIN SMALL LETTER Y WITH DIAERESIS
]]
Usage:
cp1252_filename = utf8_to_cp1252(your_utf8_filename)
Now you can use cp1252_filename to invoke io.open(), os.rename(), os.execute() and other functions from standard Lua library.
Lua and its tiny standard library is platform neutral and is not aware of correct Windows functions to read full unicode names. You can use winapi module to get some Windows-specific functions for this task. Note that it requires short name generation to be enabled on target disk.
local handler = io.open( winapi.short_path(filePath) )
if handler then
-- etc
end
It can also be easily installed through LuaRocks: luarocks install winapi.

SET A, 0x1E vs SET A, 0x1F

This is my first attempt at dpcu, I'm checking machine code generated by dpcu-16 assembly
I am using this emulator : http://dcpu.ru/
I am trying to compare code generated by
SET A, 0x1E
SET A, 0x1F
code generated is as follow :
fc01
7c01 001f
I don't get why operand size changes between those two values
That emulator appears to be using the next version of the DCPU-16 spec, which specifies that the same-word literal value for a permits values from 0xFFFF (-1) to 0x1E (30). This means that to get any literal value outside this range the assembler has to use the next-word literal syntax, which makes the operand one byte bigger.
0x1F (dec:31) is no longer a short literal (values -1 to 30), so it has to be read as a "next word" argument.
The opcodes are thus:
SET A, 0x1E
SET = 00001
A = 00000
1E = 111111
op = 1111110000000001 = fc01
SET A, 0x1F
SET = 00001
A = 00000
NW = 011111
op = 0111110000000001 = 7c01 + 001f

PGMidi changing pitch sendBytes example

I'm trying the second day to send a midi signal. I'm using following code:
int pitchValue = 8191 //or -8192;
int msb = ?;
int lsb = ?;
UInt8 midiData[] = { 0xe0, msb, lsb};
[midi sendBytes:midiData size:sizeof(midiData)];
I don't understand how to calculate msb and lsb. I tried pitchValue << 8. But it's working incorrect, When I'm looking to events using midi tool I see min -8192 and +8064 max. I want to get -8192 and +8191.
Sorry if question is simple.
Pitch bend data is offset to avoid any sign bit concerns. The maximum negative deviation is sent as a value of zero, not -8192, so you have to compensate for that, something like this Python code:
def EncodePitchBend(value):
''' return a 2-tuple containing (msb, lsb) '''
if (value < -8192) or (value > 8191):
raise ValueError
value += 8192
return (((value >> 7) & 0x7F), (value & 0x7f))
Since MIDI data bytes are limited to 7 bits, you need to split pitchValue into two 7-bit values:
int msb = (pitchValue + 8192) >> 7 & 0x7F;
int lsb = (pitchValue + 8192) & 0x7F;
Edit: as #bgporter pointed out, pitch wheel values are offset by 8192 so that "zero" (i.e. the center position) is at 8192 (0x2000) so I edited my answer to offset pitchValue by 8192.

How do I create an FCS for PPP packets?

I am trying to create a software simulation on an Ubuntu GNU/Linux machine which will work like PPPoE. I would like this simulator to take outgoing packets, strip off the ethernet header, insert the PPP flags (7E, FF, 03, 00, and 21) and place the IP layer information in the PPP packet. I am having trouble with the FCS that goes after the data. From what I can tell, the cell modem I am using has a 2 byte FCS using the CRC16-CCITT method. I have found several pieces of software that will calculate this checksum, but none of them produce what is coming out the serial line (I have a serial line "sniffer" that shows me everything the modem is being sent).
I have been looking into the source of pppd and the linux kernel itself, and I can see that both of them have a method of adding an FCS to the data. It seems quite difficult to implement, as I have no experience in kernel hacking. Can someone come up with a simple way (preferably in Python) of calculating an FCS that matches the one that the kernel produces?
Thanks.
P.S. If anyone wants, I can add a sample of the data output I am getting to the serial modem.
Used simple python library crcmod.
import crcmod #pip3 install crcmod
fcsData = "A0 19 03 61 DC"
fcsData=''.join(fcsData.split(' '))
print(fcsData)
crc16 = crcmod.mkCrcFun(0x11021, rev=True,initCrc=0x0000, xorOut=0xFFFF)
print(hex(crc16(bytes.fromhex(fcsData))))
fcs=hex(crc16(bytes.fromhex(fcsData)))
I recently did something like this while testing code to kill a ppp connection ..
This worked for me:
# RFC 1662 Appendix C
def mkfcstab():
P = 0x8408
def valiter():
for b in range(256):
v = b
i = 8
while i:
v = (v >> 1) ^ P if v & 1 else v >> 1
i -= 1
yield v & 0xFFFF
return tuple(valiter())
fcstab = mkfcstab()
PPPINITFCS16 = 0xffff # Initial FCS value
PPPGOODFCS16 = 0xf0b8 # Good final FCS value
def pppfcs16(fcs, bytelist):
for b in bytelist:
fcs = (fcs >> 8) ^ fcstab[(fcs ^ b) & 0xff]
return fcs
To get the value:
fcs = pppfcs16(PPPINITFCS16, (ord(c) for c in frame)) ^ 0xFFFF
and swap the bytes (I used chr((fcs & 0xFF00) >> 8), chr(fcs & 0x00FF))
Got this from mbed.org PPP-Blinky:
// http://www.sunshine2k.de/coding/javascript/crc/crc_js.html - Correctly calculates
// the 16-bit FCS (crc) on our frames (Choose CRC16_CCITT_FALSE)
int crc;
void crcReset()
{
crc=0xffff; // crc restart
}
void crcDo(int x) // cumulative crc
{
for (int i=0; i<8; i++) {
crc=((crc&1)^(x&1))?(crc>>1)^0x8408:crc>>1; // crc calculator
x>>=1;
}
}
int crcBuf(char * buf, int size) // crc on an entire block of memory
{
crcReset();
for(int i=0; i<size; i++)crcDo(*buf++);
return crc;
}

Resources