[Kernel(커널)] 커널에서의 IP 주소에 대한 고찰
2024. 8. 14. 02:27커널 코드 안에서 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 |