Does the send() in omnet++ set the source address of the packet to the current host address?
Why am I asking? because I'm trying to code a class for a malicious host "Eve" that performs a replay attack.
void MalAODVRouter::handleMessage(cMessage *msg)
{
cMessage *ReplayMsg = msg->dup();
AODVRouting::handleMessage(msg);
capturedMsgs++;
if (capturedMsgs==10) // One out of every 10 packets (frequency of replay)
{
//we can add a delay before sending the copy of the message again (1 time unit)
sendDelayed(ReplayMsg, 1,"ipOut");
ReplayedMsgs++;
std::cout<<"Launched Replay Packet!\n";
ev<<"Launched Replay Packet!\n";
this->capturedMsgs=0;
// }
}
}
You can see at the beginning of my code snippet I tried using the function dup() to duplicate a packet (msg) Eve's receives while its on it's on its way to the legitimate destination.
Now, can I send the duplicated packet later and it would be having the original source address OR should I dig deeper into layers to fake the source address to have Bob's address instead of Eve's? like below:
/*UDPPacket *udpPacket = dynamic_cast<UDPPacket *>(msg);
AODVControlPacket *ctrlPacket = check_and_cast<AODVControlPacket *>(udpPacket->decapsulate());
IPv4ControlInfo *udpProtocolCtrlInfo = dynamic_cast<IPv4ControlInfo *>(udpPacket->getControlInfo());
ASSERT(udpProtocolCtrlInfo != NULL);
IPv4Address sourceAddr = udpProtocolCtrlInfo->getSrcAddr(); //get Source Address
IPv4Address destinationAddr = udpProtocolCtrlInfo->getDestAddr(); //get Destination Address
IPv4Address addr = getSelfIPAddress();
if (addr != destinationAddr) // if it is not destined for "Eve"
{
UDPPacket *ReplayUDPPacket = udpPacket;
AODVControlPacket *ReplayCtrlPacket = check_and_cast<AODVControlPacket *>(ReplayUDPPacket->decapsulate());
IPv4ControlInfo *ReplayUDPProtocolCtrlInfo = dynamic_cast<IPv4ControlInfo *>(ReplayUDPPacket->getControlInfo());
ASSERT(ReplayUDPProtocolCtrlInfo != NULL);
ReplayUDPProtocolCtrlInfo->setSrcAddr(sourceAddr); //Forge Source
ReplayUDPProtocolCtrlInfo->setDestAddr(destinationAddr); //Keep Destination
*/
//we can add a delay before sending the copy of the message again (1 time unit)
sendDelayed(ReplayMsg, 1,"ipOut");
ReplayedMsgs++;
std::cout<<"Launched Replay Packet!\n";
ev<<"Launched Replay Packet!\n";
this->capturedMsgs=0;
Does the send() method automatically sets the source address of the outgoing packet to the current host address? If so, then my replay attempt is not working...
send() is an OMNeT++ API call. As OMNeT++ is just a generic discrete event simulation framework, it does not know anything about the model code (so it cannot and should not manipulate it). IP address is a defined in the INET framework so only code from the INET framework can change it.
On the other hand the modules in the standard host below you module can do whatever they want before the packet is sent out to the network. Now in this actual case, the source IP address is determined by the control info that is attached to the packet. dup()-ing the packet copies that information too, so the IP address will be the same.
Related
I'm using inet and veins_inet to simulate vanet. I wanted my nodes to use Aodv to route packets when a packet is sent from one node to another or from one node to rsu to achieve this I did the following :
I declared nodes as aodvRouters and set their mobility to VeinsInetMobility:
*.node[*].typename = "AodvRouter"
*.node[*].mobility.typename = "VeinsInetMobility"
and rsu as AdhocHost with stationary mobility
*.rsu.typename = "AdhocHost"
*.rsu.mobility.typename = "StationaryMobility":
when I use the following code to send a message from a node[43] to node[101] or other nodes it works :
bool nodeApp::startApplication(){
if (getParentModule()->getIndex() == 43) {
destAddress = L3AddressResolver().addressOf(getModuleByPath("node[101]"),27);
auto tipChunk = makeShared<tip>();
timestampPayload(tipChunk);
tipChunk->setChunkLength(B(100));
tipChunk->setPacket_type("tip");
auto packet = createPacket("tip");
packet->insertAtBack(tipChunk);
socket.sendTo(packet.release(), destAddress, 9001);
}
return true;
}
but when I change the dest address to the rsu address it doesn't work I get the following error :
A runtime error occurred:
handlePacket(): Unknown protocol: id = 55, name = nexthopforwarding -- in module (inet::MessageDispatcher) Network.node[34].tn (id=3241), at t=20.000076211898s, event #1103
to solve this error I added the following tag
auto req = packet->addTagIfAbsent<DispatchProtocolReq>();
req->setProtocol(&Protocol::udp);
auto packetProtocolTag = packet->addTagIfAbsent<PacketProtocolTag>();
packetProtocolTag->setProtocol(&Protocol::udp
but I have the followwing error
A runtime error occurred:
Implicit chunk serialization is disabled to prevent unpredictable performance degradation (you may consider changing the Chunk::enableImplicitChunkSerialization flag or passing the PF_ALLOW_SERIALIZATION flag to peek) -- in module (inet::Udp) Network.node[12].udp (id=1216), at t=2.000076936898s, event #378
can anyone help me to send a message from a node to the rsu without broadcasting the packet
I am doing development for WSN in Omnet. I want to sniff a unicast message but I don't have an idea how can i do it in Omnet. I made some research but i couldn't found any method for that
When I send data to another node, I am sending it as an unicast with this method :
cModule *nodeIndex = flatTopolojiModulu->getSubmodule("n", i);//n is array
sendDirect(new cMessage("msg"), nodeIndex, "in");
I am using sendDirect method because I am working on wireless network. According to this description : https://stackoverflow.com/a/36082721/5736731
sendDirect method is usually the case in wireless networks.
But when send message with sendDirect, a message is being handled by receiver node. For example, according to code example above:
if i=2, message that is sent only can handle by node which has index "2" from
void AnyClassName::handleMessage(cMessage *msg) function
An example of broadcasting messages can be found in OMNeT++ Manual.
You should create only one instance of message that all nodes have to receive, and then send a new copy of this message to each node in loop. The dup() method has to be used to create the copy of a message.
cMessage * msg = new cMessage("msg");
// totalN is the total number of nodes
for (int i = 0; i < totalN; ++i) {
cModule *nodeIndex = flatTopolojiModulu->getSubmodule("n", i);
sendDirect(msg->dup(), nodeIndex, "in");
}
// original message is no longer needed
delete msg;
I just solved a latency issue in our infrastructure that was triggered because this code snippet here triggered a call to getaddrinfo on every run of the code:
sock = UDPSocket.open
sock.send("#{key}|#{value}", 0,
GRAPHITE_SERVER,
STATSD_PORT)
sock.close
Because we use statsd and graphite for high-volume event and stats monitoring, we were effectively triggering numerous calls getaddrinfo on every API call, and potentially tens of thousands every minute.
I modified this code to use the internal IP address, not the DNS name, of our graphite server, and was able to resolve the latency issue (presumably because the internal AWS VPC DNS server was not equipped to handle such a high volume of requests).
Now that my issue is resolved, I would love to know why the UDP implementation in Ruby is not using a cached IP address value (presumably based on the TTL of the domain name entry). Here is the relevant line and the function in full, you can see the call to rsock_addrinfo just at the end:
static VALUE
udp_send(int argc, VALUE *argv, VALUE sock)
{
VALUE flags, host, port;
struct udp_send_arg arg;
VALUE ret;
if (argc == 2 || argc == 3) {
return rsock_bsock_send(argc, argv, sock);
}
rb_scan_args(argc, argv, "4", &arg.sarg.mesg, &flags, &host, &port);
StringValue(arg.sarg.mesg);
GetOpenFile(sock, arg.fptr);
arg.sarg.fd = arg.fptr->fd;
arg.sarg.flags = NUM2INT(flags);
arg.res = rsock_addrinfo(host, port, rsock_fd_family(arg.fptr->fd), SOCK_DGRAM, 0);
ret = rb_ensure(udp_send_internal, (VALUE)&arg,
rsock_freeaddrinfo, (VALUE)arg.res);
if (!ret) rsock_sys_fail_host_port("sendto(2)", host, port);
return ret;
}
I assume this decision is intentional and would love to learn more about the reasons why.
getaddrinfo does not return data about the TTL... because it may not have it at all in fact, as the resolution may not necessarily be done over the DNS (could be hosts file, LDAP, etc. see /etc/nsswitch.conf)
From its manual here is the structure returned:
int getaddrinfo(const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res);
struct addrinfo {
int ai_flags; /* input flags */
int ai_family; /* protocol family for socket */
int ai_socktype; /* socket type */
int ai_protocol; /* protocol for socket */
socklen_t ai_addrlen; /* length of socket-address */
struct sockaddr *ai_addr; /* socket-address for socket */
char *ai_canonname; /* canonical name for service location */
struct addrinfo *ai_next; /* pointer to next in list */
};
After a successful call to getaddrinfo(), *res is a pointer to a linked list of one or more addrinfo structures.
So it is up to the thing "behind" getaddrinfo to do some caching or not, because getaddrinfo may have used the DNS to retrieve data, or not.
Some specific API for DNS, like getdnsapi will give back to the caller some information on the TTL, see https://getdnsapi.net/documentation/spec/ and example 6.2
6·2 Get IPv4 and IPv6 Addresses for a Domain Name
This example is similar to the previous one, except that it retrieves more information than just the addresses, so it traverses the replies_tree. In this case, it gets both the addresses and their TTLs.
Without any cache layer anywhere, since UDP is stateless, any new send must trigger resolution in some way or form.
You said:
"modified this code to use the internal IP address, not the DNS name"
You should instead install a local (on the box) recursive caching nameserver, such as unbound. All your local applications will benefit from it, and a faster DNS resolution (depending on how /etc/nsswitch.conf, /etc/resolv.conf and /etc/hosts are setup also).
For the associated bug report hinted by #Casper it seems at its core more an issue about IPv6 vs IPv4 which could be solved either by adjusting /etc/gai.conf or equivalent or doing some more clever programming around opening the connection, with the so called "happy eyeball algorithm" where you try to resolve both A and AAAA at the same time which means two parallel DNS queries (because you can not combine them into one per the protocol) and try to use the fastest one coming back, with a slight preference for AAAA if you want to be in the modern camp so you would fire the A one only some given amount of milliseconds after the AAAA to catch the case where you do not get a reply at all for AAAA or a negative one. See RFC6555 for details.
I am writing a network device driver.
Kernel 2.6.35.12
The device is supposed to be working when it is connected to a bridge port.
I am trying to intercept ICMPv6 RA and NS messages (Router/ Neighbor solicitation) forwarded to the interface from the bridge.
eth <–> br0 <–> mydevice
In the device start_xmit function I am doing to following:
Check that the protocol field after the Ethernet header is IPV6 (0x86dd)
Check that the ipv6 next header is ICMPv6 and check its type:
__u8 nexthdr = ipv6_hdr(skb)->nexthdr;
if (nexthdr == htons (IPPROTO_ICMPV6))
{
struct icmp6hdr *hdr = icmp6_hdr(skb);
u8 type = hdr->icmp6_type;
if(type == htons (NDISC_NEIGHBOUR_SOLICITATION) || type == htons (NDISC_ROUTER_SOLICITATION))
{
….Do something here…
}
}
When RS/NS are sent from within the device (e.g br0), I see that the code is working right.
The problem is when traffic is forwarded through the bridge from the other port.
I see that the icmp6_hdr(skb) returns an incorrect header.
Debugging some more, it seems that the
skb->network_header and the skb->transport_header are pointing to the same place.
icmp6_hdr is using the transport_header which explain why it is incorrect.
Dumping the skb data it looks that all the headers and payload are at the right offset (also compared it with tcpdump)
I suspect that it might be related to the bridge code, before going to dive into it,
I thought that maybe anyone had come up against anything similar or have any other ideas?
Part of the problem is that you are assuming that Netfilter did anything more than just figure out what was the next header. In my experience (albeit not very long) you want to do something like this:
struct icmp6hdr *icmp6;
// Obviously don't do this unless you check to make sure that it's the right protocol
struct ipv6_hdr *ip6hdr = (struct ipv6_hdr*)skb->network_header;
// You need to move the headers around
// Notice the memory address of skb->data and skb->network_header are the same
// that means that the IP header hasn't been "pulled"
skb->transport_header = skb_pull(skb, sizeof(struct ipv6_hdr));
if(ntohs(ip6hdr->nexthdr) == IPPROTO_ICMPV6) {
icmp6 = (struct icmp6hdr*)skb->transport_header;
// Doing this is more efficient, since you only are calling the
// Network to Host function once
__u8 type = ntohs(hdr->icmp6_type);
switch(type) {
case NDISC_NEIGHBOUR_SOLICITATION:
case NDISC_ROUTER_SOLICITATION:
// Do your stuff
break;
}
}
Hopefully this was helpful. I just started diving into writing Netfilter code, so I am not exactly certain 100%, but I found this out when I was trying to do something similar with IPv4 on the NF_IP_LOCAL_IN hook.
Hi I have a problem in sending message in project, I am using pic16f877a and sim300. the main function runs repeatedly. Some characters are missed in the sent sms.
my program is like this...
void main()//main function
{
Serial_init(); // initialization of serial communication
Send_SMS();
}
void Serial_init()
{
TRISC=0XC0;
TXSTA=0x24;
SPBRG=129; // set baud rate 9600 Hz for 20MHz fosc
RCSTA=0x90;
TXIF=1;
}
void Send_SMS(void)
{
USART_puts("AT\0");
putch1(0x0D);
Delay_ms4M(200);
USART_puts("AT+CMGF=1\0"); // switch into text mode
putch1(0x0D);// ascii of Carriage Return
Delay_ms4M(200);
USART_puts("AT+CMGS=\"9741153218\"\0"); // send sms to the number
putch1(0x0D);
Delay_ms4M(200);
USART_puts("Hi this is working LOL\0"); // SMS text
putch1(0x0A); // new line
Delay_ms4M(200);
putch1(0x0D);
Delay_ms4M(100);
putch1(0x1A); // ascii of 'substitute' i.e end of file
}
void USART_puts(const unsigned char *string)
{
while(*string)
putch1(*string++);
}
void putch1(unsigned char data)
{
while(TXIF==0);
TXREG=data;
}
Please help
additional details: all other programs run properly, but if I call send_sms function, "main" runs repeatedly and several messages are sent with missed characters.
IMHO :
Your chip is resetting. This is the highest probable cause.
Either it is faulty or you have set Watchdog Timer to on somewhere.
For missing characters :
a) Chip resets in the midst of a data transfer.
b) Roule of thumb for usart:
Stop stuffing bytes to usart. Send each byte with a small leading delay like 10-20 microseconds.
The communication is asynchronous, which means the receiver has to synchronize at the beginning of each communication unit which is a byte. To do that receiver brutely uses resources to detect start bit, the length (in time) of it etc. So if you try to send a byte train, you will stall the receiver.
Have you tried the code with another 16F877a ? (to check chip failure)...