반응형
Notice
Recent Posts
Recent Comments
Link
안 쓰던 블로그
pcap 프로그래밍-ARP 패킷 만들고 보내기 본문
반응형
ARP 헤더 구조
ARP 패킷 만드는 과정
1. 헤더 구조에 맞춰서 구조체를 만들어 주고, 각 값을 채운다
2. 소켓을 열고 보낸다
3. 와이어 샤크에서 ARP 패킷으로 잘 잡히는지 확인한다
코드
#include <stdio.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <string.h>
#include <netinet/in.h> //htons: 엔디안 변경
struct eth_hdr{ //이더넷 헤더
unsigned char h_dest[6]; //이더넷 목적지 주소 6바이트
unsigned char h_source[6]; //이더넷 출발지 주소 6바이트
unsigned short h_type; //다음 패킷 타입 정보 2바이트
} __attribute__((packed));
struct arp_hdr{ //arp헤더
unsigned short ar_hrd; //하드웨어 주소 타입. 이더넷은 1
unsigned short ar_pro; //프로토콜 타입. IP는 0x0800
unsigned char ar_hln; //하드웨어 주소 길이 1바이트. MAC주소 길이는 6
unsigned char ar_pln; //프로토콜 주소 길이 1바이트. IP주소 길이는 4
unsigned short ar_op; //op코드. 요청or응답 패킷 확인. ARP요청0001 응답0002
unsigned char ar_sha[6]; //출발지 MAC주소
unsigned char ar_sip[4]; //출발지 IP주소
unsigned char ar_tha[6]; //목적지 MAC주소(이걸 채우려고 ARP쓰므로 처음엔 비어있다)
unsigned char ar_tip[4]; //목적지 IP주소
} __attribute__((packed));
static unsigned char g_buf[sizeof(struct eth_hdr)+sizeof(struct arp_hdr)]; //패킷 총 길이
static int g_sock; //소켓
int main(int argc, char *argv[]) {
struct eth_hdr ether;
struct arp_hdr arp;
struct sockaddr_ll sll; //low socket 사용
bzero(&sll, sizeof(sll));
memset(&sll, 0, sizeof(sll));
sll.sll_family = PF_PACKET;
sll.sll_ifindex = if_nametoindex("eth0");
sll.sll_halen = 6;
g_sock = socket(PF_PACKET, SOCK_RAW, 0);
//이더넷의 목적지 주소 6바이트를 브로드캐스트로 채움
ether.h_dest[0] = 0xff;
ether.h_dest[1] = 0xff;
ether.h_dest[2] = 0xff;
ether.h_dest[3] = 0xff;
ether.h_dest[4] = 0xff;
ether.h_dest[5] = 0xff;
//이더넷 출발지 주소 6바이트. 어차피 내가 만드는 헤더라 임의로
ether.h_source[0] = 0x00;
ether.h_source[1] = 0x0a;
ether.h_source[2] = 0x29;
ether.h_source[3] = 0xf7;
ether.h_source[4] = 0x62;
ether.h_source[5] = 0x11;
//short형 호스트 바이트 순서 데이터를 네트워크 바이트 순서값으로 변경(호스트 엔디안 맞춤)
ether.h_type = htons(0x0806);
arp.ar_hrd = htons(0x0001); //하드웨어 주소 타입-이더넷은 1
arp.ar_pro = htons(0x0800); //프로토콜 주소 타입-IP는 0x0800
arp.ar_hln = 0x06; //하드웨어 주소 길이-MAC주소 길이 6
arp.ar_pln = 0x04; //프로토콜 주소 길이-IP 주소 길이 4
arp.ar_op = htons(0x0001); //op코드-ARP요청 0x0001
//출발지 MAC주소-내가 헤더 만들고 있으니까 임의로 채움
arp.ar_sha[0] = 0x00;
arp.ar_sha[1] = 0x0a;
arp.ar_sha[2] = 0x29;
arp.ar_sha[3] = 0xf7;
arp.ar_sha[4] = 0x62;
arp.ar_sha[5] = 0x11;
//출발지 IP주소
arp.ar_sip[0] = 0xc0;
arp.ar_sip[1] = 0xa8;
arp.ar_sip[2] = 0x99;
arp.ar_sip[3] = 0x33;
//목적지 MAC주소-처음 통신할 때는 비어있다
arp.ar_tha[0] = 0x00;
arp.ar_tha[1] = 0x00;
arp.ar_tha[2] = 0x00;
arp.ar_tha[3] = 0x00;
arp.ar_tha[4] = 0x00;
arp.ar_tha[5] = 0x00;
//목적지 IP주소
arp.ar_tip[0] = 0xc0;
arp.ar_tip[1] = 0xa8;
arp.ar_tip[2] = 0x99;
arp.ar_tip[3] = 0x32;
memcpy(g_buf, ðer, sizeof(struct eth_hdr)); //헤더만큼 메모리 잡음
memcpy(g_buf+14, &arp, sizeof(struct arp_hdr)); //헤더만큼 메모리 잡음
sendto(g_sock, g_buf,
sizeof(struct eth_hdr) + sizeof(struct arp_hdr),0,
(struct sockaddr *)&sll, sizeof(struct sockaddr_ll)); //보냄
return 0;
}
실행
sudo wireshark
와이어 샤크 실행
g++ -o pcap_send_arp pcap_send_arp.cpp -lpcap
컴파일
sudo ./pcap_send_arp eth0
eth0으로 전송
source를 보면 내가 입력한 MAC주소가 들어있는 것을 확인할 수 있다
destination에도 잘 브로드캐스트 되었다
타입은 ARP로 잘 찍혔고, Sender IP도 내 IP로 들어 있다
반응형
'Network' 카테고리의 다른 글
pcap 프로그래밍-ARP 패킷 분석 ARP reader (0) | 2020.09.25 |
---|---|
pcap 프로그래밍-ether_addr, ether_header, ip_header, tcp_header, arphdr 구조체 (0) | 2020.09.25 |
와이어샤크 패킷 분석하기 2-tcp (0) | 2020.09.24 |
와이어샤크 패킷 분석하기 1-board (0) | 2020.09.24 |
3-way handshake와 4-way handshake (0) | 2020.09.18 |
Comments