Get Base address of UART registers - linux-device-driver

I'm using PCI card which opens two serial ports(UART).Developing driver for same.
For doing operation on UART,i need to know base address from where i can shift and access uart configuration register(exa.LCR,IER,LSR,...etc.)
Using which function i can get UART base address? or In datasheer where it is mentioned?
Thank you.

The standard port addresses are:
Standard port addresses are:
COM1 0x3F8 (1016)
COM2 0x2F8 (760)
COM3 0x3E8 (1000)
COM4 0x2E8 (744)
Additional port addresses are:
COM5 0x3E0 (992)
COM6 0x2E0 (736)
COM7 0x338 (824)
COM8 0x238 (568)

This is from the Intel® 82547EI Gigabit Ethernet Controller Data sheet :
10.1.1.1 Memory-Mapped Access to Internal Registers and Memories The internal registers and memories can be accessed as direct
memory-mapped offsets from the Base Address Register 0 (BAR0). The
appropriate offset for each specific internal register is described in
this section.
So I think that your card needs to be enumerated first by U-Boot or Linux.
Then you can access your card internal registers as offsets to the BAR0 address (from U-Boot or Linux).

Related

DPDK forward received packets to default network stack

We're using DPDK (version 20.08 on ubuntu 20.04, c++ application) to receive UDP packets with a high throughput (>2 Mpps). We use a Mellanox ConnectX-5 NIC (and a Mellanox ConnectX-3 in an older system, would be great if the solution worked there aswell).
Contrary, since we only need to send a few configuration messages, we send messages through the default network stack. This way, we can use lots of readily available tools to send configuration messages; however, since all the received data is consumed by DPDK, these tools do not get back any messages.
The most prominent issue arises with ARP negotiation: the host tries to resolve addresses, the clients also do respond properly, however, these responses are all consumed by DPDK such that the host cannot resolve the addresses and refuses to send the actual UDP packets.
Our idea would be to filter out the high throughput packets on our application and somehow "forward" everything else (e.g. ARP responses) to the default network stack. Does DPDK have a built-in solution for that? I unfortunatelly coulnd't find anything in the examples.
I've recently heard about the packet function which allows to inject packets into SOCK_DGRAM sockets which may be a possible solution. I also couldn't find a sample implementation for our use-case, though. Any help is greatly appreciated.
Theoretically, if the NIC in question supports the embedded switch feature, it should be possible to intercept the packets of interest in the hardware and redirect them to a virtual function (VF) associated with the physical function (PF), with the PF itself receiving everything else.
The user configures SR-IOV feature on the NIC / host as well as virtualisation support;
For a given NIC PF, the user adds a VF and binds it to the corresponding Linux driver;
The DPDK application is run with the PF ethdev and a representor ethdev for the VF;
To handle the packets in question, the application adds the corresponding flow rules.
The PF (ethdev 0) and the VF representor (ethdev 1) have to be explicitly specified by the corresponding EAL argument in the application: -a [pci:dbdf],representor=vf0.
As for the flow rules, there should be a pair of such.
The first rule's components are as follows:
Attribute transfer (demands that matching packets be handled in the embedded switch);
Pattern item REPRESENTED_PORT with port_id = 0 (instructs the NIC to intercept packets coming to the embedded switch from the network port represented by the PF ethdev);
Pattern items matching on network headers (these provide narrower match criteria);
Action REPRESENTED_PORT with port_id = 1 (redirects packets to the VF).
In the second rule, item REPRESENTED_PORT has port_id = 1, and action REPRESENTED_PORT has port_id = 0 (that is, this rule is inverse). Everything else should remain the same.
It is important to note that some drivers do not support item REPRESENTED_PORT at the moment. Instead, they expect that the rules be added via the corresponding ethdevs. This way, for the provided example: the first rule goes to ethdev 0, the second one goes to ethdev 1.
As per the OP update, the adapter in question might indeed support the embedded switch feature. However, as noted above, item REPRESENTED_PORT might not be supported. The rules should be inserted via specific ethdevs. Also, one more attribute, ingress, might need to be specified.
In order to check whether this scheme works, one should be able to deploy a VF (as described above) and run testpmd with the aforementioned EAL argument. In the command line of the application, the two flow rules can be tested as follows:
flow create 0 ingress transfer pattern eth type is 0x0806 / end actions represented_port ethdev_port_id 1 / end
flow create 1 ingress transfer pattern eth type is 0x0806 / end actions represented_port ethdev_port_id 0 / end
Once done, that should pass ARP packets to the VF (thus, to the network interface) in question. The rest of packets should be seen by testpmd in active forwarding mode (start command).
NOTE: it is recommended to switch to the most recent DPDK release.
For the current use case, the best option is to make use of DPDK TAP PMD (which is part of LINUX DPDK). You can use Software or Hardware to filter the specific packets then sent it desired TAP interface.
A simple example to demonstrate the same would be making use DPDK skeleton example.
build the DPDK example via cd [root folder]/example/skeleton; make static
pass the desired Physical DPDK PMD NIC using DPDK eal options ./build/basicfwd -l 1 -w [pcie id of DPDK NIC] --vdev=net_tap0;iface=dpdkTap
In second terminal execute ifconfig dpdkTap 0.0.0.0 promisc up
Use tpcudmp to capture Ingress and Egress packets using tcpdump -eni dpdkTap -Q in and tcpdump -enu dpdkTap -Q out respectively.
Note: you can configure ip address, setup TC on dpdkTap. Also you can run your custom socket programs too. You do not need to invest time on TLDP, ANS, VPP as per your requirement you just need an mechanism to inject and receive packet from Kernel network stack.

Can I detect different clients from same IP in TcpConnections?

Can we detect different clients(devices) from same IP on TCPConnection ?
Example :
I have a TCP Server called s1 and I have 2 PCs called p1,p2 and my PCs IP is same (e.g. 1.2.3.4)
when I connect to s1 (my TCP Server) with p1 and p2 (Pc1 and Pc2) can s1(my TCP server) detect these clients with same IP, isn't same device ?
From my understanding you are basically asking to detect different devices behind a NAT, i.e. devices sharing the same external IP address. There is no fully reliable way to do this but one can employ heuristics. Typically these are based on the ID field in the IP header and/or the TCP timestamp option, see for example A Technique for Counting NATted Hosts or Time has something to tell us about Network
Address Translation. One might also try to use passive OS fingerprinting in order to detect if different OS are used (and thus different real or virtual devices) - see Passive Fingerprinting.
None of these heuristics are fully reliable though and they also will not work if the devices are behind a proxy, since in this case the TCP/IP connections visible to the server originate from a single device - the proxy.
Yes you can. The server can ask the operating system for the connection information of client associated with the socket. In 'C' this would look like:
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
new_socket = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c);
if (new_socket<0)
{
perror("accept failed");
return 1;
}
The client sockaddr structure will be filled with the information about the connecting client. The server can look into this to extract the IP Address as a string doing something like:
char *ip = inet_ntoa((struct sockaddr_in *)client.sin_addr);
You can now see if ip matches p1 or p2.

How to capture only traffic sent or destined to the local machine using WinPCAP?

I want to only capture the traffic sent or destined to my local machine (no promiscuous mode). Nevertheless, broadcast traffic should also be captured.
So, the question is how to open the adapter? Which flags should be used? There is no specific flag for this kind of capture. I only found the following flags:
#define PCAP_OPENFLAG_PROMISCUOUS 1
// Defines if the adapter has to go in promiscuous mode.
#define PCAP_OPENFLAG_DATATX_UDP 2
// Defines if the data trasfer (in case of a remote capture) has to be done with UDP protocol.
#define PCAP_OPENFLAG_NOCAPTURE_RPCAP 4
// Defines if the remote probe will capture its own generated traffic.
#define PCAP_OPENFLAG_NOCAPTURE_LOCAL 8
// Defines if the local adapter will capture its own generated traffic.
#define PCAP_OPENFLAG_MAX_RESPONSIVENESS 16
// This flag configures the adapter for maximum responsiveness.
So, should I open the adapter in promiscuous mode and set an appropriate filter? Or is there a better possibility to achieve this goal (better in terms of less processing by the WinPCAP capture driver)?
Thanks for clarification!
jonas
I want to only capture the traffic sent or destined to my local machine (no promiscuous mode).
Then don't turn promiscuous mode on.
Nevertheless, broadcast traffic should also be captured.
Broadcast traffic will always be captured (unless you specify a filter, such as !broadcast, that explicitly filters it out).

How does a socket know which network interface controller to use?

If a computer has multiple network cards, all of them connected to different networks and functioning properly, when we open a socket, how does the OS determine which NIC to use with this socket? Does the socket API allow us to explicitly specify the NIC that is to be used?
I'm writing this from a Linux perspective, but I suppose it applies everywhere.
The decision is made when the socket is bound. When bind is called, the address you specify determines the interface the socket will listen on. (Or even all interfaces.)
Even if you don't use bind, it happens implicitly when you connect. The destination is looked up in the route table, which must contain a route to the destination network. The route also contains the interface to use and can optionally even specify the source address. If no source address is specified, the primary address of the interface is taken.
You can actually use bind together with connect, to force your outgoing connection to use a specific address and port. A socket must always have these two bits of information, so even when you don't, the primary address is used and a random port are chosen.
I dont know why im included in the edit suggestion when i was not even related to this question .I got similar edit suggestion before as well..might be some bug/issue.
(If you feel inclined to up-vote, #Shtééf's answer deserves it more than mine.)
That depends on whether you are connecting or binding.
If you bind, you can bind to a specific IP address corresponding to one of the machine's interfaces, or you can bind to 0.0.0.0, in which case the socket will listen on all interfaces.
If you connect an unbound socket, then the machine's routing tables, in conjunction with the destination IP adress, will determine which interface the connection request goes out on.
It is possible to bind a socket then connect it. In this case, the socket will remain bound as per the bind call when it makes the connection. (Thanks to #RemyLebeau for pointing this out.)
I'm not really sure which method is the best, but there is an alternative theory to the bind()-before-connect() approach that Shtééf presented. It's to use setsockopt() with SO_BINDTODEVICE . See: http://codingrelic.geekhold.com/2009/10/code-snippet-sobindtodevice.html
As an alternative, you can search for the appropriate nic based on its name:
//Find the ip address based on the ethernet adapter name. On my machine the ethernet adapter is "Ethernet"
System.Net.NetworkInformation.NetworkInterface[] nics = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
System.Net.NetworkInformation.NetworkInterface ethernet = nics.Where(n => n.Name.Equals("Ethernet")).Single();
UnicastIPAddressInformation uniCastIPAddressInformation = ethernet.GetIPProperties().UnicastAddresses.Where(a => a.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).Single();
IPEndPoint localEndPoint = new IPEndPoint(uniCastIPAddressInformation.Address, 9000);
//Create a TCP/IP socket.
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//Bind and start listening
listener.Bind(localEndPoint);
listener.Listen(10);

How to detemine which network interface (ip address) will be used to send a packet to a specific ip address?

I'm writing a SIP stack, and I need to insert an ip address in the message. This address needs to be the one used for sending the message. I know the destination IP and need to determine the NIC (its address) that will be used to send the message....
To expand a bit on Remy Lebeau's comment, GetBestInterfaceEx() is your best bet, if you're on Windows XP or newer. That will work for both IPv4 and IPv6 addresses.
GetBestInterface/GetBestInterfaceEx return the index (call it IDX) of the most appropriate interface to use to contact some address.
Then you can map that index into a local IP address by getting your interface<->IP address mapping using GetIpAddrTable or GetAdaptersAddresses if you're dual-stacking (supporting both IPv6 and IPv4).
Iterate over that table and find the interface with the dwIndex (or IfIndex, in the case of GetAdaptersAddresses) matching IDX.
It's usually best to allow the IP address your SIP stack will operate on to be set as an adjustable configuration option. It means the user will need to set a configuration option but at least your stack will know the IP address it's operating on.
If that's not feasible then an approach you could use is to send out the SIP request on all IP addresses using a dummy value in the Via header such as 0.0.0.0 and set the interface you get a response back on as the default one. This approach alos as the advantage that the SIP response will tell you the public IP address the request was received from which can be useful if your SIP stack is behind a NAT.
Over TCP, I think you can get the address of the local side of the socket after connect(). I don't know if the same is true for UDP (I suspect not), but it might be worth a try.
The socket will allow you to Bind to a local endpoint before calling connect (both UDP and TCP).
That is all ok if you know the port. However, if you want the port to be ephemeral (e.g. some random port number) then you must come up with your own algorithm to do so and robust code to handle the cases where the port is exclusivly taken by another application.