root@dlrc-desktop:/home/dlrc/dlsp-ep9302/work/mystar-v0.4# cat /proc/net/dev Inter-| Receive | Transmit face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop lo: 472252 1696 0 0 0 0 0 0 472252 1696 0 0 0 0 0 0 eth1:20826443 20156 0 0 0 0 0 0 926357 14613 0 0 0 0 0 0
struct ifreq ifr; strncpy(ifr.ifr_name, name, 6); if (ioctl(sock, SIOCGIFHWADDR, &ifr) < 0){ perror("get_hwaddr ioctl:"); close(sock); return -1; }
/** * get_hwaddr - get netdevice mac addr * @name: device name, e.g: eth0 * @hwaddr: where to save mac, 6 byte hwaddr[6] * @return: 0 on success, -1 on failure */ int get_hwaddr(char *name, unsigned char *hwaddr) { struct ifreq ifr; unsigned char memzero[6]; int sock; if(name == NULL || hwaddr == NULL){ printf("get_hwaddr: NULL para\n"); return -1; } sock = socket(AF_INET, SOCK_STREAM, 0); if(sock < 0){ printf("get_hwaddr: socket error\n"); //return -1; } //get eth1 mac addr memset(hwaddr, 0, 6); memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, name, 6); if (ioctl(sock, SIOCGIFHWADDR, &ifr) < 0){ perror("get_hwaddr ioctl:"); close(sock); return -1; } else { memcpy(hwaddr, ifr.ifr_hwaddr.sa_data, 6); //printf("hwaddr: %2x : %2x : %2x : %2x : %2x : %2x\n", hwaddr[0], hwaddr[1],hwaddr[2], hwaddr[3],hwaddr[4], hwaddr[5]); } memset(memzero, 0, 6); if(memcmp(memzero, hwaddr, 6) == 0){ printf("no mac\n"); return -1; } close(sock); return 0; }
int sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); if(sock < 0){ perror("sock"); return -1; }
struct sockaddr_ll sll; memset(&sll, 0, sizeof(sll)); sll.sll_ifindex = 2; // 指定网卡 if (sendto(sock, packet_start, sizeof packet_start, 0, &sll, sizeof(sll)) < 0){ perror("sendto"); return 1; }
ret = recvfrom(sock, buf, 1024, 0, NULL, NULL);
以下是一个简单的实现,运行两个实例,一个带参数,用于发送数据包。一个不带参数,用于接收数据包。完整的源码在最下面:
/* * socket.c * * Copyright (C) 2011 crazyleen <[email protected]> * */ #include <sys/socket.h> #include <string.h> #include <sys/types.h> #include <arpa/inet.h> #include <features.h> /* for the glibc version number */ #if __GLIBC__ >= 2 && __GLIBC_MINOR >= 1 #include <netpacket/packet.h> #include <net/ethernet.h> /* the L2 protocols */ #else #include <asm/types.h> #include <linux/if_packet.h> #include <linux/if_ether.h> /* The L2 protocols */ #endif #include <stdio.h> #include <netinet/in.h> #include <net/if.h> #include <sys/ioctl.h> #include <errno.h> #define _PATH_PROCNET_DEV "/proc/net/dev" static char *get_name(char *name, char *p) { while (isspace(*p)) p++; while (*p) { if (isspace(*p)) break; if (*p == ':') { /* could be an alias */ char *dot = p, *dotname = name; *name++ = *p++; while (isdigit(*p)) *name++ = *p++; if (*p != ':') { /* it wasn't, backup */ p = dot; name = dotname; } if (*p == '\0') return NULL; p++; break; } *name++ = *p++; } *name++ = '\0'; return p; } /** * read_netdev_proc - read net dev names form proc/net/dev * @devname: where to store dev names, devname[num][len] */ static int read_netdev_proc(void *devname, const int num, const int len) { FILE *fh; char buf[512]; int cnt = 0; char *dev = (char *)devname; if(devname == NULL || num < 1 || len < 4){ printf("read_netdev_proc: para error\n"); return -1; } memset(devname, 0, len * num); fh = fopen(_PATH_PROCNET_DEV, "r"); if (!fh) { fprintf(stderr, "Warning: cannot open %s (%s). Limited output.\n", _PATH_PROCNET_DEV, strerror(errno)); return -1; } fgets(buf, sizeof buf, fh); /* eat two line */ fgets(buf, sizeof buf, fh); cnt = 0; while (fgets(buf, sizeof buf, fh) && cnt < num) { char *s, name[IFNAMSIZ]; s = get_name(name, buf); strncpy(devname, name, len); devname += len; printf("get_name: %s\n", name); } if (ferror(fh)) { perror(_PATH_PROCNET_DEV); } fclose(fh); return 0; } /** * get_hwaddr - get netdevice mac addr * @name: device name, e.g: eth0 * @hwaddr: where to save mac, 6 byte hwaddr[6] * @return: 0 on success, -1 on failure */ int get_hwaddr(char *name, unsigned char *hwaddr) { struct ifreq ifr; unsigned char memzero[6]; int sock; if(name == NULL || hwaddr == NULL){ printf("get_hwaddr: NULL para\n"); return -1; } sock = socket(AF_INET, SOCK_STREAM, 0); if(sock < 0){ printf("get_hwaddr: socket error\n"); //return -1; } //get eth1 mac addr memset(hwaddr, 0, 6); memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, name, 6); if (ioctl(sock, SIOCGIFHWADDR, &ifr) < 0){ perror("get_hwaddr ioctl:"); close(sock); return -1; } else { memcpy(hwaddr, ifr.ifr_hwaddr.sa_data, 6); //printf("hwaddr: %2x : %2x : %2x : %2x : %2x : %2x\n", hwaddr[0], hwaddr[1],hwaddr[2], hwaddr[3],hwaddr[4], hwaddr[5]); } memset(memzero, 0, 6); if(memcmp(memzero, hwaddr, 6) == 0){ printf("no mac\n"); return -1; } close(sock); return 0; } unsigned char packet_start[]={ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,//dst mac 0x00, 0x23, 0x54, 0x0e, 0xe5, 0xd8,//src mac 0x88, 0x8e, //Type: 802.1x authentication 0x01, //Version:v1 0x01, //Type: Start (1) 0x00, 0x00//Length 0 }; void printhex(void *hex, int len, char *tag) { int i; unsigned char *p = (unsigned char *)hex; if(len < 1) return; for(i = 0; i < len - 1; i++){ if(*p < 0x10) printf("0%x%s", *p++, tag); else printf("%2x%s", *p++, tag); } if(*p < 0x10) printf("0%x\n", *p++); else printf("%2x\n", *p++); } int main(int argc, char **argv) { int i; unsigned char hwaddr[6]; char devname[3][7]; unsigned char buf[1024]; // for revevied packet int ret; read_netdev_proc(devname, 3, 7); for(i = 0; i < 3 && get_hwaddr(devname[i], hwaddr) != 0; i++){ //empty } printf("devname: [ %s ]\t", devname[i]); printhex(hwaddr, 6, ":"); int sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); if(sock < 0){ perror("sock"); return -1; } struct sockaddr_ll sll; memset(&sll, 0, sizeof(sll)); sll.sll_ifindex = 2; // It seems only need this to specify which NIC to use memcpy(packet_start + 6, hwaddr, 6); //memcpy(packet_start, hwaddr, 6); while(argc == 1){ if (sendto(sock, packet_start, sizeof packet_start, 0, &sll, sizeof(sll)) < 0){ perror("sendto"); return 1; } printf("Sendto Success!\n"); sleep(1); } while(argc == 2){ ret = recvfrom(sock, buf, 1024, 0, NULL, NULL); printf("recv: "); printhex(buf, ret, " "); } return 0; }