Find out MAC address on Linux&FreeBSD in C - c

I am trying to find out MAC address and I managed to create working solution using sysctl in Linux, problem is, that this solution is not working on FreeBSD version I am developing on. Is there any way I can find out mac address in C other than using sysctl?

Use the libpcap library. Its the most multi platform way you can find.
This library is used on network sniffers and intrusion detections, as well as dedicate measuring other network statistics. The nethogs utility to measure per process network usage, the iftop used to measure per machine/port bandwidth usage. Is very flexible in many roles.
Is written in C but there are some wrappers for other languages.
1: http://en.wikipedia.org/wiki/Pcap
[2]: http://www.tcpdump.org
[3]: http://sourceforge.net/projects/libpcap/
Edit:
here is a complete and exact and working example with the code and functions detailed:
http://coderrr.wordpress.com/2008/03/07/get-the-mac-address-of-a-local-ip/
There are plenty of tutorials and the source code is your best friend.
Edit 2: blaze pointed out getifaddrs(3) which seems to do the job, just a few caveats, its a non-posix function. Is a bsd function which glibc linux supports but do NOT documents. Is almost an undocumented featured :-)
All documentation are man pages and from the manual at kernel.org:
Not in POSIX.1-2001. This function first appeared in BSDi and is
present on
the BSD systems, but with slightly different semantics documented--returning
one entry per interface, not per address. This means ifa_addr and other
fields can actually be NULL if the interface has no address, and no link-level
address is returned if the interface has an IP address assigned. Also, the
way of choosing either ifa_broadaddr or ifa_dstaddr differs on various
systems.
and
The addresses returned on Linux will usually be the IPv4 and IPv6
addresses
assigned to the interface, but also one AF_PACKET address per interface
containing lower-level details about the interface and its physical layer. In
this case, the ifa_data field may contain a pointer to a struct
net_device_stats, defined in , which contains various
interface attributes and statistics.
So it may vary in behavior and you'll may have to #ifndef compile anyway.
The kernel.org man page at http://www.kernel.org/doc/man-pages/online/pages/man3/getifaddrs.3.html does provides example code in it, which may be helpful. My local linux man page is rather poor in comparison to the above linked.
I still think that libpcap is more portable if only because someone else had done all the portability work and all the extra features you gain by using it.
Hope this helps.

getifaddrs(3) returns IP addresses and MAC addresses on local interfaces. Portable between Linux and FreeBSD.

Related

Why do both fstat(2) and fstat(3) exist and which one should I use?

I was trying to read the man page for fstat, and I got fstat(2), fstat(3) and fstat(3P).
Having in the past used a system (2) command, I know the difference is that I have to write a prototype myself to announce the function (which is reflected in the fstat(2) man page).
But never have I seen that a function is both a C function (3) and a system function (2) at the same time. What would be the benefit of using one over the other? How would C even differentiate whether I am using (2) or (3).
Also, I understand that sys/stat.h is platform specific, so which of (2) and (3) would be safer to use for cross-platform? Since I don't see a prototype line in the Windows page example, I assume it is a (3)
Please explain this to be because I cannot wrap my head around why both would exist.
Web-based manpages are always a second-best option, since they can only show you a generic view of the interfaces. If you use the man command on your own system (at least for Unix-like systems), the result should reflect your actual installation, assuming you've correctly installed the documentation for your distribution.
Section 2 of the manual is intended for the description of system calls rather than standard library APIs. However, at least in the case of Linux documentation, section 2 is also used to describe the library wrappers around the system calls, which effectively documents the particular features implemented by the standard C library, normally glibc. In such cases, section 3P is used to document the to contain documentation extracted or adapted from the Posix standard. So if you want to write portable code, use only the features documented in section 3P. If you are happy to use all the extensions available to you on your system, use section 2.
man7.org and linux.die.net use different manpage repositories; on the latter, section 3P doesn't exist and the Posix programming manual is found in section 3. So https://www.man7.org/linux/man-pages/man3/fstat.3p.html and https://linux.die.net/man/3/fstat contain the same information. If you use a linux distribution, you'll probably find that man 3 fstat actually gives you the page from section 3p.
In any event, there is only one interface in the C library, which should conform to the Posix standard, but may extend it.

Zero is usually right for a protocol?

I have been going through the GNU, libc manual on using the sockets. As per to the documentation here
Exact wording from the documentation is,
zero is usually right for protocol.
I have seen several examples of code where engineers have put 0 for the protocol when implementing a socket regardless of the protocol in use!
int socket (int namespace, int style, int protocol)
May I know, What does the author mean by above statement ? I could sense that there are situations in which 0 might not be the correct answer as per to the author's statement, If so, would it be possible for someone to elaborate on such scenarios ? Most importantly where do we get the value for protocol ? Is there any standard to refer to for protocol numbers ?
The valid values for protocol is dependent on the namespace used and the kernel the program is running on.
I assume, since the question is tagged gnu, that you are running under linux. You may then find a list of valid namespaces, and links to documentation of those namespaces with man 'socket(2)'. For instance, you may find documentation for the internet namespaces AM_INET and AM_INET6 under man 'ip(7)' and man 'ipv6(7)'
Reading the ip(7) manpage you may then see that AM_INET supports protocols IPPROTO_TCP and IPPROTO_SCTP for stream sockets, and IPPROTO_UDP and IPPROTO_UDPLITE for datagram sockets.
If you want to dig further, the different protocols also have their own manpages

Get List of Time Zones Across Platforms in C

I am developing a program in C which needs to return an array of strings of all of the possible regions the computer has access to information from (ostensibly from tz database). I need to make this cross-platform between Linux (or at least Ubuntu) and Windows, so any common approaches between the two platforms would make my life much easier. I am aware of a few ways to do it on Windows (through the registry, or the approach described here http://msdn.microsoft.com/en-us/library/ms171251(v=sql.90).aspx), but I haven't been able to find any way of doing this in Linux besides hard coding an array in. What would be the best way to accomplish this in Ubuntu, and is there a better way in Windows than the two I mentioned above?
Dave, the contents of the zoneinfo directory is consistent not only across Linux distros, but also across many (most) other Unices.
The exact location may be different in some cases (I know only one: on Linux, many-many years ago it used to be under /usr/lib/zoneinfo, when there was no such thing as /usr/share), so it should be configurable in your app. But you can use /usr/share/zoneinfo as a default, and it'll work in 99.9% of the cases.
In Linux, would walking the contents of /usr/share/zoneinfo be sufficient?
There is a C++ library (I know you said C but you can write a wrapper...) called ICU which has all the necessary functions to load the list of timezones.
http://icu-project.org/apiref/icu4c/classTimeZone.html
Look for this function to get a complete list (other functions can be used if you'd like to filter the list in some ways):
/**
* Returns an enumeration over all recognized time zone IDs. (i.e.,
* all strings that createTimeZone() accepts)
*
* #return an enumeration object, owned by the caller.
* #stable ICU 2.4
*/
static StringEnumeration* U_EXPORT2 createEnumeration();

Implementation of system calls / traps within Linux kernel source

I'm currently learning about operating systems the use of traps to facilitate system calls within the Linux kernel. I've located the table of the traps in traps.c and the implementation of many of the traps within entry.S.
However, I'm instructed to find an implementation of two system calls in the Linux kernel which utilize traps to implement a system call. Although I can find the definition of the traps themselves, I'm not sure what a "call" to one of these traps within the kernel would look like. Therefore, I'm struggling to find an example of this behavior.
Before anyone asks, yes, this is homework.
As a note, I'm using Github to browse the kernel source, since kernel.org is down:
https://github.com/torvalds/linux/
For the x86 architecture the SYCALL_VECTOR (0x80) interrupt is used only for 32bit kernels. You can see the interrupt vector layout in arch/x86/include/asm/irq_vectors.h. The trap_init() function from traps.c is the one that sets the trap handler defined in entry_32.S:
set_system_trap_gate(SYSCALL_VECTOR, &system_call);
For the 64bit kernels, the new SYSENTER (Intel) or SYSCALL (AMD) intructions are used for performance reasons. The syscall_init() function from arch/x86/kernel/cpu/common.c sets up the "handler" defined in entry_64.S and bearing the same name (system_call).
For the user-space perspetive you might want to take a look at this page (a bit outdated for the function/file names).
I'm instructed to find an implementation of two system calls in the Linux kernel which utilize traps to implement a system call
Every system call utilizes a trap (interrupt 0x80 if I recall correctly) so the "kernel" bit will be turned on in PSW, and privileged operations will be available to the processor.
As you mentioned the system calls are specified in entry.S under sys_call_table: and they all start with the "sys" prefix.
you can find the system call function header in: include/linux/syscalls.h, you can find it here:
http://lxr.linux.no/#linux+v3.0.4/include/linux/syscalls.h
Use lxr (as the comment above have already mentioned) in general in order to browse the source code.
Anyhow, the function are implemented using the SYSCALL_DEFINE1 or othe versions of the macro, see
http://lxr.linux.no/#linux+v3.0.4/kernel/sys.c
If you're looking for an actual system call, not an implementation of a system call, maybe you want to check some C libraries. Why would a kernel include a system call? (I'm not talking about a system call implementation, I'm talking about e.g. an actual chdir call for example. There is a chdir system call, which is a request for changing the directory and there is a chdir system call implementation which actually changes it and must be somewhere in the kernel). Ok, maybe some kernels do include some syscalls too but that's another story :)
Anyway, if I get your question right, you're not looking for an implementation but an actual call. GNU libc is too complicated for me, but you can try browsing the dietlibc sources. Some examples:
chdir.S
syscalls.h

Using the name resolver of resolv.h with IPv6

I write or modify programs which perform name resolution and need a
good control of the process. So I do not use getaddrinfo(), I go
deeper and use res_query() / res_send() / etc in resolv.h, documented
in resolver(3).
Although not documented, the common way to set the resolver used is to
update _res.nsaddr_list. But this array, defined in resolv.h, stores
struct sockaddr_in, that is IPv4 addresses only. (IPv6 addresses
are struct sockaddr_in6, a family-independant system would use struct sockaddr.)
I'm looking for a way (preferrably portable, at least among the
various Unix) to tell _res that I want also IPv6 addresses.
Apparently, a long time ago, there was in FreeBSD a _res_ext with this
ability but I cannot find it anymore in a recent FreeBSD 7 (grep
_res_ext /usr/include/resolv.h finds nothing). You can still find
code which uses it (try yourself with Google Codesearch).
Thanks to Alnitak, I noticed it is apparently now _res._ext and not .res_ext. I wonder where these sort of things are documented or announced... I have no idea how portable _res._ext is. I can find it on Debian and FreeBSD. It seems there are few programs which use it.
Stéphane - if your resolv.h doesn't include any support for sockaddr_in6 then that suggests that on your particular O/S the resolver does not itself support IPv6 transport.
I've checked some of my systems here:
MacOS X 10.5.6 - supports the BIND 9 library, which has a res_setservers() function which can take IPv6 addresses, no _res._ext extension.
CentOS 5.2 - has the _res._ext extension, although there's no mention of IPv6 in the man page for resolv.conf except that there's a setting to tell the resolver to return AAAA records before looking for A records for gethostbyname().
EDIT - also, the CVS repository for FreeBSD suggests that FreeBSD 7.0 (see tag FREEBSD_7_0_0_RELEASE) does also support res_setservers() from Bind 9.
glibc:
res_setservers: no
__res_state._u._ext.nsaddrs
__res_state._u._ext.nsmap
set the latter to MAXNS+1 according to:
http://sourceware.org/ml/libc-hacker/2002-05/msg00035.html
BSD-libc:
res_setservers: yes
__res_state._u._ext.__res_state_ext
Seems messy to me and you'll probably need autoconf.

Resources