Last active
July 5, 2020 10:01
-
-
Save GunjiD/a61b4a1537b2652faa94d1bddd5da532 to your computer and use it in GitHub Desktop.
raw packet メモ
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <string.h> | |
#include <arpa/inet.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <sys/socket.h> | |
#include <netpacket/packet.h> | |
#include <net/ethernet.h> | |
#include <sys/ioctl.h> | |
#include <net/if.h> | |
#include <netinet/ip.h> | |
#include <netinet/udp.h> | |
#include <netinet/tcp.h> | |
#define BUF_SIZ 65536 | |
int create_socket(); | |
// socket は権限が必要なので注意 | |
//man socket(2) を参照 | |
//第三引数については man packet(7) を参照。これを設定しているとすべてのパケットを受信する。 | |
// int socket() | |
int main(int argc, char *argv[]){ | |
/* | |
* ディスクリプタを返す //// man socket(7)より | |
* | |
* */ | |
create_socket(); | |
return 0; | |
} | |
int create_socket(){ | |
// socket の file descriptor を開く | |
int sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); | |
// インターフェースの設定を行う構造体 | |
struct ifreq if_set_pm; | |
// プロトコルの情報が格納される | |
struct sockaddr saddr; | |
socklen_t saddr_len = sizeof(saddr); | |
// 受信したパケットのバイト数を格納 | |
ssize_t recv_byte; | |
// パケットを受信する | |
unsigned char *buffer = (unsigned char *) malloc(BUF_SIZ); | |
memset(buffer,0, BUF_SIZ); | |
// インターフェースの指定 | |
strncpy(if_set_pm.ifr_name, "eth0", IFNAMSIZ - 1); | |
// 現在の状態を取得 | |
ioctl(sock, SIOCGIFFLAGS, &if_set_pm); | |
// or でビットを立てる | |
if_set_pm.ifr_flags |= IFF_PROMISC; | |
// プロミスキャスモードの反映 | |
ioctl(sock, SIOCSIFFLAGS, &if_set_pm); | |
// socket の設定を行う。 man getsockopt(2) | |
if(setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, "eth0", IFNAMSIZ - 1) == -1){ | |
// エラー時には -1 | |
printf("not setting socket\n"); | |
return 1; | |
} | |
while(1){ | |
recv_byte = recvfrom(sock, buffer, BUF_SIZ, 0, &saddr, &saddr_len); | |
// 受信したパケットを ethdr にキャストして代入する | |
// ethhdr については if_ether.h を参照 | |
struct ethhdr *eth_h = (struct ethhdr*)(buffer); | |
printf("Ethernet Header\n"); | |
// 宛先アドレスの MAC アドレスを表示 | |
printf("destination address : %.2X-%.2X-%.2X-%.2X-%.2X-%.2X\n", | |
eth_h->h_dest[0],eth_h->h_dest[1],eth_h->h_dest[2],eth_h->h_dest[3],eth_h->h_dest[4],eth_h->h_dest[5]); | |
printf("source address : %.2X-%.2X-%.2X-%.2X-%.2X-%.2X\n", | |
eth_h->h_source[0],eth_h->h_source[1],eth_h->h_source[2],eth_h->h_source[3],eth_h->h_source[4],eth_h->h_source[5]); | |
printf("Packet Type ID : %d\n", eth_h->h_proto); | |
printf("packet %lu bytes\n", recv_byte); | |
printf("==================================================\n"); | |
// ethernet header の分を移動させることで IP header を抜き出す | |
struct iphdr *ip_h = (struct iphdr*)(buffer + sizeof(struct ethhdr)); | |
char src_addr[INET_ADDRSTRLEN]; | |
char dst_addr[INET_ADDRSTRLEN]; | |
//送信元IPアドレス | |
//宛先IPアドレス | |
inet_ntop(AF_INET, &ip_h->saddr, src_addr, sizeof(src_addr)); | |
inet_ntop(AF_INET, &ip_h->daddr, dst_addr, sizeof(dst_addr)); | |
printf("IP Header\n"); | |
printf("Version : %d\n", (unsigned int)ip_h->version); | |
printf("IHL : %d Bytes\n", (unsigned int)(ip_h->ihl)*4); | |
printf("Total Length : %d Bytes\n", ntohs(ip_h->tot_len)); | |
printf("Time To Live : %d \n", (unsigned int)ip_h->ttl); | |
printf("Protocol : %d \n", (unsigned int)ip_h->protocol); | |
printf("source IP : %s\n", src_addr); | |
printf("destination IP : %s\n", dst_addr); | |
printf("==================================================\n"); | |
//for(int i=0; i < sizeof(buf); i++) printf("%02X", buf[i]); | |
//printf("interface = %s \n", if_set_pm.ifr_name); | |
__u8 iphdr_len = ip_h->ihl*4; | |
struct tcphdr *udp_h = (struct tcphdr*)(buffer+ iphdr_len + sizeof(struct ethhdr)); | |
printf("Source Port %d\n", udp_h->source); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment