How to use linkaddr_set_node_addr (linkaddr_t *addr) in Contiki with Unicast - contiki

Iam trying to using this function to set the node which send packet to other node in code unicast contiki , but this function doesn't work , what's the problem ? Can you help me ,please !
I want to topo 2 node which require :
If node 2 received packet from node 1 then node2 send the packet ACK to node 1 to announce that node 2 has received the packet from node 1 . I use unicast program in contiki . , I use function linkaddr_set_node_addr (linkaddr_t *addr) to set node 1 to send packet, but this function doesn't work , can someone help me , please .
This is my code :
linkaddr_t addr;
addr.u8[0]=2;
addr.u8[1]=0;
packetbuf_copyfrom("GINDBK",5);
unicast_send(&uc,&addr);
if (linkaddr_node_addr.u8[0]==1 && linkaddr_node_addr.u8[1]==0)
{
linkaddr_t addr;
addr.u8[0]=2;
addr.u8[1]=0;
linkaddr_set_node_addr(&addr);
packetbuf_copyfrom("ACK",20);
addr.u8[0]=1;
addr.u8[1]=0;
unicast_send(&uc,&addr);
}

I think the problem is with the address assignment. You cannot simple assign values to the bytes of the address.
Instead of:
linkaddr_t addr;
addr.u8[1] = 2;
addr.u8[0] = 0;
linkaddr_set_node_addr(&addr);
Assign value to addr this way:
linkaddr_t addr = {{2,0}};
linkaddr_set_node_addr(&addr);
and if you wish to check if two addresses are equal use:
linkaddr_cmp(&addr, &addr2)

Related

How to read a byte of the Serial Presence Detect (SPD) data from the DIMM after 255(FF) bytes?

I have got SMBus Base Address Register,
and program the SMBus Transmit Slave Address Register with the DIMM SMBus address, SMBBASE 04h.
Then program the SMBus Host Command Register with the DIMM’s SPD data offset to be read, SMBBASE 03h.
But the Host Command Register (HCMD)—Offset 3h is Size: 8 bits(255/FF),
So How can I read the after 255 bytes?
For example:
DDR4 Serial Presence Detect (SPD) Table:
Byte 320 : Module Manufacturer ID Code
I need to read Byte 320.
My code like this
unsigned ReadByte(unsigned SMBase_addr,unsigned i)
{
unsigned val;
outportb(SMBase_addr,0x1e);
outportb(SMBase_addr 0x04,0xa7);
outportb(SMBase_addr 0x03,i);
outportb(SMBase_addr 0x02,0x48);
while((inportb(SMBase_addr))&0x01){
delay(10);
}
val=inportb(SMBase_addr 0x05);
return val;
}
for(i=0;i<383;i )
{
data=ReadByte(SMBase_addr,i);
printf("%4x",data);
}
and I change
outportb(SMBase_addr 0x03,i);
to
outportw(SMBase_addr 0x03,i);
Host Status Register return 0x44, Device Error (DERR).
At least in Linux PC,
You need to write SMBus address 0x37 first to reach page 1. (Let write 0 to SMbus addr 32)
Than ALL of your DDR4 RAM SPD switches to Page 1.
Just use regular functions for writing & reading required addresses.
Than switch to page 0 by writing SMBus address 0x36 after.
Trying to read DDR4 SPD?
They have 2 pages of 256 bytes each, and you need a dummy write to a special predefined address 0x6E to switch all SPD chips to page 1 (where your byte 320 is located), and than write to 0x6C switch them back to page 0 (to prevent an SPD read failure during next boot).
Read this datasheet on page 12 for more info.

lua dissector for custom protocol

I have written several Lua Dissectors for custom protocols we use and they work fine. In order to spot problems with missing packets I need to check the custom protocol sequence numbers against older packets.
The IP source and Destination addresses are always the same for device A to device B.
Inside this packet we have one custom ID.
Each ID has a sequence number so device B can determine if a packet is missing. The sequence number increments by 256 and rolls over when it reaches 65k
I have tried using global dictionary but when you scroll up and down the trace the decoder is rerun and the values change.
a couple of lines below show where the information is stored.
ID = buffer(0,6):bitfield(12,12)
SeqNum = buffer(0,6):bitfield(32,16)
Ideally I would like to list in each decoded frame if the previous sequence number is more than 256 away and to produce a table lists all these bad frames.
Src IP; Dst IP; ID; Seq
1 10.12.1.2; 10.12.1.3; 10; 0
2 10.12.1.2; 10.12.1.3; 11; 0
3 10.12.1.2; 10.12.1.3; 12; 0
4 10.12.1.2; 10.12.1.3; 11; 255
5 10.12.1.2; 10.12.1.3; 12; 255
6 10.12.1.2; 10.12.1.3; 10; 511 Packet with seq 255 is missing
I have now managed to get the dissector to check the current packet against previous packets by using a global array, where I store specific information about each frame. In the current packet being dissected I recheck the most recent packet and work my way back to the start to find a suitable packet.
dict[pinfo.number] = {frame = pinfo.number, dID = ID, dSEQNUM = SeqNum}
local frameCount = 0
local frameFound = false
while frameFound == false do
if pinfo.number > frameCount then
frameCount = frameCount + 1
if dict[(pinfo.number - frameCount)] ~= nil then
if dict[(pinfo.number - frameCount)].dID == dict[pinfo.number].dID then
seq_difference = (dict[(pinfo.number)].dSEQNUM - dict[(pinfo.number - frameCount)].dSEQNUM)
if seq_difference > 256 then
pinfo.cols.info = string.format('ID-%d SeqNum-%d missing packet(s) %d last frame %d ', ID,SeqNum, seq_difference, dict[(pinfo.number - frameCount)].frame)
end
frameFound = true
end
end
else
frameFound = true
end
end
I'm not sure I see a question to answer? If you're asking "how can I avoid having to deal with the dissector being invoked multiple times and screwing up the previous decoding of the values" - the answer to that is using the pinfo.visited boolean. It will be false the first time a given packet is dissected, and true thereafter no matter how much clicking around the user does - until the file is reloaded or a new one loaded.
To handle the reloading/new-file case, you'd hook into the init() function call for your proto, by defining a function myproto.init() function, and in that you'd clear your entire array table.
Also, you might want to google for related questions/answer on ask.wireshark.org, as that site is more frequently used for wireshark Lua API questions. For example this question/answer is similar and related to your case.

Communication between Erlang and c program

When erlang module communicates with a c program via a port it sends a packet to the c program my question is when i create a port using this configuration
Port = open_port({spawn, ExtPrg}, [{packet, 2}]).
what are the parameters sent in the packet ?
what is the length of each parameter?
Erlang module and C program communicate via stdin and stdout by sending byte stream(sequence of bytes).
Creating a port with
Port = open_port({spawn, ExtPrg}, [{packet, N}]).
(valid values for N are 1,2,4)
tells erlang that the packets sent will be in this format :
N bytes : data length of the packet (we can conclude the data length)
data length bytes : data

Detect disconnected socket?

I have client iOS app that connects to server.
It uses non blocking socket.
int fl;
fl=fcntl(s,F_GETFL,0);
fcntl(s,F_SETFL, fl | O_NONBLOCK);
int set = 1;
setsockopt(s, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int));
If there is no data then -1 returned by read
If it is disconnected then 0 returned by read
But it is not always true. Sometimes connection is lost but -1 is returned.
Is there something like eof to detect ?
0 is the EOF. If there is an error -1 is returned by read, and you should look at errno to see what it is. The only reliable way to detect a dropped connection in TCP is by writing to it at least twice.

How does one calculate ones link-local ipv6 address?

So there are several sites that will calculate your link-local ipv6 address for you, like this one right here.
Nevertheless, it does not give any useful into as to how this address is calculated nor what the input parameters are. So what is the procedure(or algorithm)to compute a link local ipv6 address if one knows ones ipv4 address, subnet mask, and gateway address? I'm doing a project with SCTP sockets that uses ISATAP network tunneling and the LL ipv6 address is used in constructing the ISATAP address.
Appendix A of RFC 4291 describes the method for computing a modified EUI-64 from a MAC address. Once you have the modified EUI-64, you just put it in the lower 64 bits of the address and put fe80:: in the top 64 bits.
Basically you flip the 7th bit of the MAC address, and pack its first 24 bits (including the flipped bit), then fffe, then the lower 24 bits of the MAC address, resulting in 64 bits total.
That being said, your question is how to derive the link local address from the IPv4 address and subnet mask. That, you can't do. The IPv4 address and subnet mask (if indeed there is one – IPv6 does not require that IPv4 be running at all on the same interface) has nothing to do with the IPv6 address and the two aren't related in any way. The IPv4 gateway address (again, if there is one) is even less relevant.
The link-local address can be based on the MAC address per RFC 4862 or randomly generated as per RFC 4941.
Normally this should be limited to global scope, but some systems extend this privacy extension implementation to link-local scope. Follow this question on serverfault for discussion of the topic.
The previous answers failed to note that there is a defined procedure for generating a link local IPv6 address from an IPv4 address when using ISATAP, and there is a different process for generating a link local IPv6 address from a MAC address. The two things are unrelated.
For ISATAP, the 32-bit IPv4 address is prepended wit the 96 bits of either fe80::200:5efe or fe80::200:5efe to get the 128-bit IPv6 link-local address.
For MAC to IPv6, the 48-bit MAC address is split in half, 16 bits are inserted in the middle, those bits being ff:fe, then it is prepended by the 64-bit link-local prefix fe80::, and finally the 7th bit in the 5th IPv6 segment is flipped, to get the 128-bit IPv6 link-local address.
The following code provides examples showing how to use the The IPAddress library to do the conversions in either Java or Go. Disclaimer: I am the project manager of those libraries.
These examples also help to visualize the conversions described above.
Go:
func convertToIsatap(ipv4Str string, isGlobal bool) string {
ipv4Address := ipaddr.NewIPAddressString(ipv4Str).GetAddress().ToIPv4()
zero := &ipaddr.IPv6AddressSegment{}
segments := make([]*ipaddr.IPv6AddressSegment, ipaddr.IPv6SegmentCount)
segments[1], segments[2], segments[3], segments[4] = zero, zero, zero, zero
segments[0] = ipaddr.NewIPv6Segment(0xfe80)
segments[5] = ipaddr.NewIPv6Segment(0x5efe)
if isGlobal {
segments[4] = ipaddr.NewIPv6Segment(0x200)
}
ipv6Address, _ := ipv4Address.GetIPv6Address(ipaddr.NewIPv6Section(segments))
return ipv6Address.String()
}
func convertToLinkLocalIPv6(macAddr string) string {
macAddress := ipaddr.NewMACAddressString(macAddr).GetAddress()
ipv6LinkLocal, _ := macAddress.ToLinkLocalIPv6()
return ipv6LinkLocal.String()
}
fmt.Println("1.2.3.4 becomes ISATAP " +
convertToIsatap("1.2.3.4", true))
fmt.Println("aa:bb:cc:11:22:33 becomes " +
convertToLinkLocalIPv6("aa:bb:cc:11:22:33"))
Java:
static String convertToIsatap(String ipv4Str, boolean isGlobal) {
IPv4Address ipv4Address = new IPAddressString(ipv4Str).getAddress().toIPv4();
IPv6AddressSegment zeroSeg = new IPv6AddressSegment(0);
IPv6AddressSegment segments[] =
new IPv6AddressSegment[IPv6Address.SEGMENT_COUNT - 2];
segments[1] = segments[2] = segments[3] = segments[4] = zeroSeg;
segments[0] = new IPv6AddressSegment(0xfe80);
segments[5] = new IPv6AddressSegment(0x5efe);
if(isGlobal) {
segments[4] = new IPv6AddressSegment(0x200);
}
return ipv4Address.getIPv6Address(
new IPv6AddressSection(segments)).toString();
}
static String convertToLinkLocalIPv6(String macStr) {
MACAddress macAddress = new MACAddressString(macStr).getAddress();
return macAddress.toLinkLocalIPv6().toString();
}
System.out.println("1.2.3.4 becomes ISATAP " +
convertToIsatap("1.2.3.4", true));
System.out.println("aa:bb:cc:11:22:33 becomes " +
convertToLinkLocalIPv6("aa:bb:cc:11:22:33"));
The output is the same for both examples:
1.2.3.4 becomes ISATAP fe80::200:5efe:102:304
aa:bb:cc:11:22:33 becomes fe80::a8bb:ccff:fe11:2233

Resources