
개요
C언어로 네트워크 프로그래밍을 하면 다소 번거로운 점이 많이 존재한다. 네트워크 라이브러리를 사용해 간편하게 바꿀수도 있지만 공부하고 있는 입장이라면 다음과 같이 매크로를 작성하며 편리하게 사용할 수 있는 방법을 생각해보는 것도 중요한 과정 중 하나라고 생각한다.
필자는 궁극적으로 귀찮음을 이기지 못하고 Ctrl C + Ctrl V를 하기 위해 만들었다 ㅎ.. 이 글을 읽는 분들도 지금 네트워크 프로그래밍을 하고있다면 나만의 매크로로 구성된 헤더파일을 하나 가져보는 것도 괜찮을 것 이다.
IPv4
IPv4 주소는 32비트의 1.1.1.1 ~ 255.255.255.255의 MIN, MAX 값을 가지는 주소 표기 방식이다. 다음의 내용과 같이 비트 쉬프트 및 AND 연산을 통해 보기 좋은 pretty 결과물을 얻을 수 있다. IP 주소가 반대로 뜬다면 당황하지 말고 자신의 데스크톱 저장 방식이 LE인지 BE인지 확인해보길 바란다. 간단하게 0~24 쉬프트 연산의 순서를 반대로 진행하면 정상적인 결과 값을 얻을 수 있다.
매크로
#define IPV4_ADDR_FMT "%d.%d.%d.%d"
#define IPV4_ADDR_FMT_ARGS(addr) ((addr >> 0) & 0XFF), ((addr >> 8) & 0XFF), ((addr >> 16) & 0XFF), ((addr >> 24) & 0XFF)
출력
// 표준 입출력 예제
printf("int_ipv4 = "IPV4_ADDR_FMT"\n", IPV4_ADDR_FMT_ARGS(src_ipv4));
printf("dst_ipv4 = "IPV4_ADDR_FMT"\n", IPV4_ADDR_FMT_ARGS(dst_ipv4));
// 파일 입출력 예제
fprintf(fp, "int_ipv4 = "IPV4_ADDR_FMT"\n", IPV4_ADDR_FMT_ARGS(src_ipv4));
fprintf(fp, "dst_ipv4 = "IPV4_ADDR_FMT"\n", IPV4_ADDR_FMT_ARGS(dst_ipv4));
IPv6
IPv4 주소가 32 비트 주소 체계라면 IPv6는 128 비트 주소 체계이다. 기존 IPv4 주소가 고갈되는 문제를 해결되기 위해 탄생하였으며 그만큼 MIN, MAX의 범위가 크다. IPv4가 0~8, 8~16, 16~24, 24~32로 주소지를 구분지어 표기했다면 IPv6는 /0~/16~/32~/48~/64~/80~/96~/112~/128로 주소지를 구분짓는다. IPv6 주소는 uint128_t 또는 unsigned char 배열로 저장할 수 있다.
매크로
#define IPV6_ADDR_FMT "%u:%u:%u:%u:%u:%u:%u:%u:%u:%u:%u:%u:%u:%u:%u:%u"
#define IPV6_ADDR_FMT_ARGS(addr) addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7], addr[8], addr[9], addr[10], addr[11], addr[12], addr[13], addr[14], addr[15]
출력
// 표준 입출력 예제
printf("src_ipv6 = "IPV6_ADDR_FMT"\n", IPV6_ADDR_FMT_ARGS(src_ipv6));
printf("dst_ipv6 = "IPV6_ADDR_FMT"\n", IPV6_ADDR_FMT_ARGS(dst_ipv6));
// 파일 입출력 예제
fprintf(fp, "src_ipv6 = "IPV6_ADDR_FMT"\n", IPV6_ADDR_FMT_ARGS(src_ipv6));
fprintf(fp, "dst_ipv6 = "IPV6_ADDR_FMT"\n", IPV6_ADDR_FMT_ARGS(dst_ipv6));
MAC
MAC 주소는 데이터 링크 계층에서 통신을 위한 네트워크 인터페이스, 즉 HW에 부여된 고유 식별자이다. 이더넷과 와이파이를 포함한 대부분의 네트워크 기술에 네트워크 주소로 사용되며 MAC 주소는 매체 접근 제어 프로토콜 OSI 모델 하위 계층에서 사용된다. 다음과 같이 매크로를 작성할 수 있다.
매크로
#define MAC_ADDR_FMT "%02X:%02X:%02X:%02X:%02X:%02X"
#define MAC_ADDR_FMT_ARGS(addr) addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]
출력
// 표준 입출력 예제
printf("src_mac = "MAC_ADDR_FMT"\n", MAC_ADDR_FMT_ARGS(src_mac));
printf("dst_mac = "MAC_ADDR_FMT"\n", MAC_ADDR_FMT_ARGS(dst_mac));
// 파일 입출력 예제
fprintf(fp, "src_mac = "MAC_ADDR_FMT"\n", MAC_ADDR_FMT_ARGS(src_mac));
fprintf(fp, "dst_mac = "MAC_ADDR_FMT"\n", MAC_ADDR_FMT_ARGS(dst_mac));