반응형

- 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는 빅엔디안, 리틀엔디안을 의미.

https://kernelnewbies.kernelnewbies.narkive.com/YavCIxAe/purpose-of-using-be16-inside-a-data-structure

 

 

- 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

https://man7.org/linux/man-pages/man7/netdevice.7.html

반응형