ipコマンドの謎

Redhat7やCentOS7からは「ifconfig」コマンドに変わり「ip」コマンドを使用するよう

言われている。

ただこのipコマンドで表示しているstateの意味がいまいちわからない。

 

[root@gochamaze ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000
link/ether 00:0c:29:22:53:51 brd ff:ff:ff:ff:ff:ff
inet 192.168.3.170/24 brd 192.168.3.255 scope global eth0
inet6 fe80::20c:29ff:fe22:5351/64 scope link
valid_lft forever preferred_lft forever

 

ではコマンドのソースファイルを読んでみることにする。ちなみに回答にたどり着ける自信はまったくない。

 

ではさくらエディタのgrepを使用して「state」を検索。

ipaddress.cに配列を発見。

static const char *oper_states[] = {
"UNKNOWN", "NOTPRESENT", "DOWN", "LOWERLAYERDOWN",
"TESTING", "DORMANT", "UP"
};

 

その下にstateを表示するであろうそれらしい関数がある。

static void print_operstate(FILE *f, __u8 state)
{
if (state >= sizeof(oper_states)/sizeof(oper_states[0]))
fprintf(f, "state %#x ", state);
else
fprintf(f, "state %s ", oper_states[state]);
}

 

またまたその下にstateの状態を確認する関数が存在する。

int get_operstate(const char *name)
{
int i;

for (i = 0; i < sizeof(oper_states)/sizeof(oper_states[0]); i++)
if (strcasecmp(name, oper_states[i]) == 0)
return i;
return -1;
}

strcasecmp, strncasecmp - 二つの文字列を大文字小文字を区別せず比較する  

 

ではget_operstateを追いかけていったら

iplink.cまで飛んでしまった。

 

else if (strcmp(*argv, "state") == 0) {
int state;
NEXT_ARG();
state = get_operstate(*argv);
if (state < 0)
invarg("Invalid operstate\n", *argv);

addattr8(&req->n, sizeof(*req), IFLA_OPERSTATE, state);

strcmp

str1とstr2を比較してその結果を返す。

■戻り値:
str1とstr2が等しいならば0、
str1>str2ならば正の値、
str1<str2ならば負の値を返す。

 

上記関数は「iplink_parse」でその大本は、iplink_modifyで。。。このあたりで理解できなくなり迷子になった。

そんで構造体がいくつか宣言されていた。

iplink.cで

struct iplink_req {
struct nlmsghdr n;
struct ifinfomsg i;
char buf[1024];
};

 

struct nlmsghdr {
    __u32 nlmsg_len;    /* ヘッダーを含むメッセージの長さ */
    __u16 nlmsg_type;   /* メッセージの内容のタイプ */
    __u16 nlmsg_flags;  /* 追加フラグ */
    __u32 nlmsg_seq;    /* シーケンス番号 */
    __u32 nlmsg_pid;    /* 送信者のポート ID */
};

 

色々調べたらここにたどり着いた。

http://linuxjm.osdn.jp/html/LDP_man-pages/man7/rtnetlink.7.html

 

ipコマンドは、nettlinkを使用して情報を取得しているようだ。

netlinkの基本的学習をする必要がある。

次回はそこから