Dropping only UDP packets in RPL - contiki

1)I am trying to drop only UDP packets in RPL in Contigi-ng OS.
I modified the code in/contiki/core/net/tcpip.c as:
...
static void
packet_input(void)
{
#if DEST_PORT_IS_MAL_DROP
if ((UIP_IP_BUF->proto == UIP_PROTO_UDP) &&
(uip_ntohs(UIP_UDP_BUF->destport)==UDP_MALICIOUS_PORT)){
uip_len=0;}
#endif
#if UIP_CONF_IP_FORWARD
if(uip_len > 0){
...
This drops all packets whose destport = UDP_MALICIOUS_PORT and do not know how to drop only UDP packets and allow control messages.
Thanks in advance

You should change uip6.c in the "os/net/ipv6/uip6.c" path.
please see this paper :A Reference Implementation for RPL Attacks Using Contiki-NG and COOJA.
This is good reference for implementing attacks in Contiki-ng.

Related

Communicating between subnets with ESP8266 wifi extender

I have a local (household 192.168.0.X) network provided by my router/modem which assigns local IP addresses by the usual Dynamic DNS. I have added an ESP8266 runnning in the WiFi Nat (natp) mode to act as an extender. So it connected to the router as a station and then provides an access point that other devices can connect to. Currently, its subnet is 172...X).
This works in the sense that devices on the extended subnet can see the "world" like google.com etc...
The problem is devices on the 192. network can't see any devices on the extended network.
The source of the problem is pretty obvious: the 192 network devices are all connected by the router which has no clue about any devices connnected to the extender access point.
Is this possible and is there a good ESP 82666 example for this?
If not example, I'm unsure what I'm not understanding-- I'm unsure of what to call this configuration so googling it isn't working.
I feel like there ought to be a way to make the extender just a transparent replicator/relay so the Router is seeing every device and is doing the DHCPS job itself rather than the ESP8266 access point. But I'm stuck.
What sort of configuration approach I can use to expose the devices on the extended network to the computers on the 192 network?
There's a myriad of possible settings but I can't seem to find a permutation that works. (e.g. the Gateway setting or turning off DHCP on the extender access point.) I've tried making the extender network be the same 192.168.0.X rather than 172. But that didn't help.
Detail:
What I have here is a sensor network out in my barn that lives on the access point. I want to be able to access the sensors from inside the house. I've goofed around with workarounds of having the barn devices send their data to a server out in the world. But I want direct access so I can query the devices or do over the air programming directly to the devices from my home computer. I can only do this right now by connecting the home computer to the (slower) extended network access point rather than the high speed home router.
Here's an example of the code I'm modifying (basically one of the ESPWIFI example sketches.)
// NAPT example released to public domain
#if LWIP_FEATURES && !LWIP_IPV6
#define HAVE_NETDUMP 0
#ifndef STASSID
#define STASSID "HouseModem"
#define STAPSK "HouseModemPassword"
#endif
#include <ESP8266WiFi.h>
#include <lwip/napt.h>
#include <lwip/dns.h>
#include <dhcpserver.h>
#define NAPT 1000
#define NAPT_PORT 10
#if HAVE_NETDUMP
#include <NetDump.h>
void dump(int netif_idx, const char* data, size_t len, int out, int success) {
(void)success; // What does this do?
Serial.print(out ? F("out ") : F(" in "));
Serial.printf("%d ", netif_idx);
// optional filter example: if (netDump_is_ARP(data))
{
netDump(Serial, data, len);
//netDumpHex(Serial, data, len);
}
}
#endif
void setup() {
Serial.begin(115200);
Serial.printf("\n\nNAPT Range extender\n");
Serial.printf("Heap on start: %d\n", ESP.getFreeHeap());
#if HAVE_NETDUMP
phy_capture = dump;
#endif
// first, connect to STA so we can get a proper local DNS server
WiFi.mode(WIFI_STA);
WiFi.begin(STASSID, STAPSK);
while (WiFi.status() != WL_CONNECTED) {
Serial.print('.');
delay(500);
}
Serial.printf("\nSTA: %s (dns: %s / %s)\n",
WiFi.localIP().toString().c_str(),
WiFi.dnsIP(0).toString().c_str(),
WiFi.dnsIP(1).toString().c_str());
// give DNS servers to AP side
dhcps_set_dns(0, WiFi.dnsIP(0));
dhcps_set_dns(1, WiFi.dnsIP(1));
WiFi.softAPConfig( // enable AP, with android-compatible google domain
// IPAddress(172, 217, 28, 254),
// IPAddress(172, 217, 28, 254),
// IPAddress(255, 255, 255, 0));
WiFi.localIP(),IPAddress(192,168,0,1),IPAddress(255, 255, 255, 0));
WiFi.softAP(STASSID "extender", STAPSK); // odd way to concat strings
Serial.printf("AP: %s\n", WiFi.softAPIP().toString().c_str());
Serial.printf("Heap before: %d\n", ESP.getFreeHeap());
err_t ret = ip_napt_init(NAPT, NAPT_PORT);
Serial.printf("ip_napt_init(%d,%d): ret=%d (OK=%d)\n", NAPT, NAPT_PORT, (int)ret, (int)ERR_OK);
if (ret == ERR_OK) {
ret = ip_napt_enable_no(SOFTAP_IF, 1);
Serial.printf("ip_napt_enable_no(SOFTAP_IF): ret=%d (OK=%d)\n", (int)ret, (int)ERR_OK);
if (ret == ERR_OK) {
Serial.printf("WiFi Network '%s' with same password is now NATed behind '%s'\n", STASSID "extender", STASSID);
}
}
Serial.printf("Heap after napt init: %d\n", ESP.getFreeHeap());
if (ret != ERR_OK) {
Serial.printf("NAPT initialization failed\n");
}
}
#else
void setup() {
Serial.begin(115200);
Serial.printf("\n\nNAPT not supported in this configuration\n");
}
#endif
void loop() {
}
You can subnetting the routers network from nat devices onwords. So tree like network structure may form.
Let say your router is assigning 192.168.0.x/24 ip to your first hop devices then those devices could modify their access points network with 192.168.1.x/24 and so on upto the possible last hop.
To make it form dynamically on their own you may need to assign common ssid and password to all devices in that structure.
If you could able to achieve this then their may be chances of accessing individual devices from router.
Also you may get the idea of to what hop level individual device seats in network tree by their subnet ip.

RPL Setup with Contiki Simple UDP API and Border Router

I have a seemingly easy but quite specific question. I have three different node types in my network: a client, an aggregator and the border router (rpl-border-router). There should be a unicast connection between one (or multiple) clients and an aggregator. When the aggregator gets messages of some specific type or when some threshold is reached the aggregator forwards some other message to the border router. The example code of unicast-recevier (aggregator) in the simple-udp-rpl folder creates a RPL DAG the following way:
static void create_rpl_dag(uip_ipaddr_t *ipaddr) {
struct uip_ds6_addr *root_if;
root_if = uip_ds6_addr_lookup(ipaddr);
if(root_if != NULL) {
rpl_dag_t *dag;
uip_ipaddr_t prefix;
rpl_set_root(RPL_DEFAULT_INSTANCE, ipaddr);
dag = rpl_get_any_dag();
uip_ip6addr(&prefix, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0);
rpl_set_prefix(dag, &prefix, 64);
PRINTF("created a new RPL dag\n");
} else {
PRINTF("failed to create a new RPL DAG\n");
}
}
However, since the border router creates a RPL DAG on its own, the receiver (aggregator) cannot send messages to the border router. But removing this RPL code from the receiver results in the inability to receive messages from the sender (client). So the problem is probably somehow connected to RPL. The ContikiRPL code is not really well documented and I am struggling to make progress. Any help is greatly appreciated.

Indy's SNMP Trap send nothing

I tried to send SNMP Trap using Indy's component TIdSnmp.
(Code was copied from Implementing SNMP SendTrap using Indy components)
void __fastcall TMainForm::btSendTrapClick(TObject *Sender)
{
String myEnterprise = _D("1.5.5.5.5.5.5.5");
String eventType = myEnterprise + _D(".1");
String eventDistance = myEnterprise + _D(".2");
TIdSNMP * idSnmp = 0;
idSnmp = new TIdSNMP(NULL);
idSnmp->Trap->Host = edHost->Text;
idSnmp->Trap->Community = _D("public");
idSnmp->Trap->Enterprise = myEnterprise;
idSnmp->Trap->GenTrap = 6; // I've met such values
idSnmp->Trap->SpecTrap = 1; // somewhere in inet
idSnmp->Trap->MIBAdd(eventType,_D("ftCritical"));
idSnmp->Trap->MIBAdd(eventDistance,_D("2.357"));
idSnmp->SendTrap();
delete idSnmp;
}
But wireshark doesn't registar any network activity. I tried variant with QuickSendTrap with the same result.
In despair I decided to try Indy's UDP component for sending something.
void __fastcall TForm1::btFireClick(TObject *Sender)
{
TIdUDPClient* udpClient = 0;
TIdBytes sendData;
myClass* packet = new myClass();
packet->a = 10;
packet->b = 77;
packet->c = "Test";
int size = sizeof(*packet);
sendData = RawToBytes(packet, size);
udpClient = new TIdUDPClient(NULL);
udpClient->Host = "192.168.100.19";
udpClient->Port = 162;
udpClient->SendBuffer(sendData);
delete udpClient;
}
Surely it's not a real SNMP Trap but wireshark see this:
192.168.100.21 192.168.100.19 UDP 54 Source port: 49873 Destination port: snmptrap
Wireshark filter is "udp portrange 161-162"
And in data section I can find my values. By the way SNMP component works properly for getting values by simple idSnmp->SendQuery() and this is registered by wireshark as well.
So, are there some additinal conditionals in order to SendTrap() works properly?
I have Windows7, administative rights. Firewall is turned off.
Code compiled by Embarcadero RAD Studio 2010, desktop application.
Should SNMP Trap receiver wait my SendTrap() just in order to SendTrap() could work? (unfortunately, I haven't got another computer for experiments at the moment)
Should be OID "1.5.5.5.5.5.5.5" be registered somewhere in my computer just in order to SendTrap() could work?
Maybe some other requirements?
But wireshark doesn't registar any network activity
That is not what you said in the other discussion. You said it was working.
So, are there some additinal conditionals in order to SendTrap() works properly?
No. The code I gave you is all you need.
Should SNMP Trap receiver wait my SendTrap() just in order to SendTrap() could work?
No. UDP is connection-less. A receiver is not required in order to send. If there is no receiver, an ICMP error will be sent back to the sender.
Should be OID "1.5.5.5.5.5.5.5" be registered somewhere in my computer just in order to SendTrap() could work?
No.

Extending packet header from within a Netfilter hook

I want to prepend IP header on an existing IP packet while inside NF_HOOK_LOCAL_OUT. The issue I face is that the skb expansion functions (such as copy/clone/expand/reallocate header) allocate a new sk_buff. We can not return this newly allocated pointer since netfilter hook function no longer (kernel version 2.6.31) passes the skb pointer's address (passes by value). How I solved the issue is as follows:
1. I got a new skb using skb_header_realloc(). This copies all the data from skb.
2. I modified the new skb (call it skb2) to prepend the new IP header, set appropriate values in the new IP header.
3. Replace the contents of the original skb (passed in the Netfilter hook function) with the contents of the skb2 using skb_morph(). Returned NF_ACCEPT.
Is this the only way of achieving what I intended to? Is there a more efficient solution? Are there other use cases of skb_morph (besides the IP reassembly code)?
This works for me, in 2.6 kernels:
...
struct iphdr* iph;
if (skb_headroom(skb) < sizeof(struct iphdr))
if (0 != pskb_expand_head(skb, sizeof(struct iphdr) - skb_headroom(skb), 0, GFP_ATOMIC)) {
printk("YOUR FAVOURITE ERROR MESSAGE");
kfree_skb(skb);
return NF_STOLEN;
}
iph = (struct iphdr*) skb_push(skb, sizeof(struct iphdr));
//Fill ip packet
return NF_ACCEPT;
Hope it helps.

Erlang C node related question

In the tutorial provided at:
http://www.erlang.org/doc/tutorial/cnode.html
There is the following example:
/* cnode_s.c */
#include
#include
#include
#include
#include "erl_interface.h"
#include "ei.h"
#define BUFSIZE 1000
int main(int argc, char **argv) {
int port; /* Listen port number */
int listen; /* Listen socket */
int fd; /* fd to Erlang node */
ErlConnect conn; /* Connection data */
int loop = 1; /* Loop flag */
int got; /* Result of receive */
unsigned char buf[BUFSIZE]; /* Buffer for incoming message */
ErlMessage emsg; /* Incoming message */
ETERM *fromp, *tuplep, *fnp, *argp, *resp;
int res;
port = atoi(argv[1]);
erl_init(NULL, 0);
if (erl_connect_init(1, "secretcookie", 0) == -1)
erl_err_quit("erl_connect_init");
/* Make a listen socket */
if ((listen = my_listen(port))
I suspect that erl_receive_msg is a blocking call, and I don't know how to overcome this. In C network programming there is the "select" statement but in the Erlang EI API I don't know whether there is such a statement.
Basically I want to build a C node, that continuously sends messages to Erlang nodes. For simplicity suppose there is only one Erlang node.
The Erlang node has to process the messages it receives from the C node. The Erlang node is not supposed to ensure that it has received the message, not does it have to reply with the result of processing. Therefore once the message is sent I don't care about it faith.
One might think that one could modify the code as:
...
if (emsg.type == ERL_REG_SEND) {
...
while(1) {
//generate tuple
erl_send(fd, fromp, tuple);
//free alloc resources
}
...
}
This will produce an infinite loop in which we produce and consume (send) messages.
But there is an important problem: if I do this, then the C node might send too many messages to the Erlang node (so there should be a way to send a message from the Erlang node to the C node to slow down), or the Erlang node might think that the C node is down.
I know that the questions must be short an suite (this is long and ugly), but summing up:
What mechanism (procedure call, algorithm) one might use to develop an eager producer in C for a lazy consumer in Erlang, such that both parties are aware of the underlying context ?
I use Port Drivers myself for the case you are describing (haven't touched the C nodes because I'd rather have more decoupling).
Have a look at the Port Driver library for Erlang: EPAPI. There is a project that leverages this library: Erland DBus.
Did you check the ei_receive_msg_tmo function? I suppose it works similar to the receive after construct of Erlang, so if you set timeout to 0, it will be non-blocking.
I believe erl_interface is deprecated, and ei should be used instead. This might be a complete misinformation though...
you need to take a closer look at the tutorial link that you posted. (search for "And finally we have the code for the C node client.") You will see that the author provided a client cnode implementation. It looks rational.

Resources