반응형

 커널 코드 안에서 IP 주소를 나타내는 변수나 키워드는 무진장 많다.

커널 안에서 IP 주소를 나타내는 형식은 C 나 JAVA의 APP단에서 나타내는 IP 주소형식과 다를 수 있다.

커널 안에서의 IP 주소 형식이 어떤지 살펴보자

 

우선 아래의 코드를 보자

https://elixir.bootlin.com/linux/v6.6.10/source/net/mptcp/pm_netlink.c#L2204

 

...
    switch (ssk->sk_family) {
	case AF_INET:
		if (nla_put_in_addr(skb, MPTCP_ATTR_SADDR4, issk->inet_saddr))
			goto nla_put_failure;
		break;
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
	case AF_INET6: {
		const struct ipv6_pinfo *np = inet6_sk(ssk);

		if (nla_put_in6_addr(skb, MPTCP_ATTR_SADDR6, &np->saddr))
			goto nla_put_failure;
		break;
	}
...

 

 

코드를 보면, nla_put_in_addr이라는 함수를 써서, 주소를 put하는 형식으로 되어있다.

 

살펴보아야할 것은 put된 주소가 어떤 형식인지이다.

 

그래서 issk->inet_saddr과 np->saddr의 자료형을 우선 살펴보자

 

■ issk->inet_addr의 자료형

https://elixir.bootlin.com/linux/v6.6.10/source/include/net/inet_sock.h#L222

struct inet_sock {
...
	__be32			inet_saddr;
...
}

 

be는 빅엔디안의 줄임말로써, 해당 데이터는 빅엔디안으로 저장될 예정이라는 걸 말한다. 

크기는 4byte(32bit)이다.  왜냐하면 IP주소는 4바이트로 표현 가능하기 떄문 (255.255.255.255)

 

  np->saddr의 자료형

https://elixir.bootlin.com/linux/v6.6.10/source/include/linux/ipv6.h#L205

/* struct ipv6_pinfo - ipv6 private area */
struct ipv6_pinfo {
	struct in6_addr 	saddr;
...
}

 

그리고 in6_addr을 보면

 

https://elixir.bootlin.com/linux/v6.6.10/source/include/uapi/linux/in6.h#L33

struct in6_addr {
	union {
		__u8		u6_addr8[16];
#if __UAPI_DEF_IN6_ADDR_ALT
		__be16		u6_addr16[8];
		__be32		u6_addr32[4];
#endif
	} in6_u;
#define s6_addr			in6_u.u6_addr8
#if __UAPI_DEF_IN6_ADDR_ALT
#define s6_addr16		in6_u.u6_addr16
#define s6_addr32		in6_u.u6_addr32
#endif
};

 

크기는 16byte이다.

 

결론

 위의 커널 소스에서 IP주소를 저장하는 방식은 바이너리 형식으로 저장되는 것을 확인되었다.

유의할 점은 저 바이너리 형식으로 저장된 형식을 C나 JAVA에서 바로 사용할 수 는 없다는 점. 사용하기 위해서는 바이너리를 string으로 변환을 해주어야한다.

 그 변환해주는 메서드는 어떤 언어 플랫폼이냐에 따라 다를 것이다.

반응형

'Linux > Kernel(커널)' 카테고리의 다른 글

[Kernel] Netlink 메시지 수신 (MPTCP) 예제  (0) 2024.08.13
[Kernel] Netlink 메시지 수신하기  (0) 2024.08.09
[Kernel(커널)] sysctl 명령어  (0) 2024.02.24
커널 소스 위치  (0) 2021.12.30
[Kernel] 커널 빌드하기  (0) 2021.08.12