マイペースなプログラミング日記

DTMやプログラミングにお熱なd-kamiがマイペースに書くブログ

IPアドレスモニター

前回作ったプログラムに、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;
}