Defining IP address to a programatically defined VLAN - linux

I am trying to create TAP's programatically, to which i am attaching a VLAN and an IPV4 address.
(using C, linux 5.4.56, on an embedded device)
TAP is created correctly with the regular ioctl's (TUNSETIFF, etc ...)
Then, i am using another set of ioctl's to set the VLAN, IPADDR, NETMASK, FLAGS, etc ... (SIOCGIFFLAGS, SIOCSIFADDR, etc ...).
For example
init_sockaddr_in_str((struct sockaddr_in *) &ifr.ifr_addr, ipv4_addr_str);
if (ioctl(sd, SIOCSIFADDR, &ifr) < 0) {
LOG("ioctl(SIOCGSIFADDR) error: (%s)\n",strerror(errno));
}
for setting the IPaddress, sd being a socket created to access this interface file descriptor.
Let supposet I created tap256 at first, the a VLAN tag 256, and an IPaddress a.b.c.d
The problem i have is that, at linux cli, i can correctly see all these interfaces with
"ip -d a"
but
Only the TAP256 is UP with the address set to IT ... an no VLAN
Another interface has been created (TAP256.256) which is DOWN with the VLAN defined
Of course, i can fix this manually (removing the IP addr from one interface, setting it to the other, etc ... but this is not the preferred option, i really liked it to be done programatically.
Is there something i am doing not right ? or a specific sequence of actions which will lead to my TAP256.256 UP and the correct IP address attached to it ?
Thanks,
Jacques

Related

How to make rule trigger on DNS rdata/IP address?

I currently have the following DNS Query Alert rule set up in Suricata (for test purposes):
alert dns any any -> any any (msg:”Test dns_query option”; dns_query; content:”google”; nocase; sid:1;)
Which is triggered when it captures DNS events which contain the word "google", such as in this packet:
{"timestamp":"2017-06-08T15:58:59.907085+0000","flow_id":1798294020028434,"in_iface":"ens33","event_type":"dns","src_ip":"172.16.10.132","src_port":53,"dest_ip":"192.168.160.140","dest_port":52385,"proto":"UDP","dns":{"type":"answer","id":57334,"rcode":"NOERROR","rrname":"www.google.com","rrtype":"A","ttl":300,"rdata":"172.217.12.164"}}
However, instead of searching for resource record names that contain "google", I want to use this same kind of alert to trigger on IP addresses that resolve to loopback, as is the case with the following packet (Notice the rdata field):
{"timestamp":"2017-06-08T15:59:37.120927+0000","flow_id":36683121284050,"in_iface":"ens33","event_type":"dns","src_ip":"172.16.10.132","src_port":53,"dest_ip":"192.168.160.140","dest_port":62260,"proto":"UDP","dns":{"type":"answer","id":53553,"rcode":"NOERROR","rrname":"outlook1.us","rrtype":"A","ttl":120,"rdata":"127.0.0.1"}}
As I have noticed, the contentsection of a Suricata rule searches only for a string.
My current rule triggers on a text match with the rrname/domain, how would I make it so that the rule triggers on rdata/IP address?
p.s.
Just out of curiosity I tried replacing the "google" in the content section of my alert with "127.0.0.1" and that didn't work either, as expected.
The ip address is just a 32 bit number. In the rule the IP should be represented as a hex value and not a string, for purposes of efficiency and saving bandwidth (a string will be 8+ bytes as opposed to 4 bytes).
Here is my final Suricata rule to alert whenever somebody gets sent to loopback on my network:
alert dns any any -> any any (msg:"BLACKLISTED DOMAIN"; content:"|7F 00 00 01|"; sid:1;)

How to change the name of a label in a linux device tree?

I am building my own kernel. The device tree of the kernel is modified, because of an own designed mainboard.
I can enable the can devices by:
// here ATMEL is defining the can0 and can1 memory mapped devices
#include "sama5d3_can.dtsi"
...
can0: can#f000c000 {
status = "okay";
};
can1: can#f8010000 {
status = "okay";
};
But now I want to switch the names of them. Can0 should become can1 and can1 should be can0.
How to do that?
PS: the error print when switching the labels and building the kernel:
| ERROR (duplicate_label): Duplicate label 'can0' on /ahb/apb/can#f8010000 and /ahb/apb/can#f000c000
| ERROR (duplicate_label): Duplicate label 'can1' on /ahb/apb/can#f8010000 and /ahb/apb/can#f000c000
The network "devices" do not take their name from the DTS at all. They get it from the name that is given to the netdevice.name.
In your case, the at91_can.c driver calls alloc_candev() that explicitely sets the interface's name to can%d (can0, can1, ...). The number "assigned" to each device in then strictly dependant on the sequence of the "enumeration" of the hardware and its registration with the at91_can driver.
Changing the device tree will not help you in changing the name of the network interfaces. If you really need to change the name of the can interfaces, you could write udev rules that do so.

Reading 802.1Q frames with specific VLAN tag under Linux

Is there any way to receive data of a specific VLAN tagged frame? Currently I am receiving all VLAN tagged frames by giving htons(0x22f0) as input to socket() function like:
m_iSocketDesc = socket(AF_PACKET, SOCK_RAW, htons(0x22f0));
numBytes = recvfrom(m_iSocketDesc, message_data, 1522, 0, NULL, 0)
I had a similar requirement. To receive packets with a specific VLAN, I created a VLAN interface and bound my raw socket to it. Now I can just send 802.3 frames, the kernel inserts/extracts VLAN tag.
Create a VLAN interface, you should have root permission
ip link add link <phyInterface> name <phyInterface.VLANID> type vlan id VLANID
Eg: ip link add link eth0 name eth0.100 type vlan 100
Use normal bind function in your application to bind to the VLAN interface. In the above example eth0.100.
You can refer to the below two links for sample code (I am NOT the owner of the code)
Sending: https://gist.github.com/austinmarton/1922600
Receiving: https://gist.github.com/austinmarton/2862515#file-recvraweth-c
The only change needed is that instead of binding to physical interface, bind to the virtual VLAN interface. Note that the Ethernet frames received are un-tagged frames. Any frames sent on this interface will automatically tagged with the VLANID.

iwlist scan: About the address? Is it unique? What kind of address is it?

#: iwlist wlan00 scanning
wlan0 Scan completed :
Cell 01 - Address: 16:76:02:7D:A5:25
.....
I was wondering what that address is? And is it unique?
That is what the Wireless tools iwlib.h refers to right?
int has_ap_addr;
sockaddr ap_addr; /* Access point address */
I am just looking for a unique identifier for the results that appear. Is that one?
Thanks

Why the route items in the route table(fetched via netlink socket) doesn't have netmask info?

I'm writing a program to find out which network interface is the best to connect to a specified target address.
Right now, I can get the route table via netlink socket APIs, but seems there is no netmask infos in it. I read the manual of rtnetlink, in all rtattr items, there is no netmask infos, just RTA_DST, RTA_SRC, RTA_GATEWAY... defined.
So, how to check out the netmask infos in route table? Just like we can see in route -n outputs.
Thanks a lot.
The prefix length associated with RTA_DST is in the rtm_dst_len field of the rtmsg, not in an rtattr. (I guess because it's a fixed-size field, unlike RTA_DST, which varies in size depending on the family.)

Resources