我正在编写一个代码来从接口读取MAC地址以列出接口及其MAC地址,因为我无法在任何一个socket.h文件中找到AF_LINK定义。
根据互联网资源,我将在下面看到:
#define AF_LINK 18 /* Link layer interface */
但我的bits / socket.h包含:
#define PF_ASH 18 /* Ash. */
.
.
#define AF_ASH PF_ASH
我应该使用PF_ASH代替AF_LINK吗?
以下是我使用AF_LINK的代码部分:
if ((family == AF_LINK) && (ifa->ifa_name[0] == 'e')) {
//This is for extracting interface number from interface name//
char newi[3];
int i, j;
for (i=0, j=0; i < strlen(ifa->ifa_name); i++) {
if (ifa->ifa_name[i] >= '0' && ifa->ifa_name[i] <= '9') {
newi[j++] = ifa->ifa_name[i];
}
}
newi[j] = '\0';
if_num = atoi(newi);
printf("Interface %d : %d\n", k++, if_num);
}
完整代码:
/*
* ethernetsocket.c
*
* Created on: Feb 25, 2015
* Author: tsp3859
*/
#include <arpa/inet.h>
#include <linux/if_packet.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <bits/socket.h>
#include <net/if.h>
#include <netinet/ether.h>
#include <ifaddrs.h>
#define MY_DEST_MAC0 0xff
#define MY_DEST_MAC1 0xff
#define MY_DEST_MAC2 0xff
#define MY_DEST_MAC3 0xff
#define MY_DEST_MAC4 0xff
#define MY_DEST_MAC5 0xff
// Source Ethernet interface
#define DEFAULT_InterFace "eth0"
#define DEFAULT_PayLoad "1.1.10"
// Allocating size to different containers
#define MAX_FRAME_SIZE 1024
#define MAX_PAYLD_SIZE 1000
#define HEADER_SIZE 14
int payLoad_Size = -1;
int frame_Size = -1;
int main(int argc, char *argv[]) {
int sockfd;
struct ifreq if_idx; // destination ethernet (optional)
struct ifreq if_mac; // destination mac address
int tx_len = 0; // header counter
char ifName[IFNAMSIZ]; // interface name
uint8_t header[HEADER_SIZE]; // ethernet header
char dummy_Payload[MAX_PAYLD_SIZE];
int if_num; // interface number, used for genarating VID
/*
* Run as one of the following command
* 1. ./a.out
* 2 ./a.out eth3
* 3. ./a.out eth4 PayLoad
*/
// Get Ethernet interface name from command line (optional)
if (argc > 1) {
if (argc == 2) {
strcpy(ifName, argv[1]);
strcpy(dummy_Payload, DEFAULT_PayLoad);
}
if (argc == 3) {
strcpy(ifName, argv[1]);
if (strlen(argv[2]) > 1000) {
memcpy(dummy_Payload, argv[2], MAX_PAYLD_SIZE);
} else
strcpy(dummy_Payload, argv[2]);
}
} else {
// Default case: All fields are optional
if (argc < 2) {
strcpy(ifName, DEFAULT_InterFace);
strcpy(dummy_Payload, DEFAULT_PayLoad);
}
}
//Getting interface number
struct ifaddrs *ifaddr, *ifa;
int family, s, n;
if (getifaddrs(&ifaddr) == -1) {
perror("getifaddrs");
exit(EXIT_FAILURE);
}
int k = 1; // Interface SNo.
for (ifa = ifaddr, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++) {
if (ifa->ifa_addr == NULL)
continue;
family = ifa->ifa_addr->sa_family;
if ((family == AF_INET || family == AF_INET6) && (ifa->ifa_name[0] == 'e')) {
char newi[3];
int i, j;
for (i=0, j=0; i < strlen(ifa->ifa_name); i++) {
if (ifa->ifa_name[i] >= '0' && ifa->ifa_name[i] <= '9') {
newi[j++] = ifa->ifa_name[i];
}
}
newi[j] = '\0';
if_num = atoi(newi);
printf("Interface %d : %d\n", k++, if_num);
}
}
// Setting frame size
payLoad_Size = strlen(dummy_Payload);
// Setting payload, contains VID
char payLoad[payLoad_Size];
//memcpy(payLoad,dummy_Payload,payLoad_Size);
int len=0;
payLoad[len++]=1;
payLoad[len++]=1;
payLoad[len]=10;
frame_Size = HEADER_SIZE + strlen(payLoad);
//printf("Payload size is %d\n ", payLoad_Size);
printf("Frame size is %d\n ", frame_Size);
printf("Payload size is %d\n\n ", strlen(payLoad));
payLoad_Size=strlen(payLoad);
// creating frame
uint8_t frame[frame_Size];
struct ether_header *eh = (struct ether_header *) header;
struct sockaddr_ll socket_address;
// Open RAW socket to send on
if ((sockfd = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW)) == -1) {
perror("Socket Error");
}
memset(&if_idx, 0, sizeof(struct ifreq));
strncpy(if_idx.ifr_name, ifName, IFNAMSIZ - 1);
if (ioctl(sockfd, SIOCGIFINDEX, &if_idx) < 0)
perror("SIOCGIFINDEX - Misprint Compatibility");
memset(&if_mac, 0, sizeof(struct ifreq));
strncpy(if_mac.ifr_name, ifName, IFNAMSIZ - 1);
if (ioctl(sockfd, SIOCGIFHWADDR, &if_mac) < 0)
perror(
"SIOCGIFHWADDR - Either interface is not correct or disconnected");
// Initializing the Ethernet Header
memset(header, 0, HEADER_SIZE);
// Print-test initial header
printf("Zeros: %02x:%02x:%02x:%02x:%02x:%02x %02x:%02x:%02x:%02x:%02x:%02x %02x:%02x\n",
header[0], header[1], header[2], header[3], header[4], header[5],
header[6], header[7], header[8], header[9], header[10], header[11],
header[12], header[13]);
/*
* Ethernet Header - 14 bytes
*
* 6 bytes - Source MAC Address
* 6 bytes - Destination MAC Address
* 2 bytes - EtherType
*
*/
eh->ether_shost[0] = ((uint8_t *) &if_mac.ifr_hwaddr.sa_data)[0];
eh->ether_shost[1] = ((uint8_t *) &if_mac.ifr_hwaddr.sa_data)[1];
eh->ether_shost[2] = ((uint8_t *) &if_mac.ifr_hwaddr.sa_data)[2];
eh->ether_shost[3] = ((uint8_t *) &if_mac.ifr_hwaddr.sa_data)[3];
eh->ether_shost[4] = ((uint8_t *) &if_mac.ifr_hwaddr.sa_data)[4];
eh->ether_shost[5] = ((uint8_t *) &if_mac.ifr_hwaddr.sa_data)[5];
eh->ether_dhost[0] = MY_DEST_MAC0;
eh->ether_dhost[1] = MY_DEST_MAC1;
eh->ether_dhost[2] = MY_DEST_MAC2;
eh->ether_dhost[3] = MY_DEST_MAC3;
eh->ether_dhost[4] = MY_DEST_MAC4;
eh->ether_dhost[5] = MY_DEST_MAC5;
eh->ether_type = htons(0x8010);
tx_len += sizeof(struct ether_header);
// Copying header to frame
memcpy(frame, header, 14);
// Copying payLoad to frame
//printf("Payload: %d\n", payLoad[1]);
memcpy(frame + 14, payLoad, strlen(payLoad));
// Printing initial frame
printf(" Frame: %02x:%02x:%02x:%02x:%02x:%02x %02x:%02x:%02x:%02x:%02x:%02x %02x:%02x\n",
frame[0], frame[1], frame[2], frame[3], frame[4], frame[5],
frame[6], frame[7], frame[8], frame[9], frame[10], frame[11],
frame[12], frame[13]);
// Printing payLoad
printf("Payload: %d.%d.%d\n", frame[14],frame[15],frame[16]);
// Index of the network device
socket_address.sll_ifindex = if_idx.ifr_ifindex;
// Address length - 6 bytes
socket_address.sll_halen = ETH_ALEN;
// Destination MAC Address
socket_address.sll_addr[0] = MY_DEST_MAC0;
socket_address.sll_addr[1] = MY_DEST_MAC1;
socket_address.sll_addr[2] = MY_DEST_MAC2;
socket_address.sll_addr[3] = MY_DEST_MAC3;
socket_address.sll_addr[4] = MY_DEST_MAC4;
socket_address.sll_addr[5] = MY_DEST_MAC5;
// Send packet
if (sendto(sockfd, frame, tx_len + strlen(payLoad), 0,
(struct sockaddr*) &socket_address, sizeof(struct sockaddr_ll)) < 0)
printf("Send failed\n");
freeifaddrs(ifaddr);
exit(EXIT_SUCCESS);
return 0;
}