Zaphiel
Zaphiel

Reputation: 293

Extracting Packet Data - Websocket Protocol - Python

I'm having problem on understanding data extracting on websocket protocol.

The problem is, I don't understand the hex code that we use for bitwise and operation for getting right field. (Code in below the table)

Here is the framing table.

  0                   1                   2                   3
  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 +-+-+-+-+-------+-+-------------+-------------------------------+
 |F|R|R|R| opcode|M| Payload len |    Extended payload length    |
 |I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
 |N|V|V|V|       |S|             |   (if payload len==126/127)   |
 | |1|2|3|       |K|             |                               |
 +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
 |     Extended payload length continued, if payload len == 127  |
 + - - - - - - - - - - - - - - - +-------------------------------+
 |                               |Masking-key, if MASK set to 1  |
 +-------------------------------+-------------------------------+
 | Masking-key (continued)       |          Payload Data         |
 +-------------------------------- - - - - - - - - - - - - - - - +
 :                     Payload Data continued ...                :
 + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
 |                     Payload Data continued ...                |
 +---------------------------------------------------------------+


My code:

import struct
import math

def binary(data):
    if data == 0: return "0"*8
    _data = str(bin(data))[2:]
    return _data.rjust(8 * math.ceil(data / 255),"0")

data = b"\x81\x8c\r\x06y\xe2ni\x17\x8che\r\x8bbhC\xd3"

header, = struct.unpack("!H",data[:2])
data = data[2:]

# HERE #
FIN    = ( header >> 15 ) & 0x01 # <-
RSV1   = ( header >> 14 ) & 0x01
RSV2   = ( header >> 13 ) & 0x01
RSV3   = ( header >> 12 ) & 0x01
OPCODE = ( header >>  8 ) & 0x0F
MASK   = ( header >>  7 ) & 0x01
LEN    = ( header >>  0 ) & 0x7F

print(binary(OPCODE))

How we know to use that specific hex codes? (0x01, 0x0F, 0x7F) And what is the logic behind it?

Thanks for everyone.

Upvotes: 1

Views: 370

Answers (1)

Andrej Debenjak
Andrej Debenjak

Reputation: 2142

Those specific hex codes are ordinary bit masks. They can be easily determined from the table you provided (RFC 6455 - Base Framing Protocol).

Explanation for OPCODE:

  • position: bits 4, 5, 6, 7
  • length: 4bits

In order to extract the OPCODE, you have to do bit operations. First, you have to do right shift by 8 (since you decided to split the frame into unsigned shorts by using !H). in your code this is done by:

header >>  8

At this point, the four OPCODE bits are at position from bit 12 to 15. However, bits from 8 to 11 still contain unwanted data. Therefor, you have to do bitwise and operation with appropriate mask. In this case, the mask contains 4 (length of OPCODE) left-most bits:

Mask:     0000000000001111b (0x0F)
Value:    00000000xxxxxxxxb
& ---------- BITWISE AND ---------
Result:   000000000000xxxxb

The mask for LEN can be similarly determined. Length is 7 bits, therefore the mask is 01111111b (0x7F in hex).

Upvotes: 1

Related Questions