This is a small example on how you can get the MAC address in C both in Linux and Windows. The example searches in fact the MAC address corresponding to a given IP address and returns it.

/*
 * mac.cpp
 *  Created on: May 25, 2010
 *      Author: len
 */

#ifdef WIN32

#include <stdio.h>
#include <Windows.h>
#include <Iphlpapi.h>
#include <Assert.h>
#pragma comment(lib, "iphlpapi.lib")

/**
 * @return the mac address of the interface with the given ip
 */
char* getMAC(const char *ip){
 PIP_ADAPTER_INFO AdapterInfo;
 DWORD dwBufLen = sizeof(AdapterInfo);
 char *mac_addr = (char*)malloc(17);

 AdapterInfo = (IP_ADAPTER_INFO *) malloc(sizeof(IP_ADAPTER_INFO));
 if (AdapterInfo == NULL) {
 printf("Error allocating memory needed to call GetAdaptersinfo\n");
 return NULL;
 }

 // Make an initial call to GetAdaptersInfo to get the necessary size into the dwBufLen variable
 if (GetAdaptersInfo(AdapterInfo, &dwBufLen) == ERROR_BUFFER_OVERFLOW) {
 FREE(AdapterInfo);
 AdapterInfo = (IP_ADAPTER_INFO *) malloc(dwBufLen);
 if (AdapterInfo == NULL) {
 printf("Error allocating memory needed to call GetAdaptersinfo\n");
 return NULL;
 }
 }

 if (GetAdaptersInfo(AdapterInfo, &dwBufLen) == NO_ERROR) {
 PIP_ADAPTER_INFO pAdapterInfo = AdapterInfo;// Contains pointer to current adapter info
 do {
 sprintf(mac_addr, "%02X:%02X:%02X:%02X:%02X:%02X",
 pAdapterInfo->Address[0], pAdapterInfo->Address[1],
 pAdapterInfo->Address[2], pAdapterInfo->Address[3],
 pAdapterInfo->Address[4], pAdapterInfo->Address[5]);
 printf("Address: %s, mac: %s", pAdapterInfo->IpAddressList.IpAddress.String, mac_addr);
 if(strcmp(ip, pAdapterInfo->IpAddressList.IpAddress.String) == 0){
 printf(" matches\n");
 free(AdapterInfo);
 return mac_addr;
 }
 printf("\n");
 pAdapterInfo = pAdapterInfo->Next;        
 }while(pAdapterInfo);                        
 }
 free(AdapterInfo);
 return NULL;
}
#endif

#ifdef linux
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netdb.h>
#include <ifaddrs.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

/**
 * @return the mac address of the interface with the given ip
 */
char *getMAC(const char *ip){
 struct ifaddrs *ifaddr, *ifa;
 int family, s;
 char host[NI_MAXHOST];
 struct sockaddr *sdl;
 unsigned char *ptr;
 char *ifa_name;
 char *mac_addr = (char*)calloc(sizeof(char), 18);

 if (getifaddrs(&ifaddr) == -1) {
 perror("getifaddrs");
 return NULL;
 }

 //iterate to find interface name for given server_ip
 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
 if (ifa->ifa_addr != NULL){
 family = ifa->ifa_addr->sa_family;
 if(family == AF_INET){
 s = getnameinfo(ifa->ifa_addr, (family == AF_INET)?sizeof(struct sockaddr_in):sizeof(struct sockaddr_in6),
 host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
 if (s != 0) {
 printf("getnameinfo() failed: %s\n", gai_strerror(s));
 return NULL;
 }
 printf("address: %s\n", host);
 if(strcmp(host, ip) == 0){
 ifa_name = ifa->ifa_name;
 printf("matching interface name: %s\n", ifa_name);
 }
 }
 }
 }

 //iterate to find corresponding ethernet address
 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
 family = ifa->ifa_addr->sa_family;
 if(family == PF_PACKET && strcmp(ifa_name, ifa->ifa_name) == 0){
 sdl = (struct sockaddr *)(ifa->ifa_addr);
 ptr = (unsigned char *)sdl->sa_data;
 ptr += 10;
 sprintf(mac_addr, "%02x:%02x:%02x:%02x:%02x:%02x", *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5));
 printf("found mac address: %s\n", mac_addr);
 break;
 }
 }
 freeifaddrs(ifaddr);
 return mac_addr;
}
#endif

int main(int argc, char *argv[]){
 char *mac = getMAC(argv[1]);
 if(mac != NULL){
 printf("mac: %s\n", mac);
 }
 return 0;
}

This example mixes various informations found on the net. The windows version is based on this example. In order to compile this example under windows you need to disable the precompiled headers (tested in VC express 2008). The linux version just iterates interfaces and matches the name of the PF_PACKET (ethernet) with AF_INET (TCP) in order to find the mac of a given ip.