2017年1月19日 星期四

libpcap - Send a frame(13)


libpcap能夠發送封包,不過是使用data-link層的raw socket。



一樣打開一個pcap handle。
    char errbuf[PCAP_ERRBUF_SIZE];
    char *device = NULL;

    //get default interface name
    device = pcap_lookupdev(errbuf);
    if(!device) {
        fprintf(stderr, "pcap_lookupdev(): %s\n", errbuf);
        exit(1);
    }//end if
    
    pcap_t *handle = pcap_open_live(device, 65535, 1, 1, errbuf);
    if(!handle) {
        fprintf(stderr, "pcap_open_live(): %s\n", errbuf);
        exit(1);
    }//end if


接著宣告一下封包,長度是14。
    u_char frame[] = "\x01\x02\x03\x04\x05\x06\xff\xff\xff\xff\xff\xff\x81\x00";
    int length = sizeof(frame) - 1;

其實一看就知道,這個封包目的mac address是"01:02:03:04:05:06",來源mac address是"ff:ff:ff:ff:ff:ff",則類型是"0x8100"(VLAN)。


呼叫函數pcap_sendpacket()送出封包。
    //send packet
    if(pcap_sendpacket(handle, frame, length) < 0) {
        fprintf(stderr, "pcap_sendpacket(): %s\n", pcap_geterr(handle));
    }//end if

除了函數pcap_sendpacket()以外,函數pcap_inject()一樣能達到相同效果,差別在於回傳值。

函數pcap_sendpacket()原型:
int pcap_sendpacket(pcap_t *p, const u_char *buf, int size);
  • 返回值:成功傳回0,失敗傳回-1,錯誤訊息從pcap_geterr()取得。
  • 參數:p一個libpcap handle。buf要送出去的封包。size送出大小。
  • 功能:從p所開啟的Interface送出封包。

函數pcap_inject()原型:
int pcap_inject(pcap_t *p, const void *buf, size_t size);
  • 返回值:成功傳回送出封包的byte數,失敗傳回-1,錯誤訊息從pcap_geterr()取得。
  • 參數:p一個libpcap handle。buf要送出去的封包。size送出大小。
  • 功能:從p所開啟的Interface送出封包。


編譯:
libpcap % gcc -I/usr/local/opt/libpcap/include -Wall -std=gnu99 -L/usr/local/opt/libpcap/lib -lpcap  send-a-frame.c -o send-a-frame


執行結果:

從左下角的十六進位可以看得出來是剛剛宣告的封包。


Source code on Github

沒有留言:

張貼留言