最近(というかずっと)Javaばかり使っているので、別の言語を思い出すためにも使ってみた。使ったのはC言語で、作ったのは簡単なEthernet Frameのヘッダをキャプチャするプログラム。動かすためにはroot権限が必要で引数にネットワークインターフェイスを指定する。省略された場合はeth0を使うようにした。無限ループしてるので終了はCtrl+Cで。何か「基礎からわかるTCP/IPネットワーク実験プログラミング」にあったipdumpの超劣化版になったなぁ
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <netinet/if_ether.h> #define MAX_SIZE 1600 char* mac_ntos(char* str, u_char* addr); int main(int argc, char** argv){ char ifname[256]; int s; if(argc == 1) strcpy(ifname, "eth0"); else if(argc == 2) strncpy(ifname, *(argv + 1), 256); if((s = socket(AF_INET, SOCK_PACKET, htons(ETH_P_ALL))) < 0){ perror("socket"); exit(EXIT_FAILURE); } struct sockaddr sa; memset(&sa, 0, sizeof(sa)); sa.sa_family = AF_INET; snprintf(sa.sa_data, 256, "%s", ifname); if(bind(s, &sa, sizeof(sa)) < 0){ perror("bind"); exit(EXIT_FAILURE); } char buff[MAX_SIZE]; int length; struct ether_header *eth; while(1){ if((length = read(s, buff, MAX_SIZE)) < 0){ perror("read"); exit(EXIT_FAILURE); } eth = (struct ether_header *)buff; char shost[18]; char dhost[18]; mac_ntos(shost, eth->ether_shost); mac_ntos(dhost, eth->ether_dhost); printf("Source Mac Address\n%s\n", shost); printf("Destination Mac Address\n%s\n", dhost); printf("Type\n0x%04x\n", ntohs(eth->ether_type)); printf("\n"); } } char* mac_ntos(char* str, u_char* addr){ snprintf(str, 18, "%02x:%02x:%02x:%02x:%02x:%02x", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); return str; }