4-way handshake failed with freeradius on openWrt? - openwrt

I used freeradius-server on openWrt to get sim IMSI. Because I did have some sim value(rand, sres, kc),I changed the source code use fake value. It can be authenticated successfully. But in the process of 4-way handshake, it failed! It just have one handshake.
I captured some package with wireshark, anyone can help me analysis the reason or have a better way to get imsi on openWrt?
eap-sim authenticate process
handshake 1 of 4

I found the reason!
At the begining, I do not have the sim value(RAND, sres, kc), so I create some fake value. The code need the correct msk value to build up PMK package, like these:
static int eap_sim_sendsuccess(EAP_HANDLER *handler)
{
unsigned char *p;
struct eap_sim_server_state *ess;
VALUE_PAIR **outvps;
VALUE_PAIR *newvp;
/* outvps is the data to the client. */
outvps= &handler->request->reply->vps;
ess = (struct eap_sim_server_state *)handler->opaque;
/* set the EAP_ID - new value */
newvp = paircreate(ATTRIBUTE_EAP_ID, PW_TYPE_INTEGER);
newvp->vp_integer = ess->sim_id++;
pairreplace(outvps, newvp);
p = ess->keys.msk; //**look here**!
add_reply(outvps, "MS-MPPE-Recv-Key", p, EAPTLS_MPPE_KEY_LEN);
p += EAPTLS_MPPE_KEY_LEN;
add_reply(outvps, "MS-MPPE-Send-Key", p, EAPTLS_MPPE_KEY_LEN);
return 1;
}
So, It built a wrong PMK package. The mobile phone recieved the 1/4 handshake and droped it.

Related

How to send and receive in a PROMELA process without timeout / deadlock?

I cannot wrap my head around this PROMELA problem: I have N processes ("pc") which may both send and receive messages over a channel ("to_pc"). Each process has its own channel over which it receives messages.
For a process to be able to receive, I have to keep it in a loop which checks the channel for incoming messages. As a second loop option the process sends a message to all other channels.
However, in simulation mode, this always causes a timeout, without anything being sent at all. My theory so far is that I created a deadlock where all processes want to send at once, causing them all to be unable to receive (since they are stuck in their "send" part of the code).
So far I have been unable to resolve this problem. I have tried to use a global variable as a semaphore to "forbid" sending, so that only one channel may send. However, this did not change the results. My only other idea is to use a timeout as the trigger for the sending, but this does not seem right to me at all.
Any ideas? Thanks in advance!
#define N 4
mtype={request,reply}
typedef message {
mtype type;
byte target;
byte sender;
};
chan to_pc[N] = [0] of {message}
inline send() {
byte j = 0;
for (j : 0 .. N-1) {
if
:: j != address ->
to_pc[j]!msg;
:: else;
fi
}
}
active [N] proctype pc(){
byte address = _pid;
message msg;
do
:: to_pc[address]?msg -> /* Here I am receiving a message. */
if
::msg.type == request->
if
:: msg.target == address ->
d_step {
msg.target = msg.sender
msg.sender = address;
msg.type = reply;
}
send();
:: else
fi
:: msg.type == reply;
:: else;
fi
:: /* Here I want to send a message! */
d_step {
msg.target = (address + 1) % N;
msg.sender = address;
msg.type = request;
}
send();
od
};
I can write a full-fledged working version of your source code if you want, but perhaps it is sufficient to highlight the source of the issue you are dealing with and let you have fun solving it.
Branching Rules
any branch with an executable condition can be taken, non-deterministically
if there is no branch with an executable condition, the else branch is taken
if there is no branch with an executable condition and no else branch, then the process hangs till when one of the conditions becomes true
Consider this
1: if
2: :: in?stuff -> ...
3: :: out!stuff -> ...
4: fi
where in and out are both synchronous channels (size is 0).
Then
if someone is sending on the other end of in then in?stuff is executable, otherwise it is not
if someone is receiving on the other end of out then out!stuff is executable, otherwise it is not
the process blocks at line 1: up until when at least one of the two conditions is executable.
Compare that code to this
1: if
2: :: true -> in?stuff; ...
3: :: true -> out!stuff; ...
4: fi
where in and out are again synchronous channels (size is 0).
Then
both branches have an executable condition (true)
the process immediately commits itself to either send or receive something, by non-deterministically choosing to execute a branch either at line 2: or 3:
if the process chooses 2: then it blocks if in?stuff is not executable, even when out!stuff would be executable
if the process chooses 3: then it blocks if out!stuff is not executable, even when in!stuff would be executable
Your code falls in the latter situation, since all the instructions within d_step { } are executable and your process commits to send way too early.
To sum up: in order to fix your model, you should refactor your code so that it's always possible to jump from send to receive mode and viceversa. Hint: get rid of that inline code, separate the decision to send from actual sending.

How does addressing work in devicetree for a Xilinx CDMA?

Background:
What I want to do is to be able to write from my ARM processor to a BRAM, on a Zynq 7000.
To do this, I have the following components:
-M_AXI_GP0 on PS7 connects to S_AXI_LITE on axi_cdma_0 through an AXI Interconnect
-cdma_introut on axi_cdma_0 connects to IRQ_F2P on PS7 through sys_concat, input 11. This means that this maps to Interrupt 87 on PS7.
-M_AXI on axi_cdma_0 connects to S00_AXI on axi_mem_intercon
-M01_AXI on axi_mem_intercon connects to S_AXI_HP3 on PS7
-M00_AXI on axi_mem_intercon connects to S_AXI on axi_bram_ctrl_0
-BRAM_PORTA on axi_bram_ctrl_0 connects to BRAM_PORTA on blk_mem_gen0
=========================================================================
In my mind, what this setup ought to do is this:
Once a transaction is submitted from the ARM DMA Engine, the Zynq will use GP0 to send a command to the CDMA controller via GP0.
The CDMA controller will receive the commands on its slave AXI_LITE port, and interpret the request to access RAM via HP3.
The CDMA controller will move data through axi_mem_intercon in order to take the transaction data from hp3 on M01_AXI, and send it through M00_AXI to the BRAM Controller
The BRAM controller will take in the AXI-4 input and convert that to the appropriate BRAM port to write the data into the BRAM generated by blk_mem_gen_0
After completing this action, the CDMA will send an interrupt through sys_concat to indicate to the DMA Engine that its work is complete.
After loading this hdl design into the PL fabric, I attempt to submit the transaction to the DMA engine via a kernel module. The result is a timeout, with the DMA engine apparently never finishing the task.
=========================================================================
In my attempts to figure out the problem, I've made these observations:
After attempting a write transaction, which times out, I attempted a read transaction to the same DMA channel, but configured to read data. What I get back is all the data that I had attempted to write. This, to me, seems to indicate that the DMA engine IS writing to somewhere, but isn't recognizing the completion of the task
The BRAM in question is a dual port RAM, and the other port reads the data in the BRAM and toggles LEDs to reflect the data. The LEDs are not toggling when I attempt this write transaction, so it seems as though the DMA transaction is not making it as far as the BRAM
When looking at cat /proc/interrupts, I can see several interrupts, but not GIC 87. As mentioned before, the interrupt line I am using goes to Input 11 of the IRQ concat block. I can confirm that the interrupt line which goes to Input 12 does indeed correspond to GIC 88 from /proc/interrupts, so I believe my understanding of which interrupt I am looking for is correct. So for some reason it is not registering that interrupt on the processor.
=========================================================================
Based on this, I believe my devicetree entry for this CDMA is what is incorrect.
In Vivado, I can see these entries in the Address Editor(Some entries omitted for brevity):
sys_ps7
Data(32 address bits:0x40000000 [1G])
axi_cdma_0 S_AXI_LITE Reg 0x43C0_0000 64K 0x43C0_FFFF
axi_cdma_0
Data(32 address bits : 4G)
axi_bram_ctrl_0 S_AXI Mem0 0xC000_0000 4K 0xC000_0FFF
sys_ps7 S_AXI_HP3 HP3... 0x0000_0000 1G 0x3FFF_FFFF
My attempt to write a devicetree entry is as follows:
axi-cdma#43C00000{
#dma-cells = <0x1>;
compatible = "tst,axi-cdma-ctrl-1.00.a";
reg = <0x10000000 0x1000>;
interrupts = <0x0 0x37 0x4>;
interrupt-parent = <0x1>;
dma-channel#C0000000{
buswidth = <0x20>;
}
Before I added this entry in my kernel module failed to even register a transaction channel, and now it does, so I am fairly certain that the kernel is accepting this entry at least enough to assign a DMA channel. However, I don't understand much about how exactly the devicetree works, specifically with the addressing, so there is a good chance I have written this incorrectly, and that is why my transaction doesn't succeed. Can anyone help me correct my design?
}
Declaring the IP core in device tree is not sufficient. You must also declare your DMA client, as Xilinx does in CDMA test client:
cdmatest_1: cdmatest#1 {
compatible ="xlnx,axi-cdma-test-1.00.a";
dmas = <&axi_cdma_0 0>;
dma-names = "cdma";
} ;
In dmas field, the axi_cdma_0 references the CDMA IP core and the 0 its first dma-channel, as defined in the devicetree:
axi_cdma_0: dma#4e200000 {
#dma-cells = <1>;
clock-names = "s_axi_lite_aclk", "m_axi_aclk";
clocks = <&clkc 15>, <&clkc 15>;
compatible = "xlnx,axi-cdma-1.00.a";
interrupt-parent = <&intc>;
interrupts = <0 31 4>;
reg = <0x4e200000 0x10000>;
xlnx,addrwidth = <0x20>;
xlnx,include-sg ;
dma-channel#4e200000 {
compatible = "xlnx,axi-cdma-channel";
interrupts = <0 31 4>;
xlnx,datawidth = <0x20>;
xlnx,device-id = <0x0>;
xlnx,include-dre ;
xlnx,max-burst-len = <0x10>;
};
};
After that, you should register your client as a platform driver. Again, from CDMA test client source:
static const struct of_device_id xilinx_cdmatest_of_ids[] = {
{ .compatible = "xlnx,axi-cdma-test-1.00.a", },
{ }
};
static struct platform_driver xilinx_cdmatest_driver = {
.driver = {
.name = "xilinx_cdmatest",
.owner = THIS_MODULE,
.of_match_table = xilinx_cdmatest_of_ids,
},
.probe = xilinx_cdmatest_probe,
.remove = xilinx_cdmatest_remove,
};
static int __init cdma_init(void)
{
return platform_driver_register(&xilinx_cdmatest_driver);
}
Please note the compatible field of device tree and of platform driver definition, these strings must match. If you did not do this, the dma_request_slave_channel() cannot reserve a channel from your CDMA IP core. Moreover, ensure you do not use dma_request_channel() which is not supported in xilinx kernel >= 4.0 and will fail to reserve channels properly, the transfer will not complete and the DMA will timeout with no interrupt. I am not sure about observation 1, it might be a caching effect. Try to use dma_alloc_coherent() instead of kmalloc().
PS: In any case, try to make sure your hardware is ok by using a bare metal app if possible.

CAPL Scripting - CAN C communication (Stop transmitting one message from DBC)

I am working on a CAPL script that has to allow all messages to transmit on a CAN C channel and stop transmitting one particular message from the database file.
Can anyone help with the method/function/code I can use?
Your question is vague, but I'm assuming you are going from one CAN channel to another. For instance, CAN C to CAN D (or CAN 3 to CAN 4), than you could do:
on message CAN3.0x7FF // This would be that one ID that stops at some point
{
message CAN4.0x7FF msg;
msg = this;
// Assuming you are receiving on CAN 3, and looking to transmit on CAN 4
if(this.dir == rx)
{
// Declare a global variable that sets to 1 when you want it to stop
if(MSG_STOP == 0)
output(msg);
}
}
on message CAN3.*
{
message CAN4.* msg;
msg = this;
if (this.dir == rx)
{
output (msg);
}
}
AFAIK, the only way to accomplish this is to disable any automatic transmission of messages (e.g. via the IG or Network IL) and transmit all messages manually from your CAPL script in timer callbacks. Transmission can be done using the output function and based on whichever criteria you define, you can choose not to call output for any messages which should be blocked.
If you are using the Interaction Layer (IL) in your simulation, and the DBC file cyclic times are correctly configured there are some CAPL functions that can be used for fault injection which will allow you to selectively start/stop transmitting certain messages:
on sysvar Sys_m0x461_Send {
/**********************************************************
* FAULT INJECTION Enable/Disable Msg Sending
**********************************************************/
if (#this) {
ILFaultInjectionEnableMsg(Message0x461fromDBC);
}
else {
ILFaultInjectionDisableMsg(Message0x461fromDBC);
}
}
In the example if the system variable (could be linked to a panel control, e.g. checkbox) equals '1' the message will transmit as defined in the DBC, otherwise the message sending is stopped.

Inet framework: Send message from one host to another

I am new to Omnet++ and I am trying to simulate a Wifi network. I have successfully created a network consisting of an AP and some nodes and all the nodes are able to connect to the AP.
What I want to do is that once all the nodes are connected to the AP, a node (based on its IP address) should send a message to another node in the network. I have created the .msg file with all the required fields and it is successfully compiled by the message compiler to the corresponding _m.h and _m.cc files. I want this message to be sent to the other node.
How to proceed with this? Iknow it has to do something with the handleMessage() function but I can't find the file containing that function.
Thanks in advance for any kind of help.
To send the initial message you will have to use the send() when you initialize you node.
From the tictoc tutorial:
void Txc1::initialize()
{
// Initialize is called at the beginning of the simulation.
// To bootstrap the tic-toc-tic-toc process, one of the modules needs
// to send the first message. Let this be `tic'.
// Am I Tic or Toc?
if (strcmp("tic", getName()) == 0)
{
// create and send first message on gate "out". "tictocMsg" is an
// arbitrary string which will be the name of the message object.
cMessage *msg = new cMessage("tictocMsg");
send(msg, "out");
}
}
Then you want the nodes to be able to react. Their reaction can be silent -- just accept the message and delete it, or send another message in return.
For that you will need to implement the handleMessage() function inside the nodes .cc file.
void Txc1::handleMessage(cMessage *msg)
{
// The handleMessage() method is called whenever a message arrives
// at the module. Here, we just send it to the other module, through
// gate `out'. Because both `tic' and `toc' does the same, the message
// will bounce between the two.
send(msg, "out");
}
You can find the function in the .cc file in the same project or folder. Normally the name of the .cc file is close to the name of the .ned file that caries the details of the host or node or whatever you call it in your project.

vxWorks Parallel Port write() Failure

I'm attempting to write to the parallel port for the first time using the vxWorks lptDrv driver, but a call to write() always seems to return a -1. Here's the code I'm using:
#define PARALLEL_PORT "/lpt/0"
/* Create a device for the parallel port */
lptDevCreate(PARALLEL_PORT,0)
/*open the parallel port*/
parallelPortFD = open(PARALLEL_PORT, O_CREAT|O_WRONLY, 0))
LOCAL UINT32 watchdogBit = 0x01;
if (write(parallelPortFD, (char*) watchdogBit, sizeof(UINT32)) == -1)
{
/* Always hits this block */
}
Both calls to lptDevCreate and open return okay. I currently don't have the hardware plugged into the parallel port, so that makes it difficult to test, but I don't think that would cause a write failure either.
For some more info, I was able to call lptShow(), but I'm not sure what I'm looking at:
controlReg = 0xff
statusReg = 0xff
created = TRUE
autofeed = TRUE
inservice = FALSE
normalInt = 0
defaultInt = 0
retryCnt = 1
busyWait (loop) = 10000
strobeWait (loop) = 10000
timeout (sec) = 1
intLevel (IRQ) = 7
The kernel configuration had a different port number than the BIOS, so I updated the kernel config to match. That then showed the statusReg set to 0x78, indicating that 1. the port was busy and 2. an out of paper error. Since nothing was plugged into the parallel port, it showed a 0x78 as the default status. I still don't have the hardware to test the port, but wind river support was seeing similar results without a device plugged in, which was then corrected when something was connected to the port.
Thanks to Benoit for the response that got me moving again.

Resources