Get ip address of interface eth0 - lua

How can i find out the ip address of eth0 with lua?
My attempt does look like this:
system = require "system"
ip = system._execute("ifconfig eth0 | grep -i 'inet addr:'")
print (ip)
But is there a better way?

"better way" may be subjective, but I guess I'd (personally) prefer to io.popen("ifconfig etho") and process the text coming back from that like a text file, instead of relying on grep.

Related

Change multiples IP and MAC with tcprewrite

I'm working with tcpreplay and I have a question. Let's say I have three hosts on the same network, for example 172.16.25.0/24. While these hosts exchange messages with each other, I capture the data on the interface of one of them through tcpdump, generating a .pcap file. How do I change the IP and MAC addresses of the three hosts using tcprewrite?
Following the changes I want to achieve:
172.16.25.151 (00:00:00:00:00:a1) -> 10.10.10.151 (00:00:00:00:00:51)
172.16.25.152 (00:00:00:00:00:b1) -> 10.10.10.152 (00:00:00:00:00:52)
172.16.25.153 (00:00:00:00:00:c1) -> 10.10.10.153 (00:00:00:00:00:53)
For the cache file:
tcpprep --auto=bridge --pcap=ping.pcap --cachefile=case1.cache
My problem is when I try rewrite the endpoints MAC address.
I used:
tcprewrite --endpoints=172.16.25.151:172.16.25.152 --enet-smac=00:00:00:00:00:a1,00:00:00:00:00:51 --enet-dmac=00:00:00:00:00:b1,00:00:00:00:00:52 -i ping.pcap -o ping.pcap-rw-mac.pcap --cachefile=case1.cache
And this replace all flows with 00:00:00:00:00:51,172.16.25.151->00:00:00:00:00:52,172.16.25.152, inclusive those with the host_153.
What am I doing wrong?

How to force rerouting of a packet after return to netfilter from NFQUEUE

I have a caching application that runs in userspace. Normally, it uses DPDK to interact with the NICs directly without kernel interaction, grabbing packets off of the wire, and either passing them through, generating a response from cache, or in some occasions blocking them. It's transparent to the endpoints, and is written to work on raw packet data straight from the NIC. Notably, I'm not doing normal socket programming here - everything's handled at the packet level, without interaction with the TCP/IP stack.
For reasons that are long and boring, I wanted to add some NAT functionality. As a proof of concept, I was hoping to put a front end on my application using iptables/netfilter. So I did the NAT parts with commands like these:
sudo iptables --table nat --append PREROUTING --in-interface seg1a -j DNAT --to-destination $SERVERIP
sudo iptables --table nat --append POSTROUTING --out-interface seg1b -j MASQUERADE
sudo route add $SERVERIP seg1b
This works well for my purposes. The clients now attach to an interface on my system, but their traffic gets redirected to the server. I'm guaranteed that their traffic passes through my system, so all's good.
But to be useful as a cache, I need to be able to respond to some requests that I get from clients. I had thought I could use NFQUEUE for this, with a small application that reads from the netfilter queue and passes packets to and from my application via IPC. I used an iptables rule like this:
sudo iptables --table mangle --append FORWARD -j NFQUEUE
This works OK as long as my application doesn't respond to anything. But when my cache attempts to respond to something from one of the endpoints, things go wrong. The cache reverses all of the L2-4 headers, manages sequence and ack numbers, etc. But the packets don't get back to the client.
I think what's happening is that routing decisions for the packet were made before it was sent to NFQUEUE. So even though the cache returns something whose source and destination IP addresses are reversed, that's irrelevant for the routing of the packet.
I've tried a number of things to change the routing of my response packets, but nothing seems to work. How does one go about changing the routing on a packet read from netfilter queues? Failing that, is there a good way to just inject packets onto the wire from netfilter queues? If that were doable, I could block the original request and then send the cache's reply as an entirely new thing.
Thanks in advance for any suggestions.
The best answer I came up with for this problem was to open a raw socket and feed it my pre-built packets. Critically, you must create an iptables rule that matches your generated packets and tells netfilter not to do connection tracking. Otherwise, netfilter sees the injected packets and thinks there's a connection collision. It then does port forwarding, so the packets come out with a different port than you put in there!
I built the socket like this:
sid = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
Then, I turned on a couple of options (leaving failure handling out for brevity):
int one = 1;
const int *val = &one;
retval = setsockopt(sid, IPPROTO_IP, IP_HDRINCL, val, sizeof(one));
retval = setsockopt(sid, SOL_SOCKET, SO_MARK, val, sizeof(one));
The first of these tells the kernel that I have the headers already, so no need to try and create them. The second tells the kernel to put a mark value of 1 on every packet sent via the socket, which I can match against in routing or iptables rules.
Later, I built a destination address and used sendto() to send the packet:
retval = sendto(sid, pL3, len, 0, (struct sockaddr *)&daddr, sizeof(daddr));
Finally, I installed a rule telling netfilter not to do connection tracking on TCP packets marked with a 1. Since I had added the sockopt above so that all of my generated packets had this mark, this worked well:
sudo iptables -t raw -I OUTPUT -p tcp -m mark --mark 1 -j CT --notrack

Wireshark: Call MAC dissector from .lua plugin

I am trying to call specific protocol dissectors from my .lua plugin.
The line is:
Dissector.get("mac"):call(buf, pinfo, tree)
Some work (e.g. gtp) but others I need do not (e.g. mac for MAC, rsl for RSL). I looked at the epan/dissectors folder and tried other variations to no avail.
Anyone knows if the issue is finding the correct name of the protocol, or something else?
Below is the answer I provided to this same question over at https://ask.wireshark.org/question/6288/call-mac-dissector-from-lua-plugin/, but copied here for convenience:
If you're looking for the correct protocol names, you can try running something like tshark -G protocols | grep NAME … where NAME is the name of the protocol you're looking for. (Refer to the tshark man page for more details on the -G option.)
For example:
$ tshark -G protocols | grep RSL
Radio Signalling Link (RSL) RSL gsm_abis_rsl
So in the case of RSL, it looks like you'd need Dissector.get("gsm_abis_rsl"):call(buf, pinfo,tree)
Of course this doesn't always work, because the same search for MAC does find it:
$ tshark -G protocols | grep MAC
DOCSIS Mac Management DOCSIS MAC MGMT docsis_mgmt
MACsec Key Agreement EAPOL-MKA mka
Radio Link Control, Medium Access Control, 3GPP TS44.060 GSM RLC MAC gsm_rlcmac
ISMACryp Protocol ISMACRYP ismacryp
**MAC MAC mac**
MAC-LTE MAC-LTE mac-lte
mac-lte-framed MAC-LTE-FRAMED mac-lte-framed
MAC-NR MAC-NR mac-nr
MikroTik MAC-Telnet Protocol MAC-Telnet mactelnet
MAC Control MACC macc
802.1AE Security tag MACsec macsec
MPLS-MAC Media Access Control (MAC) Address Withdrawal over Static Pseudowire mpls_mac
WiMax MAC Management Message MGMT MSG wmx.mgmt
DCOM IRemoteActivation REMACT remact
Token-Ring Media Access Control TR MAC trmac
WiMax Generic/Type1/Type2 MAC Header Messages WiMax Generic/Type1/Type2 MAC Header (hdr) wmx.hdr
WiMAX MAC-PHY over Ethernet WiMAX MAC-PHY wimaxmacphy
In this case, it seems you need to look at the source code (unless there's some other method I'm not aware of) in order to find the dissector that's actually registered.
$ grep "proto_register_protocol" packet-*.c | grep "\"MAC\""
packet-umts_mac.c: proto_umts_mac = proto_register_protocol("MAC", "MAC", "mac");
$ grep register_dissector packet-umts_mac.c
register_dissector("mac.fdd.rach", dissect_mac_fdd_rach, proto_umts_mac);
register_dissector("mac.fdd.fach", dissect_mac_fdd_fach, proto_umts_mac);
register_dissector("mac.fdd.pch", dissect_mac_fdd_pch, proto_umts_mac);
register_dissector("mac.fdd.dch", dissect_mac_fdd_dch, proto_umts_mac);
register_dissector("mac.fdd.edch", dissect_mac_fdd_edch, proto_umts_mac);
register_dissector("mac.fdd.edch.type2", dissect_mac_fdd_edch_type2, proto_umts_mac);
register_dissector("mac.fdd.hsdsch", dissect_mac_fdd_hsdsch, proto_umts_mac);

Wireshark display filter: host to host

I need to Write a Wireshark display filter to meet the following requirements.
All traffic from host 192.168.12.44 to host 192.168.12.1
I believe it is just
ip.src_host = 192.168.12.44 && ip.dst_host 192.168.12.1
or
ip.src== 192.168.12.44 && ip.dst==192.168.12.1
I'm just not sure which syntax is correct. Can anyone offer any tips/advice? I tried this on two different IPs that i can actually test yet they seem to offer different results, so I'm not sure which one I need.
ip.src & ip.dst are for IP adresses while ip.src_host & ip.dst_host are for their DNS names. Suppose an IP with the address 192.168.1.1 has a corresponding DNS name of mydns.mysite.com. Assuming you have enabled Resolve Network Address under View --> Name Resolution, then ip.src_host will filter mydns.mysite.com while when not enabled ip.src will filter 192.168.1.1
Please refer to this link for more information.

How to get netmask?

I know how to get from ifconfig. (linux)
But is there another way? Can found it in socket.
You need to use IO#ioctl. This is totally non-portable. On my linux box this code words:
require 'socket'
sock = Socket.new(Socket::AF_INET, Socket::SOCK_DGRAM,0)
buf = ["eth0",""].pack('a16h16')
sock.ioctl(0x891b, buf)
netmask = "#{buf[20]}.#{buf[21]}.#{buf[22]}.#{buf[23]}" #=> "255.255.255.240"
Ioctl differs considerably between systems and I had to look through a few system header files to get the right sizes for the [].pack, the location of the address in buf and the numeric value for SIOCGIFBRDADDR (the first argument to ioctl).
If these values don't work for you I can give you more information on how to find them.

Resources