[Linux] ip header, ip tunnel, iphdr, ether_header 관련 커널 소스 분석
2022. 6. 7. 01:33- iphdr 구조체
전형적으로 20bytes임
1) /usr/include/netinet/ip.h 의 위치 혹은
2) include/uapi/linux/ip.h https://elixir.bootlin.com/linux/v4.3/source/include/uapi/linux/ip.h#L85
출처: https://elixir.bootlin.com/linux/v4.3/source/include/uapi/linux/ip.h#L85
struct iphdr {
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u8 ihl:4,
version:4;
#elif defined (__BIG_ENDIAN_BITFIELD)
__u8 version:4,
ihl:4;
#else
#error "Please fix <asm/byteorder.h>"
#endif
__u8 tos;
__be16 tot_len;
__be16 id;
__be16 frag_off;
__u8 ttl;
__u8 protocol;
__sum16 check;
__be32 saddr;
__be32 daddr;
/*The options start here. */
};
- ether_header 구조체
보통 14byte임
출처1) https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/if_ether.h
#define ETH_ALEN 6 /* Octets in one ethernet addr */
struct ethhdr {
unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
unsigned char h_source[ETH_ALEN]; /* source ether addr */
__be16 h_proto; /* packet type ID field */
} __attribute__((packed));
출처2) https://elixir.bootlin.com/linux/v4.9/source/drivers/staging/slicoss/slic.h#L282
struct ether_header {
unsigned char ether_dhost[6];
unsigned char ether_shost[6];
ushort ether_type;
};
- ip tunnel parm 구조체
참고 소스 : https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/if_tunnel.h#L48
struct ip_tunnel_parm
{
char name[IFNAMSIZ];
int link;
__be16 i_flags;
__be16 o_flags;
__be32 i_key;
__be32 o_key;
struct iphdr iph;
};
- ip6_tnl_parm 그리고 ip6_tnl_parm2 구조체
참고소스 : include/uapi/linux/ip6_tunnel.h
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef _IP6_TUNNEL_H
#define _IP6_TUNNEL_H
#include <linux/types.h>
#include <linux/if.h> /* For IFNAMSIZ. */
#include <linux/in6.h> /* For struct in6_addr. */
#define IPV6_TLV_TNL_ENCAP_LIMIT 4
#define IPV6_DEFAULT_TNL_ENCAP_LIMIT 4
/* don't add encapsulation limit if one isn't present in inner packet */
#define IP6_TNL_F_IGN_ENCAP_LIMIT 0x1
/* copy the traffic class field from the inner packet */
#define IP6_TNL_F_USE_ORIG_TCLASS 0x2
/* copy the flowlabel from the inner packet */
#define IP6_TNL_F_USE_ORIG_FLOWLABEL 0x4
/* being used for Mobile IPv6 */
#define IP6_TNL_F_MIP6_DEV 0x8
/* copy DSCP from the outer packet */
#define IP6_TNL_F_RCV_DSCP_COPY 0x10
/* copy fwmark from inner packet */
#define IP6_TNL_F_USE_ORIG_FWMARK 0x20
/* allow remote endpoint on the local node */
#define IP6_TNL_F_ALLOW_LOCAL_REMOTE 0x40
struct ip6_tnl_parm {
char name[IFNAMSIZ]; /* name of tunnel device */
int link; /* ifindex of underlying L2 interface */
__u8 proto; /* tunnel protocol */
__u8 encap_limit; /* encapsulation limit for tunnel */
__u8 hop_limit; /* hop limit for tunnel */
__be32 flowinfo; /* traffic class and flowlabel for tunnel */
__u32 flags; /* tunnel flags */
struct in6_addr laddr; /* local tunnel end-point address */
struct in6_addr raddr; /* remote tunnel end-point address */
};
struct ip6_tnl_parm2 {
char name[IFNAMSIZ]; /* name of tunnel device */
int link; /* ifindex of underlying L2 interface */
__u8 proto; /* tunnel protocol */
__u8 encap_limit; /* encapsulation limit for tunnel */
__u8 hop_limit; /* hop limit for tunnel */
__be32 flowinfo; /* traffic class and flowlabel for tunnel */
__u32 flags; /* tunnel flags */
struct in6_addr laddr; /* local tunnel end-point address */
struct in6_addr raddr; /* remote tunnel end-point address */
__be16 i_flags;
__be16 o_flags;
__be32 i_key;
__be32 o_key;
};
#endif
여기서 __be랑 __le는 빅엔디안, 리틀엔디안을 의미.
- iphdr 구조체
/usr/include/linux/ip.h
참고 소스 : https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/if_link.h#L688
참고 스펙 : https://datatracker.ietf.org/doc/html/rfc791
(RFC IP header 스펙)
struct iphdr {
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u8 ihl:4, // header length
version:4; // version
#elif defined (__BIG_ENDIAN_BITFIELD)
__u8 version:4,
ihl:4;
#else
#error "Please fix <asm/byteorder.h>"
#endif
__u8 tos; // type of service
__be16 tot_len;
__be16 id;
__be16 frag_off;
__u8 ttl; // time to live
__u8 protocol;
__sum16 check;
__be32 saddr;
__be32 daddr;
/*The options start here. */
};
- ifr 구조체
struct ifreq {
char ifr_name[IFNAMSIZ]; /* Interface name */
union {
struct sockaddr ifr_addr;
struct sockaddr ifr_dstaddr;
struct sockaddr ifr_broadaddr;
struct sockaddr ifr_netmask;
struct sockaddr ifr_hwaddr;
short ifr_flags;
int ifr_ifindex;
int ifr_metric;
int ifr_mtu;
struct ifmap ifr_map;
char ifr_slave[IFNAMSIZ];
char ifr_newname[IFNAMSIZ];
char *ifr_data;
};
};
This man page describes the sockets interface which is used to configure network devices.
Linux supports some standard ioctls to configure network devices.
They can be used on any socket's file descriptor regardless of
the family or type. Most of them pass an ifreq structure:
참고한 소스코드
- ip tunnel parm
https://github.com/spotify/linux/blob/master/include/linux/if_tunnel.h
- iphdr
https://docs.huihoo.com/doxygen/linux/kernel/3.7/structiphdr.html
https://docs.huihoo.com/doxygen/linux/kernel/3.7/uapi_2linux_2ip_8h_source.html
(한글 자료, ipheader에 자세히 나와있음.)
https://tmdgus.tistory.com/124
- ifr
'Linux > Linux' 카테고리의 다른 글
Unix Domain Socket (AF_UNIX) (0) | 2022.06.07 |
---|---|
[Linux/ip] GRE tunnel 생성하기 (ip tunnel 커맨드 이용) (2) | 2022.06.07 |
[Linux] 실무에서 쓰이는 리눅스 시스템/환경 설정 (0) | 2022.03.13 |
[Linux] /etc/resolv.conf : 네임 서버(DNS 서버)를 설정하는 파일 (0) | 2022.03.09 |
[리눅스] 로그 관련 주요 파일 (0) | 2022.03.06 |