issues in Cisco 2960 - networking

I can get the switch status by using oid : .1.3.6.1.2.1.2.2.1.8
This displays all the ports with status up or down.
However, I want an oid to check the particular port, e.g. to check whether the 5th port is up or down.
Also, I want an oid to get the MAC Address & IP which is connected to a port, e.g. the MAC Address & IP of a PC which is connected to port 5.

The data about ports is stored in a MIB table. The table OID is .1.3.6.1.2.1.2.2.1, which means, that to get a specific piece of data you must query:
.1.3.6.1.2.1.2.2.1.X.Y
where X is the item index, and Y is the port index. For example the oid for the description of port 10101 is .1.3.6.1.2.1.2.2.1.2.10101:
$ snmpget -mall -v1 -c public <switch_ip> .1.3.6.1.2.1.2.2.1.2.10101
IF-MIB::ifDescr.10101 = STRING: GigabitEthernet0/1
To get all the data in the ports table you can query it like this:
$ snmpwalk -mall -v1 -c public <switch_ip> .1.3.6.1.2.1.2.2.1
To get MAC addresses on a specific port you can query the FDB in BRIDGE-MIB:
$ snmpwalk -mall -v1 -c public <switch_ip> .1.3.6.1.2.1.17.4.3.1.2
Since switching on 2960 is mostly a layer 2 operation, there is no way to get the corresponding IP addresses, unless you set it up as router.

Related

Perf Sampling - Null Physical Address

While sampling memory loads and stores via Perf, I'm attempting to capture the physical address of the memory location accessed. However, I'm finding that many accesses to kernel space (as determined by their associated virtual addresses) have an associated physical address that is null (i.e., 0x0).
Why are these physical addresses null? Is null reported because the physical address could not be determined? If null is the valid physical address, what does a physical address of null mean?
An easy way to observe this is to run the following:
sudo perf record -e mem_uops_retired.all_loads:p --count 1000 --data --phys-data timeout 2 yes
sudo perf report -i perf.data -D | grep -A2 PERF_RECORD_SAMPLE | grep phys_addr | sort | uniq -c | sort -n
I'm seeing the following:
...
2765 .. phys_addr: 0x100e849b8
3204 .. phys_addr: 0x10c553478
3588 .. phys_addr: 0x10c553480
4148 .. phys_addr: 0x10c5534a8
135328 .. phys_addr: 0x0
I'm running on Ubuntu v20.04.1 with Intel Xeon CPU D-1540.
Looking at the notes associated with the patch introducing physical address sampling:
For kernel direct mapping addresses, the patch uses virt_to_phys to
convert the virtual addresses from DLA to physical address.
For user virtual addresses, __get_user_pages_fast is used to walk the
pages tables for user physical address.
This does not work for vmalloc addresses. Right now these are not
resolved, but code to do that could be added.
Checking the Linux source, the physical address of a vmalloc address still cannot be determined (at the time of this posting). Instead, the physical address returned is null (i.e., 0).

Detect VLAN tagged packets using XDP eBPF

I am trying to detect packets with a VLAN tag. I have some PCAP files to containing VLAN tagged packets to test. A Wireshark screenshot of a sample packet:
After reading some tutorials, I wrote the following code:
#include <linux/bpf.h>
#include <linux/if_ether.h>
#include <linux/in.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_endian.h>
#define bpf_printk(fmt, ...) \
({ \
char ____fmt[] = fmt; \
bpf_trace_printk(____fmt, sizeof(____fmt), \
##__VA_ARGS__); \
})
SEC("xdpvlan")
int myxdpprogram(struct xdp_md *ctx) {
void *data = (void *)(long)ctx->data;
void *data_end = (void *)(long)ctx->data_end;
struct ethhdr *eth = data;
if ((void*)eth + sizeof(*eth) <= data_end) {
bpf_printk("h_proto is: 0x%x, ETH_P_8021Q is: 0x%x\n", bpf_ntohs(eth->h_proto), ETH_P_8021Q);
}
return XDP_PASS;
}
char _license[] SEC("license") = "GPL";
The output in /sys/kernel/debug/tracing/trace is like this:
bpf_trace_printk: h_proto is: 0x800, ETH_P_8021Q is: 0x8100
I expected:
bpf_trace_printk: h_proto is: 0x8100, ETH_P_8021Q is: 0x8100
I am using Fedora 34 to test, kernel version: 5.11.12-300.fc34.x86_64.
Why the h_proto is not equal to 0x8100?
Update
I have two VMs, and I am using tcpreplay to send packets (PCAP file) from one VM to the other VM that has the eBPF program. VMs are connected through a host-only interface. I load the program using:
ip link set dev ens37 xdpgeneric obj xdp_vlan_kern.o sec xdpvlan
[EDIT] Not sure this answer is correct, have a look at the comments for details.
Generic XDP, or SKB-mode XDP, is an XDP mode that was primarily added for experimenting with XDP (and to provide a model for future driver-based implementations). Given that it requires no support from the NIC driver, it is easier to use, but has lower performance than the other modes (driver/native XDP or XDP hardware offload).
One consequence of not having driver support is that the hook for generic XDP is necessarily higher in the networking stack when compared with native XDP. Generic XDP runs after the socket buffer (SKB) has been allocated. This means that some processing may already have occurred on your packets. In your case, the networking stack has already decapsulated the packets from their VXLAN headers, so you just observe regular IP packets.
Switching to driver-level XDP, providing your hardware (or virtual interface) uses a driver that supports it, should allow you to process your packets before they are sent to the kernel stack and before the VXLAN are removed.
I faced the same problem when running xdp in xdpdrv mode.
In this tutorial I found notes about VLAN offloads on NIC interface:
Since XDP needs to see the VLAN headers as part of the packet headers, it is important to turn off VLAN hardware offload (which most hardware NICs support), since that will remove the VLAN tag from the packet header and instead communicate it out of band to the kernel via the packet hardware descriptor. The testenv script already disables VLAN offload when setting up the environment, but for reference, here is how to turn it off for other devices, using ethtool:
# Check current setting:
ethtool -k DEV | grep vlan-offload
# Disable for both RX and TX
ethtool --offload DEV rxvlan off txvlan off
# Same as:
# ethtool -K DEV rxvlan off txvlan off
I tried to use driver-mode as #Qeole, suggested. I created a pair of virtual interfaces because my NIC's driver didn't support driver specific hook.
ip link add dev veth1 type veth peer name veth2
The I loaded the program:
ip link set dev veth1 xdpdrv obj xdp_vlan_kern.o sec xdpvlan
And the replayed the PCAP file (on the same VM):
tcpreplay -i veth2 vlan.pcap
The output was as I expected:
bpf_trace_printk: h_proto is: 0x8100, ETH_P_8021Q is: 0x8100
Roman Sokolov's answer is correct.
Disabling txvlan on the sending side fixed the error.
ip link add veth0 type veth peer name veth1
ip link add link veth0 name veth0.100 type vlan id 100
ip link set veth0 up
ip link set veth1 up
ip link set veth0.100 up
ip addr add 10.100.0.4/24 dev veth0.100
ethtool -K veth0 txvlan off
Attaching ebpf program on veth1 using SKB mode, injecting packets into veth0.100 (simply run arping would be enough), then I can get packets with vlan tags in my ebpf program.
However it didn't solve the problem when I only disable rxvlan on veth1.
I didn't test this on a physical device yet, I'll try it later and modify this answer.

Serial communication between QEMU host and guest

I'm trying to set up a pair of serial ports between my QEMU host (Debian Jessie x86_64) and guest (also Debian Jessie, but on ARM). Everything except the serial port part works.
I'm really new to QEMU so there might be a better way but I've tested the following flags when running QEMU:
-chardev tty,id=mytty,path=/dev/pts/2 (/dev/pts/2 & 3 are up with socat)
-chardev pty,id=mypty QEMU opens a PTY but when I try to read or write from host get permission denied.
In either case I can't find the ports in my guest. /dev/pts is empty and in /dev there are only tty and ttyAMA3. So, my problem is setting up communication in general and I'm especially curious on where the ports are on my guest.
I found a solution to my own question. First the device tree was incomplete so I needed to add 3 additional uart ports. That's the reason I could not find my ports in the guest.
Second, I needed to tell QEMU to use on of the ports as stdio: -append ... console=ttyAMA3 and -serial mon:stdio. Then I'm able to, with -serial pty, link QEMUs ttyAMA* to pts/* on the host.

How can I test an outbound connection to an IP address as well as a specific port?

OK, we all know how to use PING to test connectivity to an IP address. What I need to do is something similar but test if my outbound request to a given IP Address as well as a specif port (in the present case 1775) is successful. The test should be performed preferably from the command prompt.
Here is a small site I made allowing to test any outgoing port. The server listens on all TCP ports available.
http://portquiz.net
telnet portquiz.net XXXX
If there is a server running on the target IP/port, you could use Telnet. Any response other than "can't connect" would indicate that you were able to connect.
To automate the awesome service portquiz.net, I did write a bash script :
NB_CONNECTION=10
PORT_START=1
PORT_END=1000
for (( i=$PORT_START; i<=$PORT_END; i=i+NB_CONNECTION ))
do
iEnd=$((i + NB_CONNECTION))
for (( j=$i; j<$iEnd; j++ ))
do
#(curl --connect-timeout 1 "portquiz.net:$j" &> /dev/null && echo "> $j") &
(nc -w 1 -z portquiz.net "$j" &> /dev/null && echo "> $j") &
done
wait
done
If you're testing TCP/IP, a cheap way to test remote addr/port is to telnet to it and see if it connects. For protocols like HTTP (port 80), you can even type HTTP commands and get HTTP responses.
eg
Command IP Port
Telnet 192.168.1.1 80
The fastest / most efficient way I found to to this is with nmap and portquiz.net described here: http://thomasmullaly.com/2013/04/13/outgoing-port-tester/ This scans to top 1000 most used ports:
# nmap -Pn --top-ports 1000 portquiz.net
Starting Nmap 6.40 ( http://nmap.org ) at 2017-08-02 22:28 CDT
Nmap scan report for portquiz.net (178.33.250.62)
Host is up (0.072s latency).
rDNS record for 178.33.250.62: electron.positon.org
Not shown: 996 closed ports
PORT STATE SERVICE
53/tcp open domain
80/tcp open http
443/tcp open https
8080/tcp open http-proxy
Nmap done: 1 IP address (1 host up) scanned in 4.78 seconds
To scan them all (took 6 sec instead of 5):
# nmap -Pn -p1-65535 portquiz.net
The bash script example of #benjarobin for testing a sequence of ports did not work for me so I created this minimal not-really-one-line (command-line) example which writes the output of the open ports from a sequence of 1-65535 (all applicable communication ports) to a local file and suppresses all other output:
for p in $(seq 1 65535); do curl -s --connect-timeout 1 portquiz.net:$p >> ports.txt; done
Unfortunately, this takes 18.2 hours to run, because the minimum amount of connection timeout allowed integer seconds by my older version of curl is 1. If you have a curl version >=7.32.0 (type "curl -V"), you might try smaller decimal values, depending on how fast you can connect to the service. Or try a smaller port range to minimise the duration.
Furthermore, it will append to the output file ports.txt so if run multiple times, you might want to remove the file first.

Cannot bind to IPv6 address

I am facing a strange problem on my Ubuntu Karmic system.
When I call getaddrinfo() with AI_PASSIVE and AF_UNSPEC, for an empty host and the UDP 12000 port to get a bindable address, I only get back one IPv4 result (0.0.0.0:12000 for instance).
If I change my call and specify AF_INET6 instead of AF_UNSPEC, then getaddrinfo() returns "Name or service not known".
Shouldn't I get [::]:12000 as a result ?
The same thing happens if I set the host to ::1.
When I call getaddrinfo() without AI_PASSIVE (to get a "connectable" address) for the host "localhost" and the UDP 12000 port, I first get [::1]:12000 then 127.0.0.1:12000.
So apparently, my system is IPv6 ready (I can ping to both IPv4 and IPv6 addresses, as well as DNS resolution). But how is it that I can't get an IPv6 address to bind to with getaddrinfo() ?
Do you guys have any idea about what could be wrong ?
My OS is Ubuntu Karmic, fresh install without any networking tweaking.
Thank you.
P.S: If you have no idea but still want to help me, you can get this sample program or type:
wget http://people.apache.org/~jorton/gai.c
And give me the result of:
$ ./gai -ap null 12000
My result is:
$ ./gai -ap null 12000
getaddrinfo(NULL, "12000", {.family=AF_UNSPEC, .hints=0|AI_ADDRCONFIG|AI_PASSIVE}) = 0:
family= 2, proto= 6 inet4: addr=0.0.0.0, port=12000
There you can see that I only have one IPv4 result.
This happens on new systems that use eglibc: debian-glibc.
Apparently, there is a bug that requires you to set at least one valid IPv6 address to one of your network interfaces (the loopback doesn't count).
After I did this:
$ sudo ip -6 addr add 2001:660:4701:1001::1 dev eth0
I have:
$ ./gai -ap null 12000
getaddrinfo(NULL, "12000", {.family=AF_UNSPEC, .hints=0|AI_ADDRCONFIG|AI_PASSIVE}) = 0:
family= 2, proto= 6 inet4: addr=0.0.0.0, port=12000
family=10, proto= 6 inet6: addr=::, port=12000, flowinfo=0
I hope this can help someone.

Resources