I'm newbie to BSD socket programming in C. I can query a web address to get its associated ip addresses with "getaddrinfo" function. But i want to know which dns server getaddrinfo queries this information from.
If you are on linux or a unix platform, try looking at man -k resolver and look for the resolver man page or a page for functions like res_init, res_search, et. al. Those are the unix APIs to DNS, and it looks like, while there's no direct way to do what you want to do, one could glean the information through a combination of the functions and what they return, and doing a few other massaging of data.
With regard to wireshark knowing what's going on, it doesn't really know. It's just monitoring packets as they flow to and fro and printing out what it sees. The resolver is what knows, and that's the API I suggested.
I don't think you can find out which it used, but it uses one from /etc/resolv.conf
If you are on Linux, you can look at the source to 'dig'. Based on it's ability to print out the server address, I think there must be some means to do this other than just parsing the /etc/resolv.conf.
On Windows, there is a very convoluted API for the purpose.
Related
I am familiar with different tools (like netstat, tcpdump, etc.) and files (like /sys/class/net/<dev>/statistics) with which we can get the count.
But can anyone tell me if there is a way of getting that information directly from the kernel, using netlink sockets?
Sure, take a look at IFLA_STATS. You may want to check the ifstat.c file of the iproute2 package, which is pretty much the standard tool to interact with netlink.
This may not be in the right location, so tell me and I'll move it.
I am a recent EE grad and I was hired to build a system that exists on a SoC with a simple 32-bit processor. The system basically monitors several external devices and performs some DSP on it, and then is supposed to send the results using a WiFi device (in my case I have the ESP8266 using UDP) to an email server for logging/notification.
I have been trying to find a library that I can use, but my uC can only program in C and I have it set up for UDP, and everything is in C++ using some other protocol, or something else completely.
I am great at DSP, decent at SoC's and uC's, but when it come to this email server communication thing I am at a loss.
I have successfully configured everything for the sensors, the datapath, the DSP, and connected the system to my WiFi via UDP, but I have yet to figure out how to send data to any servers.
Could someone help me understand how I should go about this?
I have looked into some simple SMTP commands such as HELO, MAIL, RCPT, DATA, etc. but I cannot understand how I actually should implement them in my code.
When I send out the WiFi data via UDP what type of data do I send and how do I format it? Do I need to send any other kind of flags? How should I expect the response? I also know the data has to be transformed into base 64 which is confusing me further.
I am also not super familiar with UDP to begin with, I have been using libraries that are part of the SoC's default library to connect to my WiFi.
I know these may either seem like obvious or stupid questions but it is were I no longer have any knowledge, and everything I find online doesn't make sense, or doesn't attempt to explain it, just gives a pre-made solution
I have found the RFC2821 but it doesn't get any clearer.
I know that's a lot but any help at all would be a lifesaver!
Since you are asking this question, I'm assuming that you are not booting and running an OS suitable for micro-controllers such as an embedded variant of Linux or such. If you were, you would simply be able to take advantage of possibly built in applications or other existing code.
But you don't mention having written an Ethernet stack, so are you using some other library or operating environment which might have some of the functionality needed for an implementation of SMTP?
If you don't and really do need to write your own SMTP client to run directly on the processor you are using, then you should be able to find plenty of examples of source code for this. A quick google search of How To Write an SMTP client showed a few articles with some example code. One article seems to be an exact hit, but you need to look at it further.
However, I would highly suggest just sitting down with a telnet client and connect to an SMTP server you are allowed to use and try the commands you need to just send a message. If you only need to send text, you don't need to get involved in MIME encoding or anything like that.
To get destination derive from an host name or to apply destination address selection algorithm (as per RFC 3484) we have an library api getaddrinfo(). If you search on net you would find that the same API could be used for Source address selection. But when i tested it practically it's not happening.
When i did some homework on it found that in linux the kernel itself decides the appropriate source address depending upon the destination address by applying those rules (as per RFC 3484). This is done by kernel in fib6_rule_action() method this is done while sending the data (e.g. in sendto()).
My question is there any library API or system call which could do this for me at earlier stage meaning before sending data.
You can get that information via linux routing sockets aka rtnetlink. Specifically it is the RTA_SRC you are looking for.
A word of warning, (rt)netlink sockets are not the easiest protocol to use and there is not much up to date documentation besides the source code. The wikipedia page for netlink might get you started. Some of the External Links seem good and the linked paper contains more references.
I suggest using a library, if you can find one and your netlink related code is any longer than the single source address query. Libnl or libmnl might be good. The former also has a nice page about routing sockets.
As a test, you can get the same functionality with the user space command ip -6 route get <dst_addr> eg ip -6 route get 2a00:1450:4010:c04::63.
I want to get in the middle of packet forwarding (Not routing). For example, the system is a layer 2 bridge between hosts and their gateway. I want to check the layer 7 for string or whatever "foo" and forward/drop/delay the packet based on the result. What I am having trouble with is intercepting the packet.
What I have read so far:
I know I can get the copy of packet from BPF device (Usenix paper by Steven McCanne and Van Jacobson http://www.tcpdump.org/papers/bpf-usenix93.pdf ). that's good for sniffing but not for me.
I can access the PF device and set the filtering rules which is good for forwarding or dropping decisions, but not for inspection. man pf (4)
I can get packets into the ALTQ queues, BUT I do not know how to access the individual packets located in the queue. man altq(9)
I have also looking into the source code for PF(/usr/src/sys/contrib/pf/net ), PFCTL (/usr/src/contrib/pf/pfctl) and ALTQ(/usr/src/sys/contrib/altq/altq).
On FreeBSD 9.1 machine
I am not C expert, but I am good with it.
Maybe I am getting tired today with all the reading and missed something trivial. Please forgive me if so. Plus, this will be a very good find fro those looking into the subject.
P.S. There is a way of controlling the flow of "foo", by detecting "foo" in packet and denying the answer to that from coming back by setting up the filter for answer to that request. This is NOT what I am trying to achieve. I do not want the packet to leave the system if it should not.
EDIT 2 P.S. There is a great way of doing this on Linux. I can achieve everything I mentioned here on Linux with libnetfilter_queue. I will not bother posting solution here because there are many many many tutorials on how to do it on Linux.
In conclusion, I am still looking for answer on how to do this on BSD. As far as I can understand, I need to write a wrapper/library based on pf (because there is no such thing on the net - otherwise I should have found it already), that does the same thing as libnetfilter with it's libnetfilter_queue library. Or I could somehow dig into libnetfilter and port it to FreeBSD, but since it is based on iptables, only thing I can get from digging into libnetfilter library is logic and algorithms not the actual code itself, which by itself could prove to be of no use to me.
FreeBSD 9.1 has an userspace framework for packet access called netmap. It was recently introduced and has an amazing performance scale. It does very simple but powerful thing - just mmaps the NIC buffers to userspace portion of memory and detaches the packet processing from host stack, this was exactly what I needed the rest is on me.
If anyone needs any goods reference for this, please refer to man netmap (4)
Have a look at OpenDPI or nDPI.
Check out the "Divert Sockets" in BSD implementation as well. Unlike Netmap, it is not zero-copy (IMHO) however it can work with ipfw in order to implement the necessary filters in order to filter packages you want to process.
getaddrinfo() is a function we need to use before creating a socket() or connect()ing, right? Then how does getaddrinfo communicate with DNS server in the first place?
PS: Where can I see the complete source of getaddrinfo?
The short answer is "it asks the system", which in turn knows how to do DNS lookups and which servers to use.
getaddrinfo() is documented by the getaddrinfo(3) manual page, which means it's a C library function. It is also a POSIX function, so there is no canonical "source"; each standard C library of an operating system that conforms to POSIX will implement its own version. Either way the source to just that function is probably not too enlightening, since it would just call other functions and OS APIs, and you'd have to drill down pretty far to get to the actual DNS mechanism. You'd be better off reading documentation of the DNS protocol itself if you're interested in how that works.
It is not necessary to call getaddrinfo() before creating a socket or connecting. It is used to translate a domain name, like stackoverflow.com, to an IP address like 69.59.196.211. If you know the IP address then you can connect directly to that address and there is no need to use getaddrinfo(). getaddrinfo() uses the DNS protocol to talk to your name servers, which are configured using their IP address.
The glibc source code is here.
Does your Unix system have the file /etc/nsswitch.conf? If so, then the "hosts" entry gives the search order for resolving hostnames into IP addresses. Does your system have the file /etc/resolv.conf? If so, then it specifies what DNS servers to use.
As you can see, getaddrinfo() can do quite a bit (and can take a while)!
getaddrinfo() likely does make a connect() call behind the scenes, however it already knows the IP address of the DNS server it needs to connect to in order to query for the address of the host you are asking it to query for.
getaddrinfo() is only needed if you want to map "www.somehost.com" to an IP address, it's not needed as a primer to call connect().
You can probably find the complete source code for getaddrinfo() in glibc sources which you'd be able to find here (among other places).
Hope that clarifies things for you.
It is using DNS protocol (UDP)
http://www.freesoft.org/CIE/Topics/77.htm