프로젝트 현황
pcap으로 진행하던 프로젝트를
pcap으로는 진행이 불가능하다고 판단하여 raw socket으로 옮기고
echo server제작 실습 중. client 부분을 담당하여 git flow로 협업
알게 된 것들
프로젝트를 진행하고 코드를 분석하면서 알게 된 것들을 일단 정리
inet_pton 함수
https://techlog.gurucat.net/317
헤더파일은
#include<arpa/inet.h>
를 포함하며. 사람이 알아보기 쉬운 형태의 IPv4, IPv6 주소를 binary 형태로 변환하는 기능을 수행한다.
int inet_pton(int af, const char *src, void *dst);
af는 AF_INET나 AF_INET6 중 하나이고 src는 문자열, dst는 binary로 변환된 주소가 저장될 포인터. network byte order로 저장된다.
성공시 1을 반환
문자열에 저장된 주소가 af에 유효한 주소가 아닐 경우 0 반환
af가 적절하지 않을 경우 -1 반환
중괄호 초기화
C++에서는 중괄호 초기화를 제공한다.
구조체 멤버를 초기화하는데 사용할 수 있다.
socket 함수
https://blockdmask.tistory.com/212
<sys/types.h>, <sys/socket.h>
에 들어있고, <netinet/in.h>에도 있는듯...?
int socket(int domain, int type, int protocol);
형식은 이렇게 이루어지고
domain은 어떤 영역에서 통신할건지 지정해준다.
AF_INET 등 ..
type는 어떤 타입의 프로토콜을 사용할지 설정한다.
SOCK_RAW를 사용해야..? raw socket을 사용하는 듯 하다.
protocol은 어떤 프로토콜의 값을 설정하냐인데, TCP면 IPPROTO_TCP,
ICMP면 IPPROTO_ICMP 등을 사용한다.
반환은 소켓을 가리키는 socket descriptor을 반환한다. 파일디스크립터와 비슷하며 -1이 반환되면 생성 실패.
0이상의 값이 반환되면 socket descriptor이 반환된 것이다.
IP 헤더를 조작하기 위해서는 IP_HDRINCL 값을 on으로 두어야 한다고 한다.
IP_HDRINCL 값을 1로 설정했어도 IP헤더의 식별자 부분을 0으로 채우면 커널에서 나머지 부분을 자동으로 작성하여 처리한다고 한다.
AP_INET? PF_INET?
오래 전 소켓프로그래밍을 설계할 때, 확장성을 위해 한 종류의 주소체계가 여러 프로토콜을 지원할 수 있도록 하였다.
그래서 주소체계를 지정하는데 쓰이는지, 프로토콜을 지정하는데 쓰이는 지 구분하기 위해 AF, PF를 만들었고
AF는 Address Family, 주소 체계를 지정하고
PF는 Protocol Family, 프로토콜을 지정한다.
여러 주소체계를 지정하는 일은 일어나지 않았고 둘이 같은 값을 가지도록 사용된다.
아무거나 사용해도 좋지만, 주소 체계를 지정할 땐 AF를 쓰고 프로토콜은 PF를 써서 명시적으로 보여주긴 해야겠다 생각.
inet_addr vs inet_pton
inet_addr은 ipv4만 지원하며 inet_pton은 ipv4와 ipv6를 지원한다.
raw socket에서 0을 자동으로 채워주는지에 대하여
raw socket에서 0으로 넣어두면 운영체제에서 자동으로 해당 부분을 채워준다고 들었는데 이게 맞다면 source ip나 checksum 등을 따로 구할 필요가 없다. (물론 fake_header에서는 checksum을 구현해야 할 것이다.)
그래서 테스트를 진행했다.
tos는 보통 0이라고는 하는데 암튼
ip header에서
tos, frag_off, check(checksum), saddr을 0으로 주었고
tcp header에서 source port, checksum, seq, ack 등을 0으로 주었다.
그리고 wireshark에서 분석한다.
ip header에서 checksum이 자동으로 들어가고 source address는 127.0.0.1로 세팅된다.
checksum이 맞게 자동으로 들어간 건지는 모르겠다.. 일단 tcp도 보자
tcp source port는 자동으로 설정되지 않는다.
checksum도 마찬가지.
맨 처음 보낸 패킷의 seq number, ack number인데
seq number raw 부분은 랜덤 값으로 채워져야 하나 여기서 자동으로 채워주지 않았다.
아무래도 ip는 괜찮겠지만 tcp는 알아서 채워야 하는 듯 하다.