iptables勉強
ユーザ空間から IPTablesのチェインの取り出し。
とりあえずなんとなくとれるようになったので今日はここまで。
#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <string.h> #include <net/if.h> #include <getopt.h> #include <stdlib.h> #include <linux/netfilter_ipv4.h> #include <linux/netfilter_ipv4/ip_tables.h> #include <linux/netfilter/x_tables.h> int show_ipt_entry(struct ipt_entry * ent, struct ipt_getinfo *info, struct ipt_get_entries *entries) { struct xt_entry_target *xt_target = ipt_get_target(ent); // user定義チェイン if ( strcmp(xt_target->u.user.name, "ERROR") == 0 ) { printf("user定義チェイン(%s)\n", (char*)xt_target->data); return 0; } // builtinチェイン int i; for ( i = 0; i < NF_IP_NUMHOOKS; ++i ) { if ( info->valid_hooks & (1 << i) ) { // 有効か確認 if ( (struct ipt_entry*)((char*)entries->entrytable + info->hook_entry[i]) == ent ) { switch( i ) { case NF_IP_PRE_ROUTING: printf("PREROUTING\n"); break; case NF_IP_POST_ROUTING: printf("POSTROUTING\n"); break; case NF_IP_LOCAL_IN: printf("LOACLIN\n"); break; case NF_IP_LOCAL_OUT: printf("LOCALOUT\n"); break; case NF_IP_FORWARD: printf("FORWARD\n"); break; default: printf("unknown chain\n"); break; } } } } struct xt_standard_target *st = (struct xt_standard_target*)xt_target; printf("#### ipt_verdict %d ####\n", st->verdict); return 0; } void main(int argc, char *argv[]) { char table[256] = {}; strcpy(table, "filter"); int arg; while( (arg = getopt(argc, argv, "t:")) != -1 ) { switch(arg) { case 't': strcpy(table, optarg); break; } } int sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); struct ipt_getinfo info; memset(&info, 0, sizeof(info)); strcpy(info.name, table); int len = sizeof(info); if ( getsockopt(sock, IPPROTO_IP, IPT_SO_GET_INFO, &info, &len) == -1 ) { perror("IPT_SO_GET_INFO error\n"); return; } printf("#### ipt_getinfo ####\n"); printf("name : %s\n", info.name); printf("valid_hooks : %d\n", info.valid_hooks); printf("underflow: \n"); printf("\tNF_INET_PRE_ROUTING : %d\n", info.underflow[NF_INET_PRE_ROUTING]); printf("\tNF_INET_LOCAL_IN: %d\n", info.underflow[NF_INET_LOCAL_IN]); printf("\tNF_INET_FORWARD: %d\n", info.underflow[NF_INET_FORWARD]); printf("\tNF_INET_LOCAL_OUT: %d\n", info.underflow[NF_INET_LOCAL_OUT]); printf("\tNF_INET_POST_ROUTING: %d\n", info.underflow[NF_INET_POST_ROUTING]); printf("num_entries: %d\n", info.num_entries); printf("size: %d\n", info.size); struct ipt_get_entries *entries; len = sizeof(*entries) + info.size; entries = calloc(1, len); strcpy(entries->name, info.name); entries->size = info.size; if ( getsockopt(sock, IPPROTO_IP, IPT_SO_GET_ENTRIES, entries, &len) == -1 ) { perror("IPT_SO_GET_ENTRIES error\n"); return; } int i; for(i = 0; i < NF_INET_NUMHOOKS; ++i) { if ( info.underflow[i] == -1 ) { continue; } struct ipt_entry* ent = (struct ipt_entry*)((char*)entries->entrytable + info.underflow[i]); struct xt_entry_target *t = ipt_get_target(ent); if ( strcmp(t->u.user.name, "") != 0 ) { printf("error\n"); } struct xt_standard_target *st = (struct xt_standard_target*)t; } IPT_ENTRY_ITERATE(entries->entrytable, entries->size, show_ipt_entry, &info, entries); }