Scapy custom DHCP Option82 - scapy

I'm trying to create a custom DHCP request with Option82 included but I'm not able to set the length of the suboption:
ethernet= Ether(dst='ff:ff:ff:ff:ff:ff',src=get_if_hwaddr("eth1"), type=0x800)
ip= IP(src='0.0.0.0', dst='255.255.255.255')
udp = UDP(sport=68, dport=67)
bootp = BOOTP(chaddr =hw, ciaddr ='0.0.0.0', xid =0x01020304, flags= 1)
dhcp = DHCP(options=[("message-type","discover")])/DHCP(options=[("relay_agent_Information", "TEST"), "end"])
packet = ethernet / ip / udp / bootp / dhcp
No matter what I do, option82 always has the wrong length. Does any body know how to set the address header of the suboption?
Thanks in advance!

DHCP Option 82 isn't a simple string like "TEST". You may find a very nice explanation of the option in RFC3046 DHCP Option 82 is a "container" option for specific agent-supplied sub-options. The format of the Relay Agent Information option is:
Code Len Agent Information Field
+------+------+------+------+------+------+--...-+------+
| 82 | N | i1 | i2 | i3 | i4 | | iN |
+------+------+------+------+------+------+--...-+------+
The length N gives the total number of octets in the Agent Information Field. The Agent Information field consists of a sequence of SubOpt/Length/Value tuples for each sub-option, encoded in the following manner:
SubOpt Len Sub-option Value
+------+------+------+------+------+------+--...-+------+
| 1 | N | s1 | s2 | s3 | s4 | | sN |
+------+------+------+------+------+------+--...-+------+
SubOpt Len Sub-option Value
+------+------+------+------+------+------+--...-+------+
| 2 | N | i1 | i2 | i3 | i4 | | iN |
+------+------+------+------+------+------+--...-+------+
Scapy doesn't work with suboptions so you need to supply the complete Option 82 field in hexadecimal format, including field length etc. As an example, consider the following modification to your code that yields the correct length of Option 82:
...
option82 = "\x01\x01\x05\x02\x06\x11\x22\x34\x44\x55\x66"
dhcp = DHCP(options=[("message-type","discover")])/DHCP(options=[("relay_agent_Information", option82), "end"])
...
In this particular case DHCP Option 82 is \x01\x01\x05\x02\x06\x11\x22\x34\x44\x55\x66. Here the Circuit ID = 05 andRemote ID = 112233445566. The corresponding Wireshark dump is below:

Related

Excel - Check if Value of Two Columns are new in a List and Passing a new ID to them

Good Morning,
I'm trying to formulate something in Excel that allow us to check if the value of two columns are new in a list, and if so, assign a new ID for them. If it's not, let it "Blank" or Assign the same ID that have been assigned before(Either way would work for me).
I'm trying to use something with Count.if, but it doesn't fit. As i'm thinking about this for some time, i decided to look for help.
What i want to do is a formula that solves the "Formula" Columns below:
Space|Name|*Formula*
1 | AB | 1
1 | AB | 1
1 | AB | 1
1 | CA | 2
2 | DD | 3
2 | EE | 4
2 | EE | 4
3 | SS | 5
3 | SS | 5
1 | ZZ | 6
1 | AB | 1
Sequential Numbering of Groups of Data
In cell C2 use the following array formula (Ctrl,Shift+Enter):
=IF(COUNTIFS(A$2:A2,A2,B$2:B2,B2)=1,MAX(C$1:C1)+1,
INDEX(C$1:C1,MATCH(1,(A$1:A1=A2)*(B$1:B1=B2),0)))
Then copy C2 and pastedown from C3 to the last cell.
If you're satisfied with just numbering each first occurrence then use the following formula:
=IF(COUNTIFS(A$2:A2,A2,B$2:B2,B2)=1,MAX(C$1:C1)+1,"")
Both solutions use the headers i.e. the headers must not be numbers.
If you don't mind non-sequential numbering, you can just return the index of the first match found as your identifier:
Copy into C2, then fill down as necessary. The match row stop may need alteration based on how much data you have
=MATCH(A2&"#"&B2, A$2:A$100&"#"&B$2:B$100,0)
Or as an array formula (only need to place in C2);
=MATCH(A2:A11&"#"&B2:B11, A2:A11&"#"&B2:B11,0)

How do ZeroMQ HEARTBEAT sockopts() settings work?

I'm using python's pyzmq==22.2.1 which should support ZeroMQ 4.2.0 (according to the API)
I'm trying to make use of the heartbeat socket options (ZMQ_HEARTBEAT_IVL, ZMQ_HEARTBEAT_TIMEOUT and ZMQ_HEARTBEAT_TTL). However, when I set these socket options, I am not receiving the expected TimeoutException or any exception on my socket. It just seems to sit there doing nothing.
What is the expected behaviour after setting these socket options ?
On the server side, how does the server detect the client has timeout and missed a heartbeat and vice versa for the client (is there an exception or something that's supposed to be thrown or something ?).
I've setup a simple router-dealer echo example below:
# Server Code:
import zmq
c = zmq.Context()
s = c.socket(zmq.ROUTER)
s.setsockopt(zmq.HEARTBEAT_IVL, 1000)
s.setsockopt(zmq.HEARTBEAT_TIMEOUT, 5000)
s.setsockopt(zmq.HEARTBEAT_TTL, 5000)
s.bind('tcp://127.0.0.1:5555')
while True:
id, data = s.recv_multipart()
s.send_multipart([id, data], zmq.NOBLOCK)
# Client Code
import zmq
import time
c = zmq.Context()
s = c.socket(zmq.DEALER)
s.HEARTBEAT_IVL = 1000
s.HEARTBEAT_TIMEOUT = 5000
s.connect('tcp://127.0.0.1:5555')
i = 0
while True:
s.send(str(i).encode())
print(s.recv())
i += 1
time.sleep(1)
Q : What is the expected behaviour after setting these socket options ?
A :well,there are two-fold effect of the said settings. One, that actually works for your setup goals ( i.e. going & sending (most probably ZMTP/3.1) ZMTP_PING connection-oriented service-sublayer "ZMTP/3.1-service-packets" and reciprocally, not sure, but most often, adequately formed "ZMTP/{3.1|2.x|1.0}-service-packets" (hopefully delivered) back. These "service-packets" are visible on the wire-line (if present - an inproc://-transport-class and vmci://-transport-class too have no actual wire a typical user can hook-on and sniff-traffic in, but some kind of pointer-acrobatics used for RAM-mapping), so a protocol-analyser will "see" them id decodes like this:
a local-initiator
MAY send:
+------+----+
| %xNN | 24 |
+------+----+
0 1
flags size
+------+---+---+---+---+
| %xNN | P | I | N | G |
+------+---+---+---+---+
2 3 4 5 6
ZMTP/3.1-Command name "PING"
+---+---+
| |
+---+---+
7 8 ping-ttl 2B
MAY be zero
MAY be ttl stored as [0:15], being a 16-bit TTL in 1/100 [s] ~ max 6553 [s]
ttl provides a strong hint
to the other peer to disconnect
if no further traffic is received after that time.
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | 0 |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
ping-context (max 16B)
MAY be zero
MAY be context-specific context-payload, not more than 16B
a remote-peer
SHALL respond:
+------+----+
| %xNN | 22 |
+------+----+
0 1
flags size
+------+---+---+---+---+
| %xNN | P | O | N | G |
+------+---+---+---+---+
2 3 4 5 6
ZMTP/3.1-Command name "PONG"
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | 0 |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
ping-context (echoed as obtained from PING)
ZMTP/3.1 v/s ZMTP/3.0 v/s ZMTP/2.x v/s ZMTP/1.0 differences and details get solved during version-negotiation phase, once the sublayer of connection-setup services performs all low-level needed handshaking (re)negotiations among peers trying to agree on version-, auth- & security- related principles
The second effect of these ( under-the-hood of the Context()-engine instance performed negotiations ) is that you shall never see any direct interaction with ZeroMQ-(abstract)-Message-Transport-Protocol ( ZMTP ) defined service-setup-&-maintenance-processes.
We simply enjoy the (above ZMTP generated) exposed API-calls to setup, configure and harness "our" user-level operated Signalling / Messaging infrastructure meta-plane, that is based on all the know-how "hidden" under-the-hood (and should remain so - sure, unless one decides to roll up sleeves and help develop the ZeroMQ system towards its next generation)
Q : ( is there an exception or something that's supposed to be thrown or something ? )
A :
This is why all above had to have been told first, as the due reasoning, for which there ought be a fair & honest answer no to your second question.

Aligning serial data using the Read trait in Rust

So I have some data going through a serial port at regular intervals. Eight bytes are sent every 2 seconds.
I would read this data. Because transmission is constant, I can't just start reading at any moment. I need to align the data. So clearly, the way to do this is to send a header or some sort of separator bytes.
With the Read trait, I can read a certain number of bytes into my buffer. It might look like this:
let mut serial_buf: Vec<u8> = vec![0; 16];
loop {
match port.read(serial_buf.as_mut_slice()) {
Ok(t) => print_data(&serial_buf[..t]),
Err(ref e) if e.kind() == std::io::ErrorKind::TimedOut => (),
Err(e) => eprintln!("{:?}", e),
}
}
But the output I get will look something like this without alignment (with bytes 'abcd' being sent every 2 seconds):
abcd
a
bcd
abc
d
a
bcd
ab
cd
So what's the most practical way of reading and discarding until an alignment bit is found, then making sure that all subsequent reads are aligned?
Thanks,
You need a way to recognize a packet. For this you need to define your protocol.
I guess you want to keep it really simple and low-overhead, so I'll give an example.
+----------+-------+------+------+------+------+------+------+------+------+-----------+
| Byte | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
+==========+=======+======+======+======+======+======+======+======+======+===========+
| Function | Start | Data | Data | Data | Data | Data | Data | Data | Data | CheckSum |
+----------+-------+------+------+------+------+------+------+------+------+-----------+
| Value | 0 | X | X | X | X | X | X | X | X | XOR 0..=8 |
+----------+-------+------+------+------+------+------+------+------+------+-----------+
So what do we have here?
Our message always starts with a 0. This way we can recognize the start of the message. The data can still contain 0's because we don't rely on it, it just makes our job easier.
(This could be any value, really, but 0 will do the job just fine)
After our start byte, we get our data. This is just the ABCD you used in your example.
Our last byte is a very simple checksum. We simple XOR together all the bytes.
How does this all work then?
Collect some data.
If data < 10 bytes, go to 1
If data[0] != 0 (our start byte), then remove the first byte from our buffer. Go to 2.
XOR together all bytes to get our calculated checksum.
If data[9] != calculated_checksum, then remove the first byte from our buffer. Go to 2.
(We did detect a start byte, but the checksum is incorrect. Therefore we know that the current data is not a packet)
We've got the packet! (Probably*) Read bytes 1..=8 for processing. Then remove the first 10 bytes from the buffer. Go to 2.
That's it!
But there's a lot of things to improve for performance and reliability.
Better start header that supports dynamic lengths and multiple message types.
Better checksum. XOR is not very good for reliability. A CRC is one of the best.
Buffer management. You could use a cyclical buffer so you don't have to remove any bytes.

Two RFID readers show different identifiers

I have used two RFID readers (different vendors), which provide two different identifiers for the very same RFID tag:
Reader A shows 5BFA0746 (decimal 1543112518)
Reader B shows 4607FA5B (decimal 1174927963)
Can you explain why?
There are no similarities with the last bytes nor prefixes.
I'm not sure that I completely understand your question, but the two values are identical except for their byte-order. Hence, both readers do read the same value (possibly an ISO/IEC 14443-3 UID/anti-collsion identifier?). They just present them in reversed byte order:
+--------+--------+--------+--------+
Reader A: | Byte 0 | Byte 1 | Byte 2 | Byte 3 |
| 5B | FA | 07 | 46 |
+--------+--------+--------+--------+
Reader B: | Byte 3 | Byte 2 | Byte 1 | Byte 0 |
| 46 | 07 | FA | 5B |
+--------+--------+--------+--------+
I can think of two reasons this may be happening:
1) CRC or checksum calculations at the start vs. end of the tag ID (vendors may implement this differently) but it sounds like you've already investigated that
2) The readers are configured to read different areas of the tag. For example, are you sure you are getting the tag ID in both cases? For passive UHF RFID Tags, you might be configured to read the TID Serial # vs. EPC. For HF MiFare readers, perhaps you are reading a data bank on one reader and the ID in the other. This is a long way of saying, are you sure both of your readers are actually configured the same way?

Scaling values with a known upper limit

I have a column of values in Excel that I need to modify by a scale factor. Original column example:
| Value |
|:-----:|
| 75 |
| 25 |
| 25 |
| 50 |
| 0 |
| 0 |
| 100 |
Scale factor: 1.5
| Value |
|:-----:|
| 112.5 |
| 37.5 |
| 37.5 |
| 75 |
| 0 |
| 0 |
| 150 |
The problem is I need them to be within a range of 0-100. My first thought was take them as percentages of 100, but then quickly realized that this would be going in circles.
Is there some sort of mathematical method or Excel formula I could use to handle this so that I actually make meaningful changes to the values, such that when these numbers are modified, 150 is 100 but 37.5 might not be 25 and I'm not just canceling out my scale factor?
Assuming your data begin in cell A1, you can use this formula:
=MIN(100,A1*1.5)
Copy downward as needed.
You could do something like:
ScaledValue = (v - MIN(AllValues)) / (MAX(AllValues) - MIN(AllValues)) * (SCALE_MAX - SCALE_MIN) + SCALE_MIN
Say your raw data (a.k.a. AllValues) ranges from a MIN of 15 to a MAX of 83, and you want to scale it to a range of 0 to 100. To do that you would set SCALE_MIN = 0 and SCALE_MAX = 100. In the above equation, v is any single value in the data.
Hope that helps
Another option is:
ScaledValue = PERCENTRANK.INC(AllValues, v)
In contrast to my earlier suggestion, (linear --- preserves relative spacing of the data points), this preserves the order of the data but not spacing. Using PERCENTRANK.INC will have the effect that sparse data will get compressed closer together, and bunched data will get spread out.
You could also do a weighted combination of the two methods --- give the linear method a weight of say 0.5 so that relative spacing is partially preserved.

Resources