前回作ったプログラムに、IPパケットが流れてきた場合、送信元IPアドレスと宛先IPアドレスを表示するという機能を加えたプログラムを作った。IPヘッダにはもっといろいろ情報があるけど、とりあえずIPアドレスのみの表示とした
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <netinet/if_ether.h> #include <netinet/ip.h> #define MAX_SIZE 1600 char* mac_ntoa(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; struct ip* ip; 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]; int type; mac_ntoa(shost, eth->ether_shost); //送信元のMACアドレス取得 mac_ntoa(dhost, eth->ether_dhost); //宛先のMACアドレス取得 type = ntohs(eth->ether_type); //上位層のプロトコルタイプを取得 printf("Source MAC Address\n%s\n", shost); printf("Destination MAC Address\n%s\n", dhost); printf("Type\n0x%04x\n", type); if(type == ETHERTYPE_IP){ ip = (struct ip*)(buff + sizeof(struct ether_header)); //送信元IPアドレス取得 char* src_addr = inet_ntoa(ip->ip_src); printf("Source IP Address\n%s\n", src_addr); //宛先IPアドレス取得 char* dst_addr = inet_ntoa(ip->ip_dst); printf("Destination IP Address\n%s\n", dst_addr); } printf("\n"); } } char* mac_ntoa(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; }