├── MyFireWall ├── MyFireWall-cmd │ ├── firewall.c │ └── get.c └── MyFireWall │ ├── MyFireWall.pro │ ├── MyFireWall.pro.user │ ├── MyfwApi.h │ ├── main.cpp │ ├── mainwindow.cpp │ ├── mainwindow.h │ └── mainwindow.ui ├── README.md ├── images ├── DNAT.png ├── ipsetting.png ├── main.png ├── nat_instance1.png ├── nat_instance2.png ├── net_diagram.png ├── snat.png ├── status.png └── vmnet.png └── myfw ├── .tmp_versions └── myfw.mod ├── Makefile └── myfw_mod.c /MyFireWall/MyFireWall-cmd/firewall.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | //#include 11 | #include 12 | #include 13 | #include 14 | 15 | #define NETLINK_TEST (25) 16 | #define MAX_PAYLOAD (1024) 17 | #define TEST_PID (100) 18 | #define TCP 6 19 | #define UDP 17 20 | #define ICMP 1 21 | #define ANY -1 22 | #define MAX_RULE_NUM 50 23 | #define MAX_STATU_NUM 101 24 | #define MAX_NAT_NUM 100 25 | #define MAX_LOG_NUM 1000 26 | 27 | typedef struct { 28 | char src_ip[20]; 29 | char dst_ip[20]; 30 | short src_port; 31 | short dst_port; 32 | char protocol; 33 | bool action; 34 | bool log; 35 | }Rule; 36 | static Rule rules[MAX_RULE_NUM]; 37 | static int rnum = 0; //rules num 38 | 39 | typedef struct { 40 | unsigned src_ip; 41 | unsigned short src_port; 42 | unsigned dst_ip; 43 | unsigned short dst_port; 44 | unsigned char protocol; 45 | unsigned long t; 46 | }Connection; 47 | static Connection cons[MAX_STATU_NUM]; 48 | static int cnum = 0; 49 | 50 | typedef struct { 51 | //unsigned firewall_ip; 52 | unsigned nat_ip; 53 | unsigned short firewall_port; 54 | unsigned short nat_port; 55 | }NatEntry; 56 | static NatEntry natTable[MAX_NAT_NUM]; 57 | static int nnum = 0; //nat rules num 58 | unsigned net_ip = 0, net_mask = 0, firewall_ip = 0; 59 | 60 | typedef struct { 61 | unsigned src_ip; 62 | unsigned dst_ip; 63 | unsigned short src_port; 64 | unsigned short dst_port; 65 | unsigned char protocol; 66 | unsigned char action; 67 | }Log; 68 | static Log logs[MAX_LOG_NUM]; 69 | static int lnum = 0;//logs num 70 | 71 | /*----------------------------------------------------------------------------------------------------------------*/ 72 | unsigned ipstr_to_num(const char *ip_str){ 73 | int count = 0; 74 | unsigned tmp = 0,ip = 0, i; 75 | for(i = 0; i < strlen(ip_str); i++){ 76 | if(ip_str[i] == '.'){ 77 | ip = ip | (tmp << (8 * (3 - count))); 78 | tmp = 0; 79 | count++; 80 | continue; 81 | } 82 | tmp *= 10; 83 | tmp += ip_str[i] - '0'; 84 | } 85 | ip = ip | tmp; 86 | return ip; 87 | } 88 | 89 | char * addr_from_net(char * buff, __be32 addr){ 90 | __u8 *p = (__u8*)&addr; 91 | snprintf(buff, 16, "%u.%u.%u.%u", 92 | (__u32)p[0], (__u32)p[1], (__u32)p[2], (__u32)p[3]); 93 | return buff; 94 | } 95 | 96 | /*----------------------------------------------------------------------------------------------------------------*/ 97 | int netlink_create_socket(void) 98 | { 99 | //create a socket 100 | return socket(AF_NETLINK, SOCK_RAW, NETLINK_TEST); 101 | } 102 | 103 | int netlink_bind(int sock_fd) 104 | { 105 | struct sockaddr_nl addr; 106 | memset(&addr, 0, sizeof(struct sockaddr_nl)); 107 | addr.nl_family = AF_NETLINK; 108 | addr.nl_pid = TEST_PID; 109 | addr.nl_groups = 0; 110 | return bind(sock_fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_nl)); 111 | } 112 | 113 | int netlink_send_message(int sock_fd, const unsigned char *message, int len,unsigned int pid, unsigned int group) 114 | { 115 | struct nlmsghdr *nlh = NULL; 116 | struct sockaddr_nl dest_addr; 117 | struct iovec iov; 118 | struct msghdr msg; 119 | if( !message ) { 120 | return -1; 121 | } 122 | //create message 123 | nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(len)); 124 | if( !nlh ) { 125 | perror("malloc"); 126 | return -2; 127 | } 128 | nlh->nlmsg_len = NLMSG_SPACE(len); 129 | nlh->nlmsg_pid = TEST_PID; 130 | nlh->nlmsg_flags = 0; 131 | memcpy(NLMSG_DATA(nlh), message, len); 132 | iov.iov_base = (void *)nlh; 133 | iov.iov_len = nlh->nlmsg_len; 134 | memset(&dest_addr, 0, sizeof(struct sockaddr_nl)); 135 | dest_addr.nl_family = AF_NETLINK; 136 | dest_addr.nl_pid = pid; 137 | dest_addr.nl_groups = group; 138 | memset(&msg, 0, sizeof(struct msghdr)); 139 | msg.msg_name = (void *)&dest_addr; 140 | msg.msg_namelen = sizeof(struct sockaddr_nl); 141 | msg.msg_iov = &iov; 142 | msg.msg_iovlen = 1; 143 | //send message 144 | if( sendmsg(sock_fd, &msg, 0) < 0 ) 145 | { 146 | printf("send error!\n"); 147 | free(nlh); 148 | return -3; 149 | } 150 | free(nlh); 151 | return 0; 152 | } 153 | 154 | int netlink_recv_message(int sock_fd, unsigned char *message, int *len) 155 | { 156 | struct nlmsghdr *nlh = NULL; 157 | struct sockaddr_nl source_addr; 158 | struct iovec iov; 159 | struct msghdr msg; 160 | if( !message || !len ) { 161 | return -1; 162 | } 163 | //create message 164 | nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD)); 165 | if( !nlh ) { 166 | perror("malloc"); 167 | return -2; 168 | } 169 | iov.iov_base = (void *)nlh; 170 | iov.iov_len = NLMSG_SPACE(MAX_PAYLOAD); 171 | memset(&source_addr, 0, sizeof(struct sockaddr_nl)); 172 | memset(&msg, 0, sizeof(struct msghdr)); 173 | msg.msg_name = (void *)&source_addr; 174 | msg.msg_namelen = sizeof(struct sockaddr_nl); 175 | msg.msg_iov = &iov; 176 | msg.msg_iovlen = 1; 177 | if ( recvmsg(sock_fd, &msg, 0) < 0 ) { 178 | printf("recvmsg error!\n"); 179 | return -3; 180 | } 181 | *len = nlh->nlmsg_len - NLMSG_SPACE(0); 182 | memcpy(message, (unsigned char *)NLMSG_DATA(nlh), *len); 183 | free(nlh); 184 | return 0; 185 | } 186 | /*------------------------------------------------------------------*/ 187 | void print_IP(unsigned long int src_ip) 188 | { 189 | unsigned char src_i[4]; 190 | src_i[3] = src_ip%256; src_ip /= 256; 191 | src_i[2] = src_ip%256; src_ip /= 256; 192 | src_i[1] = src_ip%256; src_ip /= 256; 193 | src_i[0] = src_ip%256; src_ip /= 256; 194 | printf("%d.%d.%d.%d", src_i[0],src_i[1],src_i[2],src_i[3]); 195 | } 196 | 197 | void sprint_IP(char output[], unsigned long int src_ip) 198 | { 199 | unsigned char src_i[4]; 200 | src_i[3] = src_ip%256; src_ip /= 256; 201 | src_i[2] = src_ip%256; src_ip /= 256; 202 | src_i[1] = src_ip%256; src_ip /= 256; 203 | src_i[0] = src_ip%256; src_ip /= 256; 204 | sprintf(output, "%d.%d.%d.%d", src_i[0],src_i[1],src_i[2],src_i[3]); 205 | } 206 | 207 | void Convert(unsigned &ip, unsigned &mask, const char *ip_range){ 208 | char tmp_ip[20]; 209 | int p = -1, count = 0; 210 | unsigned len = 0, tmp = 0, i; 211 | ip = 0, mask = 0; 212 | strcpy(tmp_ip, ip_range); 213 | for(i = 0; i < strlen(tmp_ip); i++){ 214 | if(p != -1){ 215 | len *= 10; 216 | len += tmp_ip[i] - '0'; 217 | } 218 | else if(tmp_ip[i] == '/') 219 | p = i; 220 | } 221 | if(p != -1){ 222 | tmp_ip[p] = '\0'; 223 | mask = 0xFFFFFFFF << (32 - len); 224 | } 225 | else mask = 0xFFFFFFFF; 226 | for(i = 0; i < strlen(tmp_ip); i++){ 227 | if(tmp_ip[i] == '.'){ 228 | ip = ip | (tmp << (8 * (3 - count))); 229 | tmp = 0; 230 | count++; 231 | continue; 232 | } 233 | tmp *= 10; 234 | tmp += tmp_ip[i] - '0'; 235 | } 236 | ip = ip | tmp; 237 | } 238 | /*------------------------------Rules-------------------------------*/ 239 | int SendRules() 240 | { 241 | int sock_fd; 242 | unsigned char buf[MAX_PAYLOAD]; 243 | unsigned char a[5000]; 244 | int len; 245 | sock_fd = netlink_create_socket(); 246 | if(sock_fd == -1) { 247 | printf("socket error!\n"); 248 | return -1; 249 | } 250 | if( netlink_bind(sock_fd) < 0 ) { 251 | perror("bind"); 252 | close(sock_fd); 253 | exit(EXIT_FAILURE); 254 | } 255 | a[0] = 0; 256 | a[1] = rnum; 257 | memcpy(a + 2, rules, rnum * sizeof(Rule)); 258 | netlink_send_message(sock_fd, (const unsigned char *)a, rnum * sizeof(Rule) + 2, 0, 0); 259 | close(sock_fd); 260 | return 1; 261 | } 262 | 263 | bool AddRule( 264 | const char *src_ip, const char *dst_ip, 265 | unsigned short src_port, 266 | unsigned short dst_port, 267 | unsigned char protocol, 268 | bool action, bool log){ 269 | if(rnum < 100){ 270 | strcpy(rules[rnum].src_ip, src_ip); 271 | strcpy(rules[rnum].dst_ip, dst_ip); 272 | rules[rnum].src_port = src_port; 273 | rules[rnum].dst_port = dst_port; 274 | rules[rnum].protocol = protocol; 275 | rules[rnum].action = action; 276 | rules[rnum].log = log; 277 | rnum++; 278 | return true; 279 | } 280 | return false; 281 | } 282 | 283 | bool DelRule(int pos){ 284 | if(pos >= rnum || pos < 0) 285 | return false; 286 | memcpy(rules + pos, rules + pos + 1, sizeof(Rule) * (rnum - pos)); 287 | rnum--; 288 | return true; 289 | } 290 | 291 | void PrintRules(){ 292 | printf("|----------------------------------------------------------------------|\n"); 293 | printf("| src_ip | dst_ip |src_port|dst_port|protocol| action | log |\n"); 294 | printf("|----------------------------------------------------------------------|\n"); 295 | for(int i = 0; i < rnum; i++){ 296 | printf("|%15.20s|%15.20s|%7hd|%7hd|%7hhd|%7d|%7d|\n", rules[i].src_ip, rules[i].dst_ip, rules[i].src_port, rules[i].dst_port, rules[i].protocol, rules[i].action, rules[i].log); 297 | printf("|----------------------------------------------------------------------------------------------------------|\n"); 298 | } 299 | return; 300 | } 301 | 302 | /*----------------------------NAT RULES-----------------------------*/ 303 | int SendNatRules() 304 | { 305 | int sock_fd; 306 | unsigned char buf[MAX_PAYLOAD]; 307 | unsigned char a[5000]; 308 | int len; 309 | sock_fd = netlink_create_socket(); 310 | if(sock_fd == -1) { 311 | printf("socket error!\n"); 312 | return -1; 313 | } 314 | if( netlink_bind(sock_fd) < 0 ) { 315 | perror("bind"); 316 | close(sock_fd); 317 | exit(EXIT_FAILURE); 318 | } 319 | a[0] = 1; 320 | a[1] = nnum; 321 | memcpy(a + 2, &net_ip, sizeof(unsigned)); 322 | memcpy(a + 6, &net_mask, sizeof(unsigned)); 323 | memcpy(a + 10, &firewall_ip, sizeof(unsigned)); 324 | memcpy(a + 14, natTable, nnum * sizeof(NatEntry)); 325 | netlink_send_message(sock_fd, (const unsigned char *)a, nnum * sizeof(NatEntry) + 14, 0, 0); 326 | close(sock_fd); 327 | return 1; 328 | } 329 | 330 | bool AddNatRule(unsigned nat_ip, unsigned firewall_ip, unsigned short nat_port, unsigned short firewall_port){ 331 | if(nnum < 100){ 332 | natTable[nnum].nat_ip = nat_ip; 333 | //natTable[nnum].firewall_ip = firewall_ip; 334 | natTable[nnum].nat_port = nat_port; 335 | natTable[nnum].firewall_port = firewall_port; 336 | nnum++; 337 | return true; 338 | } 339 | return false; 340 | } 341 | 342 | bool DelNatRule(int pos){ 343 | if(pos >= nnum || pos < 0) 344 | return false; 345 | memcpy(rules + pos, rules + pos + 1, sizeof(Rule) * (nnum - pos)); 346 | nnum--; 347 | return true; 348 | } 349 | 350 | void SetNat(unsigned net, unsigned mask, unsigned ip){ 351 | firewall_ip = ip; 352 | net_ip = net; 353 | net_mask = mask; 354 | } 355 | 356 | void PrintNatRules(){ 357 | printf("|----------------------------------------------------------------------|\n"); 358 | printf("| nat_ip | firewall_port | nat_port |\n"); 359 | printf("|----------------------------------------------------------------------|\n"); 360 | for(int i = 0; i < nnum; i++){ 361 | char buff[20], buff2[20]; 362 | printf("|%15s|%15d|%15d|\n",addr_from_net(buff2, natTable[i].nat_ip), natTable[i].firewall_port, natTable[i].nat_port); 363 | printf("|----------------------------------------------------------------------------------------------------------|\n"); 364 | } 365 | return; 366 | } 367 | 368 | /*--------------------------------------Log-------------------------------------*/ 369 | int GetLogs() 370 | { 371 | int sock_fd; 372 | //unsigned char buf[MAX_PAYLOAD]; 373 | unsigned char a[100]; 374 | unsigned char buf[1000 * sizeof(Log)]; 375 | int len; 376 | sock_fd = netlink_create_socket(); 377 | if(sock_fd == -1) { 378 | printf("socket error!\n"); 379 | return -1; 380 | } 381 | if( netlink_bind(sock_fd) < 0 ) { 382 | perror("bind"); 383 | close(sock_fd); 384 | exit(EXIT_FAILURE); 385 | } 386 | a[0] = 2; 387 | netlink_send_message(sock_fd, (const unsigned char *)a, 2, 0, 0); 388 | if( netlink_recv_message(sock_fd, buf, &len) == 0 ) { 389 | printf("recvlen:%d\n",len); 390 | memcpy(logs, buf, len); 391 | lnum = len / sizeof(Log); 392 | } 393 | close(sock_fd); 394 | return 1; 395 | } 396 | 397 | void PrintLogs(){ 398 | printf("Logs:\n"); 399 | for(int i = 0; i < lnum; i++){ 400 | char buff[20], buff2[20]; 401 | printf("|%15s|%15s|%5hu|%5hu|%5hhu|%5hhu\n", addr_from_net(buff, logs[i].src_ip), addr_from_net(buff2, logs[i].dst_ip), logs[i].src_port, logs[i].dst_port, logs[i].protocol, logs[i].action); 402 | } 403 | } 404 | /*---------------------------------------Statu list-------------------------------------*/ 405 | int GetConnections() 406 | { 407 | int sock_fd; 408 | //unsigned char buf[MAX_PAYLOAD]; 409 | unsigned char a[100]; 410 | unsigned char buf[101 * sizeof(Connection)]; 411 | int len; 412 | sock_fd = netlink_create_socket(); 413 | if(sock_fd == -1) { 414 | printf("socket error!\n"); 415 | return -1; 416 | } 417 | if( netlink_bind(sock_fd) < 0 ) { 418 | perror("bind"); 419 | close(sock_fd); 420 | exit(EXIT_FAILURE); 421 | } 422 | a[0] = 3; 423 | netlink_send_message(sock_fd, (const unsigned char *)a, 1, 0, 0); 424 | if( netlink_recv_message(sock_fd, buf, &len) == 0 ) { 425 | printf("recvlen:%d\n",len); 426 | memcpy(cons, buf, len); 427 | cnum = len / sizeof(Connection); 428 | } 429 | close(sock_fd); 430 | return 1; 431 | } 432 | 433 | void PrintConnections(){ 434 | printf("Connections:\n"); 435 | for(int i = 0; i < cnum; i++){ 436 | char buff[20], buff2[20]; 437 | printf("|%15s|%15s|%5hu|%5hu|%5hhu|\n", addr_from_net(buff, cons[i].src_ip), addr_from_net(buff2, cons[i].dst_ip), cons[i].src_port, cons[i].dst_port, cons[i].protocol); 438 | } 439 | } 440 | 441 | int main() 442 | { 443 | AddRule("any", "127.0.0.1", -1, -1, -1, 1, 0); 444 | AddRule("127.0.0.1", "any", -1, -1, -1, 1, 0); 445 | AddRule("192.168.152.1", "any", -1, -1, -1, 1, 1); 446 | AddRule("any", "192.168.152.1", -1, -1, -1, 1, 1); 447 | AddRule("192.168.164.1", "any", -1, -1, -1, 1, 1); 448 | AddRule("any", "192.168.164.1", -1, -1, -1, 1, 1); 449 | AddRule("192.168.164.0/24", "any", -1, -1, -1, 1,1); 450 | AddRule("any", "192.168.164.0/24", -1, -1, -1, 1,1); 451 | AddRule("any", "any", -1, -1, -1, 1, 1); 452 | //AddRule("192.168.1.1", "any", -1, -1, -1, 1, 0); 453 | PrintRules(); 454 | printf("sending\n"); 455 | SendRules(); 456 | printf("send end\n"); 457 | char firewall_ip[20] = "192.168.152.1"; 458 | char nat_ip[20] = "192.168.164.2"; 459 | unsigned short firewall_port = 8888; 460 | unsigned short nat_port = 80; 461 | SetNat(ipstr_to_num("192.168.164.0"), 0xffffff00, ipstr_to_num("192.168.152.1")); 462 | AddNatRule(ipstr_to_num(nat_ip), ipstr_to_num(firewall_ip), nat_port, firewall_port); 463 | PrintNatRules(); 464 | SendNatRules(); 465 | 466 | //GetLogs(); 467 | //PrintLogs(); 468 | return 0; 469 | } 470 | -------------------------------------------------------------------------------- /MyFireWall/MyFireWall-cmd/get.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | //#include 11 | #include 12 | #include 13 | #include 14 | 15 | #define NETLINK_TEST (25) 16 | #define MAX_PAYLOAD (1024) 17 | #define TEST_PID (100) 18 | #define TCP 6 19 | #define UDP 17 20 | #define ICMP 1 21 | #define ANY -1 22 | #define MAX_RULE_NUM 50 23 | #define MAX_STATU_NUM 101 24 | #define MAX_NAT_NUM 100 25 | #define MAX_LOG_NUM 1000 26 | 27 | typedef struct { 28 | char src_ip[20]; 29 | char dst_ip[20]; 30 | short src_port; 31 | short dst_port; 32 | char protocol; 33 | bool action; 34 | bool log; 35 | }Rule; 36 | static Rule rules[MAX_RULE_NUM]; 37 | static int rnum = 0; //rules num 38 | 39 | typedef struct { 40 | unsigned src_ip; 41 | unsigned short src_port; 42 | unsigned dst_ip; 43 | unsigned short dst_port; 44 | unsigned char protocol; 45 | unsigned long t; 46 | }Connection; 47 | static Connection cons[MAX_STATU_NUM]; 48 | static int cnum = 0; 49 | 50 | typedef struct { 51 | //unsigned firewall_ip; 52 | unsigned nat_ip; 53 | unsigned short firewall_port; 54 | unsigned short nat_port; 55 | }NatEntry; 56 | static NatEntry natTable[MAX_NAT_NUM]; 57 | static int nnum = 0; //nat rules num 58 | unsigned net_ip = 0, net_mask = 0, firewall_ip = 0; 59 | 60 | typedef struct { 61 | unsigned src_ip; 62 | unsigned dst_ip; 63 | unsigned short src_port; 64 | unsigned short dst_port; 65 | unsigned char protocol; 66 | unsigned char action; 67 | }Log; 68 | static Log logs[MAX_LOG_NUM]; 69 | static int lnum = 0;//logs num 70 | 71 | /*----------------------------------------------------------------------------------------------------------------*/ 72 | unsigned ipstr_to_num(const char *ip_str){ 73 | int count = 0; 74 | unsigned tmp = 0,ip = 0, i; 75 | for(i = 0; i < strlen(ip_str); i++){ 76 | if(ip_str[i] == '.'){ 77 | ip = ip | (tmp << (8 * (3 - count))); 78 | tmp = 0; 79 | count++; 80 | continue; 81 | } 82 | tmp *= 10; 83 | tmp += ip_str[i] - '0'; 84 | } 85 | ip = ip | tmp; 86 | return ip; 87 | } 88 | 89 | char * addr_from_net(char * buff, __be32 addr){ 90 | __u8 *p = (__u8*)&addr; 91 | snprintf(buff, 16, "%u.%u.%u.%u", 92 | (__u32)p[0], (__u32)p[1], (__u32)p[2], (__u32)p[3]); 93 | return buff; 94 | } 95 | 96 | /*----------------------------------------------------------------------------------------------------------------*/ 97 | int netlink_create_socket(void) 98 | { 99 | //create a socket 100 | return socket(AF_NETLINK, SOCK_RAW, NETLINK_TEST); 101 | } 102 | 103 | int netlink_bind(int sock_fd) 104 | { 105 | struct sockaddr_nl addr; 106 | memset(&addr, 0, sizeof(struct sockaddr_nl)); 107 | addr.nl_family = AF_NETLINK; 108 | addr.nl_pid = TEST_PID; 109 | addr.nl_groups = 0; 110 | return bind(sock_fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_nl)); 111 | } 112 | 113 | int netlink_send_message(int sock_fd, const unsigned char *message, int len,unsigned int pid, unsigned int group) 114 | { 115 | struct nlmsghdr *nlh = NULL; 116 | struct sockaddr_nl dest_addr; 117 | struct iovec iov; 118 | struct msghdr msg; 119 | if( !message ) { 120 | return -1; 121 | } 122 | //create message 123 | nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(len)); 124 | if( !nlh ) { 125 | perror("malloc"); 126 | return -2; 127 | } 128 | nlh->nlmsg_len = NLMSG_SPACE(len); 129 | nlh->nlmsg_pid = TEST_PID; 130 | nlh->nlmsg_flags = 0; 131 | memcpy(NLMSG_DATA(nlh), message, len); 132 | iov.iov_base = (void *)nlh; 133 | iov.iov_len = nlh->nlmsg_len; 134 | memset(&dest_addr, 0, sizeof(struct sockaddr_nl)); 135 | dest_addr.nl_family = AF_NETLINK; 136 | dest_addr.nl_pid = pid; 137 | dest_addr.nl_groups = group; 138 | memset(&msg, 0, sizeof(struct msghdr)); 139 | msg.msg_name = (void *)&dest_addr; 140 | msg.msg_namelen = sizeof(struct sockaddr_nl); 141 | msg.msg_iov = &iov; 142 | msg.msg_iovlen = 1; 143 | //send message 144 | if( sendmsg(sock_fd, &msg, 0) < 0 ) 145 | { 146 | printf("send error!\n"); 147 | free(nlh); 148 | return -3; 149 | } 150 | free(nlh); 151 | return 0; 152 | } 153 | 154 | int netlink_recv_message(int sock_fd, unsigned char *message, int *len) 155 | { 156 | struct nlmsghdr *nlh = NULL; 157 | struct sockaddr_nl source_addr; 158 | struct iovec iov; 159 | struct msghdr msg; 160 | if( !message || !len ) { 161 | return -1; 162 | } 163 | //create message 164 | nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD)); 165 | if( !nlh ) { 166 | perror("malloc"); 167 | return -2; 168 | } 169 | iov.iov_base = (void *)nlh; 170 | iov.iov_len = NLMSG_SPACE(MAX_PAYLOAD); 171 | memset(&source_addr, 0, sizeof(struct sockaddr_nl)); 172 | memset(&msg, 0, sizeof(struct msghdr)); 173 | msg.msg_name = (void *)&source_addr; 174 | msg.msg_namelen = sizeof(struct sockaddr_nl); 175 | msg.msg_iov = &iov; 176 | msg.msg_iovlen = 1; 177 | if ( recvmsg(sock_fd, &msg, 0) < 0 ) { 178 | printf("recvmsg error!\n"); 179 | return -3; 180 | } 181 | *len = nlh->nlmsg_len - NLMSG_SPACE(0); 182 | memcpy(message, (unsigned char *)NLMSG_DATA(nlh), *len); 183 | free(nlh); 184 | return 0; 185 | } 186 | /*------------------------------------------------------------------*/ 187 | void print_IP(unsigned long int src_ip) 188 | { 189 | unsigned char src_i[4]; 190 | src_i[3] = src_ip%256; src_ip /= 256; 191 | src_i[2] = src_ip%256; src_ip /= 256; 192 | src_i[1] = src_ip%256; src_ip /= 256; 193 | src_i[0] = src_ip%256; src_ip /= 256; 194 | printf("%d.%d.%d.%d", src_i[0],src_i[1],src_i[2],src_i[3]); 195 | } 196 | 197 | void sprint_IP(char output[], unsigned long int src_ip) 198 | { 199 | unsigned char src_i[4]; 200 | src_i[3] = src_ip%256; src_ip /= 256; 201 | src_i[2] = src_ip%256; src_ip /= 256; 202 | src_i[1] = src_ip%256; src_ip /= 256; 203 | src_i[0] = src_ip%256; src_ip /= 256; 204 | sprintf(output, "%d.%d.%d.%d", src_i[0],src_i[1],src_i[2],src_i[3]); 205 | } 206 | 207 | /*------------------------------Rules-------------------------------*/ 208 | int SendRules() 209 | { 210 | int sock_fd; 211 | unsigned char buf[MAX_PAYLOAD]; 212 | unsigned char a[100]; 213 | int len; 214 | sock_fd = netlink_create_socket(); 215 | if(sock_fd == -1) { 216 | printf("socket error!\n"); 217 | return -1; 218 | } 219 | if( netlink_bind(sock_fd) < 0 ) { 220 | perror("bind"); 221 | close(sock_fd); 222 | exit(EXIT_FAILURE); 223 | } 224 | a[0] = 0; 225 | a[1] = rnum; 226 | memcpy(a + 2, rules, rnum * sizeof(Rule)); 227 | netlink_send_message(sock_fd, (const unsigned char *)a, rnum * sizeof(Rule) + 2, 0, 0); 228 | close(sock_fd); 229 | return 1; 230 | } 231 | 232 | bool AddRule( 233 | const char *src_ip, const char *dst_ip, 234 | unsigned short src_port, 235 | unsigned short dst_port, 236 | unsigned char protocol, 237 | bool action, bool log){ 238 | if(rnum < 100){ 239 | strcpy(rules[rnum].src_ip, src_ip); 240 | strcpy(rules[rnum].dst_ip, dst_ip); 241 | rules[rnum].src_port = src_port; 242 | rules[rnum].dst_port = dst_port; 243 | rules[rnum].protocol = protocol; 244 | rules[rnum].action = action; 245 | rules[rnum].log = log; 246 | rnum++; 247 | return true; 248 | } 249 | return false; 250 | } 251 | 252 | bool DelRule(int pos){ 253 | if(pos >= rnum || pos < 0) 254 | return false; 255 | memcpy(rules + pos, rules + pos + 1, sizeof(Rule) * (rnum - pos)); 256 | rnum--; 257 | return true; 258 | } 259 | 260 | void PrintRules(){ 261 | printf("|----------------------------------------------------------------------|\n"); 262 | printf("| src_ip | dst_ip |src_port|dst_port|protocol| action | log |\n"); 263 | printf("|----------------------------------------------------------------------|\n"); 264 | for(int i = 0; i < rnum; i++){ 265 | printf("|%15.20s|%15.20s|%7hd|%7hd|%7hhd|%7d|%7d|\n", rules[i].src_ip, rules[i].dst_ip, rules[i].src_port, rules[i].dst_port, rules[i].protocol, rules[i].action, rules[i].log); 266 | printf("|----------------------------------------------------------------------------------------------------------|\n"); 267 | } 268 | return; 269 | } 270 | 271 | /*----------------------------NAT RULES-----------------------------*/ 272 | int SendNatRules() 273 | { 274 | int sock_fd; 275 | unsigned char buf[MAX_PAYLOAD]; 276 | unsigned char a[100]; 277 | int len; 278 | sock_fd = netlink_create_socket(); 279 | if(sock_fd == -1) { 280 | printf("socket error!\n"); 281 | return -1; 282 | } 283 | if( netlink_bind(sock_fd) < 0 ) { 284 | perror("bind"); 285 | close(sock_fd); 286 | exit(EXIT_FAILURE); 287 | } 288 | a[0] = 1; 289 | a[1] = nnum; 290 | memcpy(a + 2, &net_ip, sizeof(unsigned)); 291 | memcpy(a + 6, &net_mask, sizeof(unsigned)); 292 | memcpy(a + 10, &firewall_ip, sizeof(unsigned)); 293 | memcpy(a + 14, natTable, nnum * sizeof(NatEntry)); 294 | netlink_send_message(sock_fd, (const unsigned char *)a, nnum * sizeof(NatEntry) + 14, 0, 0); 295 | close(sock_fd); 296 | return 1; 297 | } 298 | 299 | bool AddNatRule(unsigned nat_ip, unsigned firewall_ip, unsigned short nat_port, unsigned short firewall_port){ 300 | if(nnum < 100){ 301 | natTable[nnum].nat_ip = nat_ip; 302 | //natTable[nnum].firewall_ip = firewall_ip; 303 | natTable[nnum].nat_port = nat_port; 304 | natTable[nnum].firewall_port = firewall_port; 305 | nnum++; 306 | return true; 307 | } 308 | return false; 309 | } 310 | 311 | bool DelNatRule(int pos){ 312 | if(pos >= nnum || pos < 0) 313 | return false; 314 | memcpy(rules + pos, rules + pos + 1, sizeof(Rule) * (nnum - pos)); 315 | nnum--; 316 | return true; 317 | } 318 | 319 | void SetNat(unsigned net, unsigned mask, unsigned ip){ 320 | firewall_ip = ip; 321 | net_ip = net; 322 | net_mask = mask; 323 | } 324 | 325 | void PrintNatRules(){ 326 | printf("|----------------------------------------------------------------------|\n"); 327 | printf("| nat_ip | firewall_port | nat_port |\n"); 328 | printf("|----------------------------------------------------------------------|\n"); 329 | for(int i = 0; i < nnum; i++){ 330 | char buff[20], buff2[20]; 331 | printf("|%15s|%15d|%15d|\n",addr_from_net(buff2, natTable[i].nat_ip), natTable[i].firewall_port, natTable[i].nat_port); 332 | printf("|----------------------------------------------------------------------------------------------------------|\n"); 333 | } 334 | return; 335 | } 336 | 337 | /*--------------------------------------Log-------------------------------------*/ 338 | int GetLogs() 339 | { 340 | int sock_fd; 341 | //unsigned char buf[MAX_PAYLOAD]; 342 | unsigned char a[100]; 343 | unsigned char buf[1000 * sizeof(Log)]; 344 | int len; 345 | sock_fd = netlink_create_socket(); 346 | if(sock_fd == -1) { 347 | printf("socket error!\n"); 348 | return -1; 349 | } 350 | if( netlink_bind(sock_fd) < 0 ) { 351 | perror("bind"); 352 | close(sock_fd); 353 | exit(EXIT_FAILURE); 354 | } 355 | a[0] = 2; 356 | netlink_send_message(sock_fd, (const unsigned char *)a, 2, 0, 0); 357 | if( netlink_recv_message(sock_fd, buf, &len) == 0 ) { 358 | printf("recvlen:%d\n",len); 359 | memcpy(logs, buf, len); 360 | lnum = len / sizeof(Log); 361 | } 362 | close(sock_fd); 363 | return 1; 364 | } 365 | 366 | void PrintLogs(){ 367 | printf("Logs:\n"); 368 | for(int i = 0; i < lnum; i++){ 369 | char buff[20], buff2[20]; 370 | printf("|%15s|%15s|%5hu|%5hu|%5hhu|%5hhu\n", addr_from_net(buff, logs[i].src_ip), addr_from_net(buff2, logs[i].dst_ip), logs[i].src_port, logs[i].dst_port, logs[i].protocol, logs[i].action); 371 | } 372 | } 373 | /*---------------------------------------Statu list-------------------------------------*/ 374 | int GetConnections() 375 | { 376 | int sock_fd; 377 | //unsigned char buf[MAX_PAYLOAD]; 378 | unsigned char a[100]; 379 | unsigned char buf[101 * sizeof(Connection)]; 380 | int len; 381 | sock_fd = netlink_create_socket(); 382 | if(sock_fd == -1) { 383 | printf("socket error!\n"); 384 | return -1; 385 | } 386 | if( netlink_bind(sock_fd) < 0 ) { 387 | perror("bind"); 388 | close(sock_fd); 389 | exit(EXIT_FAILURE); 390 | } 391 | a[0] = 3; 392 | netlink_send_message(sock_fd, (const unsigned char *)a, 1, 0, 0); 393 | if( netlink_recv_message(sock_fd, buf, &len) == 0 ) { 394 | printf("recvlen:%d\n",len); 395 | memcpy(cons, buf, len); 396 | cnum = len / sizeof(Connection); 397 | } 398 | close(sock_fd); 399 | return 1; 400 | } 401 | 402 | void PrintConnections(){ 403 | printf("Connections:\n"); 404 | for(int i = 0; i < cnum; i++){ 405 | char buff[20], buff2[20]; 406 | printf("|%15s|%15s|%5hu|%5hu|%5hhu|\n", addr_from_net(buff, cons[i].src_ip), addr_from_net(buff2, cons[i].dst_ip), cons[i].src_port, cons[i].dst_port, cons[i].protocol); 407 | } 408 | } 409 | 410 | int main() 411 | { 412 | GetLogs(); 413 | PrintLogs(); 414 | GetConnections(); 415 | PrintConnections(); 416 | return 0; 417 | } 418 | -------------------------------------------------------------------------------- /MyFireWall/MyFireWall/MyFireWall.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2019-09-09T00:36:56 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui 8 | 9 | TARGET = MyFireWall 10 | TEMPLATE = app 11 | 12 | 13 | SOURCES += main.cpp\ 14 | mainwindow.cpp 15 | 16 | HEADERS += mainwindow.h \ 17 | MyfwApi.h 18 | 19 | FORMS += mainwindow.ui 20 | -------------------------------------------------------------------------------- /MyFireWall/MyFireWall/MyFireWall.pro.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | ProjectExplorer.Project.ActiveTarget 7 | 0 8 | 9 | 10 | ProjectExplorer.Project.EditorSettings 11 | 12 | true 13 | false 14 | 15 | Cpp 16 | 17 | CppGlobal 18 | 19 | 20 | 21 | QmlJS 22 | 23 | QmlJSGlobal 24 | 25 | 26 | 2 27 | System 28 | false 29 | 4 30 | true 31 | 1 32 | true 33 | 0 34 | true 35 | 0 36 | 8 37 | true 38 | 1 39 | true 40 | true 41 | true 42 | false 43 | 44 | 45 | 46 | ProjectExplorer.Project.PluginSettings 47 | 48 | 49 | 50 | ProjectExplorer.Project.Target.0 51 | 52 | Desktop 53 | Desktop 54 | Qt4ProjectManager.Target.DesktopTarget 55 | 0 56 | 0 57 | 0 58 | 59 | ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-linux-generic-elf-64bit./usr/bin/gdb 60 | 61 | 62 | qmake 63 | 64 | QtProjectManager.QMakeBuildStep 65 | false 66 | true 67 | 68 | false 69 | 70 | 71 | Make 72 | 73 | Qt4ProjectManager.MakeStep 74 | false 75 | 76 | 77 | 78 | 2 79 | Build 80 | 81 | ProjectExplorer.BuildSteps.Build 82 | 83 | 84 | 85 | Make 86 | 87 | Qt4ProjectManager.MakeStep 88 | true 89 | clean 90 | 91 | 92 | 1 93 | Clean 94 | 95 | ProjectExplorer.BuildSteps.Clean 96 | 97 | 2 98 | false 99 | 100 | Qt 4.8.1 in PATH (System) Release 101 | 102 | Qt4ProjectManager.Qt4BuildConfiguration 103 | 0 104 | /home/fgy/MyFireWall/MyFireWall-build-desktop-Qt_4_8_1_in_PATH__System__Release 105 | 1 106 | true 107 | 108 | 109 | ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-linux-generic-elf-64bit./usr/bin/gdb 110 | 111 | 112 | qmake 113 | 114 | QtProjectManager.QMakeBuildStep 115 | false 116 | true 117 | 118 | false 119 | 120 | 121 | Make 122 | 123 | Qt4ProjectManager.MakeStep 124 | false 125 | 126 | 127 | 128 | 2 129 | Build 130 | 131 | ProjectExplorer.BuildSteps.Build 132 | 133 | 134 | 135 | Make 136 | 137 | Qt4ProjectManager.MakeStep 138 | true 139 | clean 140 | 141 | 142 | 1 143 | Clean 144 | 145 | ProjectExplorer.BuildSteps.Clean 146 | 147 | 2 148 | false 149 | 150 | Qt 4.8.1 in PATH (System) Debug 151 | 152 | Qt4ProjectManager.Qt4BuildConfiguration 153 | 2 154 | /home/fgy/MyFireWall/MyFireWall-build-desktop-Qt_4_8_1_in_PATH__System__Debug 155 | 1 156 | true 157 | 158 | 2 159 | 160 | 161 | 0 162 | Deploy 163 | 164 | ProjectExplorer.BuildSteps.Deploy 165 | 166 | 1 167 | No deployment 168 | 169 | ProjectExplorer.DefaultDeployConfiguration 170 | 171 | 1 172 | 173 | true 174 | true 175 | 176 | 177 | false 178 | false 179 | false 180 | false 181 | false 182 | false 183 | false 184 | false 185 | true 186 | true 187 | 0.01 188 | 0.01 189 | 10 190 | 10 191 | true 192 | true 193 | 25 194 | 25 195 | 196 | 197 | true 198 | true 199 | valgrind 200 | valgrind 201 | 202 | 0 203 | 1 204 | 2 205 | 3 206 | 4 207 | 5 208 | 6 209 | 7 210 | 8 211 | 9 212 | 10 213 | 11 214 | 12 215 | 13 216 | 14 217 | 218 | 219 | 0 220 | 1 221 | 2 222 | 3 223 | 4 224 | 5 225 | 6 226 | 7 227 | 8 228 | 9 229 | 10 230 | 11 231 | 12 232 | 13 233 | 14 234 | 235 | MyFireWall 236 | 237 | Qt4ProjectManager.Qt4RunConfiguration 238 | 2 239 | 240 | MyFireWall.pro 241 | false 242 | false 243 | 244 | 245 | 3768 246 | true 247 | false 248 | false 249 | 250 | 1 251 | 252 | 253 | 254 | ProjectExplorer.Project.TargetCount 255 | 1 256 | 257 | 258 | ProjectExplorer.Project.Updater.EnvironmentId 259 | {b602281c-425d-4348-ad9e-bd5f352b24c9} 260 | 261 | 262 | ProjectExplorer.Project.Updater.FileVersion 263 | 10 264 | 265 | 266 | -------------------------------------------------------------------------------- /MyFireWall/MyFireWall/MyfwApi.h: -------------------------------------------------------------------------------- 1 | #ifndef MYFWAPI_H 2 | #define MYFWAPI_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | using namespace std; 19 | 20 | #define NETLINK_TEST (25) 21 | #define MAX_PAYLOAD (1024) 22 | #define TEST_PID (100) 23 | #define TCP 6 24 | #define UDP 17 25 | #define ICMP 1 26 | #define ANY -1 27 | #define MAX_RULE_NUM 50 28 | #define MAX_STATU_NUM 101 29 | #define MAX_NAT_NUM 100 30 | #define MAX_LOG_NUM 1000 31 | 32 | bool ac_or_drop = false; 33 | 34 | typedef struct { 35 | char src_ip[20]; 36 | char dst_ip[20]; 37 | int src_port; 38 | int dst_port; 39 | char protocol; 40 | bool action; 41 | bool log; 42 | }Rule; 43 | static Rule rules[MAX_RULE_NUM]; 44 | static int rnum = 0; //rules num 45 | 46 | typedef struct { 47 | unsigned src_ip; 48 | unsigned short src_port; 49 | unsigned dst_ip; 50 | unsigned short dst_port; 51 | unsigned char protocol; 52 | unsigned long t; 53 | }Connection; 54 | static Connection cons[MAX_STATU_NUM]; 55 | static int cnum = 0; 56 | 57 | typedef struct { 58 | //unsigned firewall_ip; 59 | unsigned nat_ip; 60 | unsigned short firewall_port; 61 | unsigned short nat_port; 62 | }NatEntry; 63 | static NatEntry natTable[MAX_NAT_NUM]; 64 | static int nnum = 0; //nat rules num 65 | unsigned net_ip = 0, net_mask = 0, firewall_ip = 0; 66 | 67 | typedef struct { 68 | unsigned src_ip; 69 | unsigned dst_ip; 70 | unsigned short src_port; 71 | unsigned short dst_port; 72 | unsigned char protocol; 73 | unsigned char action; 74 | }Log; 75 | static Log logs[MAX_LOG_NUM]; 76 | static int lnum = 0;//logs num 77 | 78 | /*----------------------------------------------------------------------------------------------------------------*/ 79 | unsigned ipstr_to_num(const char *ip_str){ 80 | int count = 0; 81 | unsigned tmp = 0,ip = 0, i; 82 | for(i = 0; i < strlen(ip_str); i++){ 83 | if(ip_str[i] == '.'){ 84 | ip = ip | (tmp << (8 * (3 - count))); 85 | tmp = 0; 86 | count++; 87 | continue; 88 | } 89 | tmp *= 10; 90 | tmp += ip_str[i] - '0'; 91 | } 92 | ip = ip | tmp; 93 | return ip; 94 | } 95 | 96 | char * addr_from_net(char * buff, __be32 addr){ 97 | __u8 *p = (__u8*)&addr; 98 | snprintf(buff, 16, "%u.%u.%u.%u", 99 | (__u32)p[0], (__u32)p[1], (__u32)p[2], (__u32)p[3]); 100 | return buff; 101 | } 102 | 103 | void Convert(unsigned &ip, unsigned &mask, const char *ip_range){ 104 | char tmp_ip[20]; 105 | int p = -1, count = 0; 106 | unsigned len = 0, tmp = 0, i; 107 | ip = 0, mask = 0; 108 | strcpy(tmp_ip, ip_range); 109 | for(i = 0; i < strlen(tmp_ip); i++){ 110 | if(p != -1){ 111 | len *= 10; 112 | len += tmp_ip[i] - '0'; 113 | } 114 | else if(tmp_ip[i] == '/') 115 | p = i; 116 | } 117 | if(p != -1){ 118 | tmp_ip[p] = '\0'; 119 | if(len) 120 | mask = 0xFFFFFFFF << (32 - len); 121 | } 122 | else mask = 0xFFFFFFFF; 123 | for(i = 0; i < strlen(tmp_ip); i++){ 124 | if(tmp_ip[i] == '.'){ 125 | ip = ip | (tmp << (8 * (3 - count))); 126 | tmp = 0; 127 | count++; 128 | continue; 129 | } 130 | tmp *= 10; 131 | tmp += tmp_ip[i] - '0'; 132 | } 133 | ip = ip | tmp; 134 | } 135 | /*----------------------------------------------------------------------------------------------------------------*/ 136 | int netlink_create_socket(void) 137 | { 138 | //create a socket 139 | return socket(AF_NETLINK, SOCK_RAW, NETLINK_TEST); 140 | } 141 | 142 | int netlink_bind(int sock_fd) 143 | { 144 | struct sockaddr_nl addr; 145 | memset(&addr, 0, sizeof(struct sockaddr_nl)); 146 | addr.nl_family = AF_NETLINK; 147 | addr.nl_pid = TEST_PID; 148 | addr.nl_groups = 0; 149 | return bind(sock_fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_nl)); 150 | } 151 | 152 | int netlink_send_message(int sock_fd, const unsigned char *message, int len,unsigned int pid, unsigned int group) 153 | { 154 | struct nlmsghdr *nlh = NULL; 155 | struct sockaddr_nl dest_addr; 156 | struct iovec iov; 157 | struct msghdr msg; 158 | if( !message ) { 159 | return -1; 160 | } 161 | //create message 162 | nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(len)); 163 | if( !nlh ) { 164 | perror("malloc"); 165 | return -2; 166 | } 167 | nlh->nlmsg_len = NLMSG_SPACE(len); 168 | nlh->nlmsg_pid = TEST_PID; 169 | nlh->nlmsg_flags = 0; 170 | memcpy(NLMSG_DATA(nlh), message, len); 171 | iov.iov_base = (void *)nlh; 172 | iov.iov_len = nlh->nlmsg_len; 173 | memset(&dest_addr, 0, sizeof(struct sockaddr_nl)); 174 | dest_addr.nl_family = AF_NETLINK; 175 | dest_addr.nl_pid = pid; 176 | dest_addr.nl_groups = group; 177 | memset(&msg, 0, sizeof(struct msghdr)); 178 | msg.msg_name = (void *)&dest_addr; 179 | msg.msg_namelen = sizeof(struct sockaddr_nl); 180 | msg.msg_iov = &iov; 181 | msg.msg_iovlen = 1; 182 | //send message 183 | if( sendmsg(sock_fd, &msg, 0) < 0 ) 184 | { 185 | printf("send error!\n"); 186 | free(nlh); 187 | return -3; 188 | } 189 | free(nlh); 190 | return 0; 191 | } 192 | 193 | int netlink_recv_message(int sock_fd, unsigned char *message, int *len) 194 | { 195 | struct nlmsghdr *nlh = NULL; 196 | struct sockaddr_nl source_addr; 197 | struct iovec iov; 198 | struct msghdr msg; 199 | if( !message || !len ) { 200 | return -1; 201 | } 202 | //create message 203 | nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD)); 204 | if( !nlh ) { 205 | perror("malloc"); 206 | return -2; 207 | } 208 | iov.iov_base = (void *)nlh; 209 | iov.iov_len = NLMSG_SPACE(MAX_PAYLOAD); 210 | memset(&source_addr, 0, sizeof(struct sockaddr_nl)); 211 | memset(&msg, 0, sizeof(struct msghdr)); 212 | msg.msg_name = (void *)&source_addr; 213 | msg.msg_namelen = sizeof(struct sockaddr_nl); 214 | msg.msg_iov = &iov; 215 | msg.msg_iovlen = 1; 216 | if ( recvmsg(sock_fd, &msg, 0) < 0 ) { 217 | printf("recvmsg error!\n"); 218 | return -3; 219 | } 220 | *len = nlh->nlmsg_len - NLMSG_SPACE(0); 221 | memcpy(message, (unsigned char *)NLMSG_DATA(nlh), *len); 222 | free(nlh); 223 | return 0; 224 | } 225 | 226 | /*------------------------------Rules-------------------------------*/ 227 | bool AddRule( 228 | const char *src_ip, const char *dst_ip, 229 | int src_port, 230 | int dst_port, 231 | char protocol, 232 | bool action, bool log) { 233 | if (rnum < 100) { 234 | strcpy(rules[rnum].src_ip, src_ip); 235 | strcpy(rules[rnum].dst_ip, dst_ip); 236 | rules[rnum].src_port = src_port; 237 | rules[rnum].dst_port = dst_port; 238 | rules[rnum].protocol = protocol; 239 | rules[rnum].action = action; 240 | rules[rnum].log = log; 241 | rnum++; 242 | return true; 243 | } 244 | return false; 245 | } 246 | 247 | bool DelRule(int pos) { 248 | if (pos >= rnum || pos < 0) 249 | return false; 250 | memcpy(rules + pos, rules + pos + 1, sizeof(Rule) * (rnum - pos)); 251 | rnum--; 252 | return true; 253 | } 254 | 255 | int SendRules() 256 | { 257 | if (ac_or_drop) { 258 | AddRule("any", "any", -1, -1, -1, 1, 0); 259 | } 260 | else AddRule("any", "any", -1, -1, -1, 0, 0); 261 | int sock_fd; 262 | unsigned char buf[MAX_PAYLOAD]; 263 | unsigned char a[5000]; 264 | int len; 265 | sock_fd = netlink_create_socket(); 266 | if(sock_fd == -1) { 267 | printf("socket error!\n"); 268 | return -1; 269 | } 270 | if( netlink_bind(sock_fd) < 0 ) { 271 | perror("bind"); 272 | close(sock_fd); 273 | exit(EXIT_FAILURE); 274 | } 275 | a[0] = 0; 276 | a[1] = rnum; 277 | memcpy(a + 2, rules, rnum * sizeof(Rule)); 278 | netlink_send_message(sock_fd, (const unsigned char *)a, rnum * sizeof(Rule) + 2, 0, 0); 279 | close(sock_fd); 280 | rnum--; 281 | return 1; 282 | } 283 | 284 | void SetDefault(bool flag) { 285 | ac_or_drop = flag; 286 | } 287 | 288 | /*----------------------------NAT RULES-----------------------------*/ 289 | int SendNatRules() 290 | { 291 | int sock_fd; 292 | unsigned char a[5000]; 293 | sock_fd = netlink_create_socket(); 294 | if(sock_fd == -1) { 295 | printf("socket error!\n"); 296 | return -1; 297 | } 298 | if( netlink_bind(sock_fd) < 0 ) { 299 | perror("bind"); 300 | close(sock_fd); 301 | exit(EXIT_FAILURE); 302 | } 303 | a[0] = 1; 304 | a[1] = nnum; 305 | memcpy(a + 2, &net_ip, sizeof(unsigned)); 306 | memcpy(a + 6, &net_mask, sizeof(unsigned)); 307 | memcpy(a + 10, &firewall_ip, sizeof(unsigned)); 308 | memcpy(a + 14, natTable, nnum * sizeof(NatEntry)); 309 | netlink_send_message(sock_fd, (const unsigned char *)a, nnum * sizeof(NatEntry) + 14, 0, 0); 310 | close(sock_fd); 311 | return 1; 312 | } 313 | 314 | bool AddNatRule(unsigned nat_ip, unsigned short nat_port, unsigned short firewall_port){ 315 | if(nnum < 100){ 316 | natTable[nnum].nat_ip = nat_ip; 317 | //natTable[nnum].firewall_ip = firewall_ip; 318 | natTable[nnum].nat_port = nat_port; 319 | natTable[nnum].firewall_port = firewall_port; 320 | nnum++; 321 | return true; 322 | } 323 | return false; 324 | } 325 | 326 | bool DelNatRule(int pos){ 327 | if(pos >= nnum || pos < 0) 328 | return false; 329 | memcpy(rules + pos, rules + pos + 1, sizeof(Rule) * (nnum - pos)); 330 | nnum--; 331 | return true; 332 | } 333 | 334 | void SetNat(unsigned net, unsigned mask, unsigned ip){ 335 | firewall_ip = ip; 336 | net_ip = net; 337 | net_mask = mask; 338 | } 339 | 340 | /*--------------------------------------Log-------------------------------------*/ 341 | int GetLogs() 342 | { 343 | int sock_fd; 344 | //unsigned char buf[MAX_PAYLOAD]; 345 | unsigned char a[100]; 346 | unsigned char buf[1000 * sizeof(Log)]; 347 | int len; 348 | sock_fd = netlink_create_socket(); 349 | if(sock_fd == -1) { 350 | printf("socket error!\n"); 351 | return -1; 352 | } 353 | if( netlink_bind(sock_fd) < 0 ) { 354 | perror("bind"); 355 | close(sock_fd); 356 | exit(EXIT_FAILURE); 357 | } 358 | a[0] = 2; 359 | netlink_send_message(sock_fd, (const unsigned char *)a, 2, 0, 0); 360 | if( netlink_recv_message(sock_fd, buf, &len) == 0 ) { 361 | printf("recvlen:%d\n",len); 362 | memcpy(logs, buf, len); 363 | lnum = len / sizeof(Log); 364 | } 365 | close(sock_fd); 366 | return 1; 367 | } 368 | 369 | /*---------------------------------------Statu list-------------------------------------*/ 370 | int GetConnections() 371 | { 372 | int sock_fd; 373 | //unsigned char buf[MAX_PAYLOAD]; 374 | unsigned char a[100]; 375 | unsigned char buf[101 * sizeof(Connection)]; 376 | int len; 377 | sock_fd = netlink_create_socket(); 378 | if(sock_fd == -1) { 379 | printf("socket error!\n"); 380 | return -1; 381 | } 382 | if( netlink_bind(sock_fd) < 0 ) { 383 | perror("bind"); 384 | close(sock_fd); 385 | exit(EXIT_FAILURE); 386 | } 387 | a[0] = 3; 388 | netlink_send_message(sock_fd, (const unsigned char *)a, 1, 0, 0); 389 | if( netlink_recv_message(sock_fd, buf, &len) == 0 ) { 390 | printf("recvlen:%d\n",len); 391 | memcpy(cons, buf, len); 392 | cnum = len / sizeof(Connection); 393 | } 394 | close(sock_fd); 395 | return 1; 396 | } 397 | 398 | #endif // MYFWAPI_H 399 | -------------------------------------------------------------------------------- /MyFireWall/MyFireWall/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "mainwindow.h" 3 | 4 | int main(int argc, char *argv[]) 5 | { 6 | QApplication a(argc, argv); 7 | MainWindow w; 8 | w.show(); 9 | 10 | return a.exec(); 11 | } 12 | -------------------------------------------------------------------------------- /MyFireWall/MyFireWall/mainwindow.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | #include "ui_mainwindow.h" 3 | #include "MyfwApi.h" 4 | 5 | MainWindow::MainWindow(QWidget *parent) : 6 | QMainWindow(parent), 7 | ui(new Ui::MainWindow) 8 | { 9 | ui->setupUi(this); 10 | setWindowTitle("MyFireWall-gui"); 11 | ui->reject_radioButton->setChecked(true); 12 | InitRuleTable(); 13 | InitNatTable(); 14 | InitStatuTable(); 15 | InitLogTable(); 16 | } 17 | 18 | MainWindow::~MainWindow() 19 | { 20 | delete ui; 21 | } 22 | 23 | void MainWindow::on_add_pushButton_clicked() 24 | { 25 | int row = ui->tableWidget_rule->rowCount(); 26 | ui->tableWidget_rule->insertRow(row); 27 | } 28 | 29 | void MainWindow::on_apply_pushButton_clicked() 30 | { 31 | short src_port, dst_port; 32 | char protocol; 33 | bool action, log; 34 | rnum = 0; 35 | int row = ui->tableWidget_rule->rowCount(); 36 | for(int i = 0; i < row; i++){ 37 | src_port = ui->tableWidget_rule->item(i, 2)->text().toShort(); 38 | dst_port = ui->tableWidget_rule->item(i, 3)->text().toShort(); 39 | protocol = ui->tableWidget_rule->item(i, 4)->text().toInt(); 40 | action = ui->tableWidget_rule->item(i, 5)->text().toInt(); 41 | log = ui->tableWidget_rule->item(i, 6)->text().toInt(); 42 | AddRule(ui->tableWidget_rule->item(i, 0)->text().toLatin1().data(), 43 | ui->tableWidget_rule->item(i, 1)->text().toLatin1().data(), 44 | src_port, dst_port, protocol, action, log); 45 | } 46 | SendRules(); 47 | } 48 | 49 | void MainWindow::on_del_pushButton_clicked() 50 | { 51 | int rowIndex = ui->tableWidget_rule->currentRow(); 52 | if (rowIndex != -1) 53 | ui->tableWidget_rule->removeRow(rowIndex); 54 | } 55 | 56 | 57 | void MainWindow::on_addnat_pushButton_clicked() 58 | { 59 | int row = ui->tableWidget_nat->rowCount(); 60 | ui->tableWidget_nat->insertRow(row); 61 | } 62 | 63 | void MainWindow::on_delnat_pushButton_clicked() 64 | { 65 | int rowIndex = ui->tableWidget_nat->currentRow(); 66 | if (rowIndex != -1) 67 | ui->tableWidget_nat->removeRow(rowIndex); 68 | } 69 | 70 | void MainWindow::on_applynat_pushButton_clicked() 71 | { 72 | unsigned firewall_ip, nat_ip, inet_ip, mask; 73 | firewall_ip = ipstr_to_num(ui->lineEdit->text().toLatin1().data()); 74 | Convert(inet_ip, mask, ui->lineEdit_2->text().toLatin1().data()); 75 | SetNat(inet_ip, mask, firewall_ip); 76 | unsigned short nat_port, firewall_port; 77 | nnum = 0; 78 | int row = ui->tableWidget_nat->rowCount(); 79 | for(int i = 0; i < row; i++){ 80 | nat_ip = ipstr_to_num(ui->tableWidget_nat->item(i, 0)->text().toLatin1().data()); 81 | nat_port = ui->tableWidget_nat->item(i, 1)->text().toShort(); 82 | firewall_port = ui->tableWidget_nat->item(i, 2)->text().toShort(); 83 | AddNatRule(nat_ip, nat_port, firewall_port); 84 | } 85 | SendNatRules(); 86 | } 87 | 88 | 89 | 90 | void MainWindow::on_pushButton_flashlink_clicked() 91 | { 92 | GetConnections(); 93 | ui->tableWidget_status->setRowCount(0); 94 | int row; 95 | char buff[20]; 96 | for(int i = 0; i < cnum; i++){ 97 | row = ui->tableWidget_status->rowCount(); 98 | ui->tableWidget_status->insertRow(row); 99 | ui->tableWidget_status->setItem(i, 0,new QTableWidgetItem(QString(QLatin1String(addr_from_net(buff, cons[i].src_ip))))); 100 | ui->tableWidget_status->setItem(i, 1,new QTableWidgetItem(QString(QLatin1String(addr_from_net(buff, cons[i].dst_ip))))); 101 | ui->tableWidget_status->setItem(i, 2,new QTableWidgetItem(QString::number(cons[i].src_port))); 102 | ui->tableWidget_status->setItem(i, 3,new QTableWidgetItem(QString::number(cons[i].dst_port))); 103 | ui->tableWidget_status->setItem(i, 4,new QTableWidgetItem(QString::number(cons[i].protocol))); 104 | } 105 | ui->tableWidget_status->show(); 106 | } 107 | 108 | void MainWindow::on_pushButton_flashlog_clicked() 109 | { 110 | GetLogs(); 111 | ui->tableWidget_logs->setRowCount(0); 112 | int row; 113 | char buff[20]; 114 | for(int i = 0; i < lnum; i++){ 115 | row = ui->tableWidget_logs->rowCount(); 116 | ui->tableWidget_logs->insertRow(row); 117 | qDebug() << QString(QLatin1String(addr_from_net(buff, logs[i].src_ip))) << endl; 118 | qDebug() << QString(QLatin1String(addr_from_net(buff, logs[i].dst_ip))) << endl; 119 | qDebug() << QString::number(logs[i].src_port) << endl; 120 | qDebug() << QString::number(logs[i].dst_port) << endl; 121 | qDebug() << QString::number(logs[i].protocol) << endl; 122 | qDebug() << QString::number(logs[i].action) << endl; 123 | ui->tableWidget_logs->setItem(i, 0,new QTableWidgetItem(QString(QLatin1String(addr_from_net(buff, logs[i].src_ip))))); 124 | ui->tableWidget_logs->setItem(i, 1,new QTableWidgetItem(QString(QLatin1String(addr_from_net(buff, logs[i].dst_ip))))); 125 | ui->tableWidget_logs->setItem(i, 2,new QTableWidgetItem(QString::number(logs[i].src_port))); 126 | ui->tableWidget_logs->setItem(i, 3,new QTableWidgetItem(QString::number(logs[i].dst_port))); 127 | ui->tableWidget_logs->setItem(i, 4,new QTableWidgetItem(QString::number(logs[i].protocol))); 128 | ui->tableWidget_logs->setItem(i, 5,new QTableWidgetItem(QString::number(logs[i].action))); 129 | } 130 | ui->tableWidget_logs->show(); 131 | } 132 | 133 | 134 | void MainWindow::InitRuleTable(){ 135 | QStringList header; 136 | header << "source ip" <<"dest ip" << "src port" << "dst port" << "protocol" << "action" << "has log"; 137 | ui->tableWidget_rule->setColumnCount(7); 138 | ui->tableWidget_rule->setSelectionBehavior(QAbstractItemView::SelectRows); 139 | ui->tableWidget_rule->setFocusPolicy(Qt::NoFocus); 140 | QHeaderView *headerView = ui->tableWidget_rule->verticalHeader(); 141 | headerView->setHidden(true); 142 | ui->tableWidget_rule->setHorizontalHeaderLabels(header); 143 | ui->tableWidget_rule->horizontalHeader()->resizeSection(0,160); 144 | ui->tableWidget_rule->horizontalHeader()->resizeSection(1,160); 145 | ui->tableWidget_rule->horizontalHeader()->resizeSection(2,70); 146 | ui->tableWidget_rule->horizontalHeader()->resizeSection(3,70); 147 | ui->tableWidget_rule->horizontalHeader()->resizeSection(4,70); 148 | ui->tableWidget_rule->horizontalHeader()->resizeSection(5,60); 149 | ui->tableWidget_rule->horizontalHeader()->resizeSection(6,60); 150 | } 151 | 152 | 153 | 154 | void MainWindow::InitNatTable(){ 155 | QStringList header; 156 | header << "nat ip" << "nat port" << "firewall port"; 157 | ui->tableWidget_nat->setColumnCount(3); 158 | ui->tableWidget_nat->setSelectionBehavior(QAbstractItemView::SelectRows); 159 | ui->tableWidget_nat->setFocusPolicy(Qt::NoFocus); 160 | QHeaderView *headerView = ui->tableWidget_nat->verticalHeader(); 161 | headerView->setHidden(true); 162 | ui->tableWidget_nat->setHorizontalHeaderLabels(header); 163 | ui->tableWidget_nat->horizontalHeader()->resizeSection(0,200); 164 | ui->tableWidget_nat->horizontalHeader()->resizeSection(1,100); 165 | ui->tableWidget_nat->horizontalHeader()->resizeSection(2,100); 166 | } 167 | 168 | void MainWindow::InitStatuTable(){ 169 | QStringList header; 170 | header << "source ip" <<"dest ip" << "src port" << "dst port" << "protocol"; 171 | ui->tableWidget_status->setColumnCount(5); 172 | ui->tableWidget_status->setSelectionBehavior(QAbstractItemView::SelectRows); 173 | ui->tableWidget_status->setFocusPolicy(Qt::NoFocus); 174 | QHeaderView *headerView = ui->tableWidget_status->verticalHeader(); 175 | headerView->setHidden(true); 176 | ui->tableWidget_status->setHorizontalHeaderLabels(header); 177 | ui->tableWidget_status->horizontalHeader()->resizeSection(0,187); 178 | ui->tableWidget_status->horizontalHeader()->resizeSection(1,187); 179 | ui->tableWidget_status->horizontalHeader()->resizeSection(2,90); 180 | ui->tableWidget_status->horizontalHeader()->resizeSection(3,90); 181 | ui->tableWidget_status->horizontalHeader()->resizeSection(4,90); 182 | } 183 | 184 | void MainWindow::InitLogTable(){ 185 | QStringList header; 186 | header << "source ip" <<"dest ip" << "src port" << "dst port" << "protocol" << "action"; 187 | ui->tableWidget_logs->setColumnCount(6); 188 | ui->tableWidget_logs->setSelectionBehavior(QAbstractItemView::SelectRows); 189 | ui->tableWidget_logs->setFocusPolicy(Qt::NoFocus); 190 | QHeaderView *headerView = ui->tableWidget_logs->verticalHeader(); 191 | headerView->setHidden(true); 192 | ui->tableWidget_logs->setHorizontalHeaderLabels(header); 193 | ui->tableWidget_logs->horizontalHeader()->resizeSection(0,165); 194 | ui->tableWidget_logs->horizontalHeader()->resizeSection(1,165); 195 | ui->tableWidget_logs->horizontalHeader()->resizeSection(2,80); 196 | ui->tableWidget_logs->horizontalHeader()->resizeSection(3,80); 197 | ui->tableWidget_logs->horizontalHeader()->resizeSection(4,80); 198 | ui->tableWidget_logs->horizontalHeader()->resizeSection(5,80); 199 | } 200 | 201 | void MainWindow::on_accept_radioButton_clicked() 202 | { 203 | SetDefault(true); 204 | } 205 | 206 | void MainWindow::on_reject_radioButton_clicked() 207 | { 208 | SetDefault(false); 209 | } 210 | -------------------------------------------------------------------------------- /MyFireWall/MyFireWall/mainwindow.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINWINDOW_H 2 | #define MAINWINDOW_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace Ui { 11 | class MainWindow; 12 | } 13 | 14 | class MainWindow : public QMainWindow 15 | { 16 | Q_OBJECT 17 | 18 | public: 19 | explicit MainWindow(QWidget *parent = 0); 20 | ~MainWindow(); 21 | void InitRuleTable(); 22 | void InitNatTable(); 23 | void InitStatuTable(); 24 | void InitLogTable(); 25 | 26 | private slots: 27 | void on_add_pushButton_clicked(); 28 | 29 | void on_del_pushButton_clicked(); 30 | 31 | void on_addnat_pushButton_clicked(); 32 | 33 | void on_delnat_pushButton_clicked(); 34 | 35 | void on_pushButton_flashlink_clicked(); 36 | 37 | void on_pushButton_flashlog_clicked(); 38 | 39 | void on_applynat_pushButton_clicked(); 40 | 41 | void on_apply_pushButton_clicked(); 42 | 43 | void on_accept_radioButton_clicked(); 44 | 45 | void on_reject_radioButton_clicked(); 46 | 47 | private: 48 | Ui::MainWindow *ui; 49 | }; 50 | 51 | #endif // MAINWINDOW_H 52 | -------------------------------------------------------------------------------- /MyFireWall/MyFireWall/mainwindow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 806 10 | 501 11 | 12 | 13 | 14 | MainWindow 15 | 16 | 17 | 18 | 19 | 20 | 10 21 | 0 22 | 791 23 | 431 24 | 25 | 26 | 27 | 0 28 | 29 | 30 | 31 | filter rules 32 | 33 | 34 | 35 | 36 | 10 37 | 10 38 | 651 39 | 381 40 | 41 | 42 | 43 | 44 | 45 | 46 | 680 47 | 30 48 | 98 49 | 27 50 | 51 | 52 | 53 | add 54 | 55 | 56 | 57 | 58 | 59 | 680 60 | 80 61 | 98 62 | 27 63 | 64 | 65 | 66 | del 67 | 68 | 69 | 70 | 71 | 72 | 680 73 | 330 74 | 91 75 | 22 76 | 77 | 78 | 79 | accept 80 | 81 | 82 | 83 | 84 | 85 | 680 86 | 360 87 | 91 88 | 22 89 | 90 | 91 | 92 | reject 93 | 94 | 95 | 96 | 97 | 98 | 680 99 | 130 100 | 98 101 | 27 102 | 103 | 104 | 105 | apply 106 | 107 | 108 | 109 | 110 | 111 | 670 112 | 300 113 | 66 114 | 17 115 | 116 | 117 | 118 | default: 119 | 120 | 121 | 122 | 123 | 124 | nat settings 125 | 126 | 127 | 128 | 129 | 650 130 | 350 131 | 98 132 | 27 133 | 134 | 135 | 136 | apply 137 | 138 | 139 | 140 | 141 | 142 | 650 143 | 300 144 | 98 145 | 27 146 | 147 | 148 | 149 | del 150 | 151 | 152 | 153 | 154 | 155 | 650 156 | 240 157 | 98 158 | 27 159 | 160 | 161 | 162 | add 163 | 164 | 165 | 166 | 167 | 168 | 10 169 | 10 170 | 401 171 | 381 172 | 173 | 174 | 175 | 176 | 177 | 178 | 550 179 | 60 180 | 211 181 | 31 182 | 183 | 184 | 185 | 186 | 187 | 188 | 550 189 | 140 190 | 211 191 | 31 192 | 193 | 194 | 195 | 196 | 197 | 198 | 490 199 | 30 200 | 91 201 | 17 202 | 203 | 204 | 205 | firewall ip: 206 | 207 | 208 | 209 | 210 | 211 | 490 212 | 110 213 | 131 214 | 17 215 | 216 | 217 | 218 | Intranet segment: 219 | 220 | 221 | 222 | 223 | 224 | statu links 225 | 226 | 227 | 228 | 229 | 670 230 | 30 231 | 98 232 | 27 233 | 234 | 235 | 236 | flash 237 | 238 | 239 | 240 | 241 | 242 | 10 243 | 10 244 | 641 245 | 371 246 | 247 | 248 | 249 | 250 | 251 | 252 | filter logs 253 | 254 | 255 | 256 | 257 | 680 258 | 30 259 | 98 260 | 27 261 | 262 | 263 | 264 | flash 265 | 266 | 267 | 268 | 269 | 270 | 10 271 | 10 272 | 651 273 | 371 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 0 284 | 0 285 | 806 286 | 25 287 | 288 | 289 | 290 | 291 | 292 | TopToolBarArea 293 | 294 | 295 | false 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 基于netfilter的防火墙系统 2 |   本防火墙基于netfilter实现,测试运行环境为Ubuntu12.04系统版本,内核版本:3.13.0-32-generic。实现了规则匹配,状态连接列表,动态nat转换,日志查询等功能。提供了应用程序界面以及命令行两种版本的用户程序。
3 |                                    ----2019年10月30日 作者:冯冠云 4 | ## 使用方式 5 |   在这里首先介绍如何部署及使用本防火墙中的代码。
6 |   要完成本实验共需要三台虚拟机(系统版本Ubuntu12.04,内核版本:3.13.0-32-generic),分别为内网主机,防火墙,外网主机。代码仅部署在充当防火墙的虚拟机中,但为了方便进行实验验证,我们仍需要在内网主机与外网主机中进行一定的设置。安装虚拟机的过程已经略去,虚拟机镜像下载地址:[华科镜像源Ubuntu12.04](http://mirror.hust.edu.cn/ubuntu-releases/12.04/ubuntu-12.04.5-desktop-amd64.iso)。
7 | ### VMWARE添加虚拟网卡 8 |   运行VMWARE,编辑->虚拟网络编辑器->更改设置。添加虚拟网卡VMnet2(192.168.164.0/24)和VMnet3(192.168.152.0/24)。添加后的配置如下:

9 |           

10 |   “右键虚拟机->设置->添加->网络适配器“可以为虚拟机添加网卡。内网主机添加虚拟网卡VMnet2,外网主机添加虚拟网卡VMnet3,防火墙添加VMnet2和VMnet3两个网卡。添加完成后三台虚拟机的网络拓扑图如下:
11 |

12 | 13 | ### 内网主机配置 14 |   进入内网主机对应的虚拟机系统,点击右上角设置标志,"system setting->Network->options->IPv4 Settings"设置静态ip地址为:`192.168.164.2`,并将其网关设置为`192.168.164.1`。设置如下:

15 |                  

16 |   安装apache,开启web服务。并可以通过修改`/var/www/index.html`来修改网页的内容。安装完成后打开浏览器,访问127.0.0.1,如果能正常访问,说明web服务已经开启。命令如下: 17 | ``` 18 | sudo apt-get install apache2 19 | sudo /etc/init.d/apache2 start 20 | ``` 21 | ### 外网主机配置 22 |   类似内网主机虚拟机的设置,设置静态ip:`192.168.152.2`,并将网关设置为`192.168.152.1`。安装并开启web服务。 23 | 24 | ### 防火墙主机配置 25 |   首先开启防火墙转发功能,使用命令`sudo echo 1 > /proc/sys/net/ipv4/ip_forward`开启该功能。开启后测试内网主机(192.168.164.2)是否可以ping通外网主机(192.168.152.2)如果可以,说明目前为止配置没有问题。 26 | 27 | #### 内核模块安装 28 | 将myfw文件夹拷贝到防火墙虚拟机中,执行以下命令: 29 | ``` 30 | cd myfw 31 | make clean 32 | make 33 | sudo insmod myfw.ko 34 | ``` 35 | #### 运行用户程序 36 | -------------------------------------------------------------------------------- /images/DNAT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuanyunFeng/MyFireWall-netfilter/ec365c1c7e819a20e86eacaf909651f7fbe99e1f/images/DNAT.png -------------------------------------------------------------------------------- /images/ipsetting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuanyunFeng/MyFireWall-netfilter/ec365c1c7e819a20e86eacaf909651f7fbe99e1f/images/ipsetting.png -------------------------------------------------------------------------------- /images/main.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuanyunFeng/MyFireWall-netfilter/ec365c1c7e819a20e86eacaf909651f7fbe99e1f/images/main.png -------------------------------------------------------------------------------- /images/nat_instance1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuanyunFeng/MyFireWall-netfilter/ec365c1c7e819a20e86eacaf909651f7fbe99e1f/images/nat_instance1.png -------------------------------------------------------------------------------- /images/nat_instance2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuanyunFeng/MyFireWall-netfilter/ec365c1c7e819a20e86eacaf909651f7fbe99e1f/images/nat_instance2.png -------------------------------------------------------------------------------- /images/net_diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuanyunFeng/MyFireWall-netfilter/ec365c1c7e819a20e86eacaf909651f7fbe99e1f/images/net_diagram.png -------------------------------------------------------------------------------- /images/snat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuanyunFeng/MyFireWall-netfilter/ec365c1c7e819a20e86eacaf909651f7fbe99e1f/images/snat.png -------------------------------------------------------------------------------- /images/status.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuanyunFeng/MyFireWall-netfilter/ec365c1c7e819a20e86eacaf909651f7fbe99e1f/images/status.png -------------------------------------------------------------------------------- /images/vmnet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuanyunFeng/MyFireWall-netfilter/ec365c1c7e819a20e86eacaf909651f7fbe99e1f/images/vmnet.png -------------------------------------------------------------------------------- /myfw/.tmp_versions/myfw.mod: -------------------------------------------------------------------------------- 1 | /home/fgy/myfw/myfw.ko 2 | /home/fgy/myfw/myfw_mod.o 3 | -------------------------------------------------------------------------------- /myfw/Makefile: -------------------------------------------------------------------------------- 1 | KERN_DIR = /lib/modules/$(shell uname -r)/build 2 | myfw-objs := myfw_mod.o #file2.o file3.o 3 | obj-m += myfw.o 4 | 5 | all: 6 | make -C $(KERN_DIR) M=$(shell pwd) modules 7 | clean: 8 | make -C $(KERN_DIR) M=$(shell pwd) modules clean 9 | rm -rf modules.order 10 | rm -f *.symvers 11 | -------------------------------------------------------------------------------- /myfw/myfw_mod.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | 49 | #define NETLINK_TEST (25) 50 | #define TCP 6 51 | #define UDP 17 52 | #define ICMP 1 53 | #define ANY -1 54 | #define ICMP_PORT 30001 55 | #define MAX_RULE_NUM 50 56 | #define MAX_STATU_NUM 101 57 | #define MAX_NAT_NUM 100 58 | #define MAX_LOG_NUM 100 59 | 60 | 61 | MODULE_LICENSE("GPL"); 62 | //MODULE_AUTHER("FGY"); 63 | 64 | //struct { __u32 pid; }user_process; 65 | 66 | typedef struct { 67 | char src_ip[20]; 68 | char dst_ip[20]; 69 | int src_port; 70 | int dst_port; 71 | char protocol; 72 | bool action; 73 | bool log; 74 | }Rule; 75 | static Rule rules[MAX_RULE_NUM]; 76 | static int rnum = 0; //rules num 77 | 78 | typedef struct { 79 | unsigned src_ip; 80 | unsigned short src_port; 81 | unsigned dst_ip; 82 | unsigned short dst_port; 83 | unsigned char protocol; 84 | unsigned long t; 85 | }Connection; 86 | static Connection cons[MAX_STATU_NUM]; 87 | static Connection cons2[MAX_STATU_NUM]; 88 | static int cnum = 0; //nat rules num 89 | 90 | typedef struct { 91 | //unsigned firewall_ip; 92 | unsigned nat_ip; 93 | unsigned short firewall_port; 94 | unsigned short nat_port; 95 | }NatEntry; 96 | static NatEntry natTable[MAX_NAT_NUM]; 97 | static int nnum = 0; //nat rules num 98 | unsigned net_ip, net_mask, firewall_ip; 99 | unsigned short firewall_port = 20000; 100 | 101 | typedef struct { 102 | unsigned src_ip; 103 | unsigned dst_ip; 104 | unsigned short src_port; 105 | unsigned short dst_port; 106 | unsigned char protocol; 107 | unsigned char action; 108 | }Log; 109 | static Log logs[MAX_LOG_NUM]; 110 | static int lnum = 0;//logs num 111 | 112 | static void netlink_input(struct sk_buff *__skb); 113 | unsigned int hook_func(unsigned int,struct sk_buff *,const struct net_device *, 114 | const struct net_device *,int(*okfn)(struct sk_buff*)); 115 | unsigned int hook_func_nat_in(unsigned int,struct sk_buff *,const struct net_device *, 116 | const struct net_device *,int(*okfn)(struct sk_buff*)); 117 | unsigned int hook_func_nat_out(unsigned int,struct sk_buff *,const struct net_device *, 118 | const struct net_device *,int(*okfn)(struct sk_buff*)); 119 | 120 | static dev_t devId; 121 | static struct class *cls = NULL; 122 | struct sock *nl_sk = NULL; 123 | struct netlink_kernel_cfg nkc = { 124 | .groups = 0, 125 | .flags = 0, 126 | .input = netlink_input, 127 | .cb_mutex = NULL, 128 | .bind = NULL, 129 | //nkc.unbind = NULL; 130 | .compare = NULL 131 | }; 132 | static struct nf_hook_ops input_filter = { 133 | .hook = (nf_hookfn *)hook_func, 134 | .owner = THIS_MODULE, 135 | .pf = PF_INET, 136 | .hooknum = NF_INET_PRE_ROUTING, 137 | .priority = NF_IP_PRI_FIRST 138 | }; // NF_INET_PRE_ROUTING - for incoming packets 139 | static struct nf_hook_ops output_filter = { 140 | .hook = (nf_hookfn *)hook_func, 141 | .owner = THIS_MODULE, 142 | .pf = PF_INET, 143 | .hooknum = NF_INET_POST_ROUTING, 144 | .priority = NF_IP_PRI_FIRST 145 | }; // NF_INET_POST_ROUTING - for outgoing packets 146 | static struct nf_hook_ops input_nat_filter = { 147 | .hook = (nf_hookfn *)hook_func_nat_in, 148 | .owner = THIS_MODULE, 149 | .pf = PF_INET, 150 | .hooknum = NF_INET_PRE_ROUTING, 151 | .priority = NF_IP_PRI_NAT_DST 152 | }; 153 | static struct nf_hook_ops output_nat_filter = { 154 | .hook = (nf_hookfn *)hook_func_nat_out, 155 | .owner = THIS_MODULE, 156 | .pf = PF_INET, 157 | .hooknum = NF_INET_POST_ROUTING, 158 | .priority = NF_IP_PRI_NAT_SRC 159 | }; 160 | 161 | /*-----------------------------------hash begin---------------------------------------------*/ 162 | //return 102: no empty places 163 | //return 101: find exist connection 164 | //return 0<=p<101: find places to insert 165 | unsigned CHashCheck(unsigned src_ip, unsigned dst_ip, unsigned char protocol, 166 | unsigned short src_port, unsigned short dst_port){ 167 | unsigned p = (src_ip ^ dst_ip ^ protocol ^ src_port ^ src_port) % 101; 168 | unsigned tmp = p; 169 | while(time_before(jiffies, cons[p].t)){ 170 | if((protocol == cons[p].protocol && src_ip == cons[p].src_ip && dst_ip == cons[p].dst_ip 171 | && src_port == cons[p].src_port && dst_port == cons[p].dst_port) || 172 | (protocol == cons[p].protocol && dst_ip == cons[p].src_ip && src_ip == cons[p].dst_ip 173 | && dst_port == cons[p].src_port && src_port == cons[p].dst_port)){ 174 | cons[p].t = jiffies + 10 * HZ; 175 | printk("hash check return 101 exist\n"); 176 | return 101; 177 | } 178 | p = (p + 7) % 101; 179 | if(p == tmp){ 180 | printk("hash check return 102 full\n"); 181 | return 102; 182 | } 183 | } 184 | printk("hash check return p:%u\n", p); 185 | return p; 186 | } 187 | 188 | void UpdateHashList(void){ 189 | int i; 190 | cnum = 0; 191 | for(i = 0; i < MAX_STATU_NUM; i++){ 192 | if(time_before(jiffies, cons[i].t)){ 193 | cons2[cnum].src_ip = cons[i].src_ip; 194 | cons2[cnum].dst_ip = cons[i].dst_ip; 195 | cons2[cnum].src_port = cons[i].src_port; 196 | cons2[cnum].dst_port = cons[i].dst_port; 197 | cons2[cnum].protocol = cons[i].protocol; 198 | cons2[cnum].t = 0; 199 | cnum++; 200 | } 201 | } 202 | } 203 | 204 | void CHashInsert(unsigned src_ip, unsigned dst_ip, unsigned char protocol, 205 | unsigned short src_port, unsigned short dst_port, unsigned p){ 206 | cons[p].src_ip = src_ip; 207 | cons[p].dst_ip = dst_ip; 208 | cons[p].src_port = src_port; 209 | cons[p].dst_port = dst_port; 210 | cons[p].protocol = protocol; 211 | cons[p].t = jiffies + 10 * HZ; 212 | } 213 | 214 | 215 | /*-----------------------------------tools begin------------------------------------------*/ 216 | bool IsMatch(unsigned ip, const char *ip_range){ 217 | char tmp_ip[20]; 218 | int p = -1, count = 0; 219 | unsigned len = 0, tmp = 0, mask = 0, r_ip = 0,i; 220 | strcpy(tmp_ip, ip_range); 221 | for(i = 0; i < strlen(tmp_ip); i++){ 222 | if(p != -1){ 223 | len *= 10; 224 | len += tmp_ip[i] - '0'; 225 | } 226 | else if(tmp_ip[i] == '/') 227 | p = i; 228 | } 229 | if(p != -1){ 230 | tmp_ip[p] = '\0'; 231 | if(len) 232 | mask = 0xFFFFFFFF << (32 - len); 233 | } 234 | else mask = 0xFFFFFFFF; 235 | for(i = 0; i < strlen(tmp_ip); i++){ 236 | if(tmp_ip[i] == '.'){ 237 | r_ip = r_ip | (tmp << (8 * (3 - count))); 238 | tmp = 0; 239 | count++; 240 | continue; 241 | } 242 | tmp *= 10; 243 | tmp += tmp_ip[i] - '0'; 244 | } 245 | r_ip = r_ip | tmp; 246 | return (r_ip & mask) == (ip & mask); 247 | } 248 | 249 | unsigned ipstr_to_num(const char *ip_str){ 250 | int count = 0; 251 | unsigned tmp = 0,ip = 0, i; 252 | for(i = 0; i < strlen(ip_str); i++){ 253 | if(ip_str[i] == '.'){ 254 | ip = ip | (tmp << (8 * (3 - count))); 255 | tmp = 0; 256 | count++; 257 | continue; 258 | } 259 | tmp *= 10; 260 | tmp += ip_str[i] - '0'; 261 | } 262 | ip = ip | tmp; 263 | return ip; 264 | } 265 | 266 | char * addr_from_net(char * buff, __be32 addr){ 267 | __u8 *p = (__u8*)&addr; 268 | snprintf(buff, 16, "%u.%u.%u.%u", 269 | (__u32)p[0], (__u32)p[1], (__u32)p[2], (__u32)p[3]); 270 | return buff; 271 | } 272 | void print_ip(unsigned long ip) { 273 | printk("%ld.%ld.%ld.%ld\n", (ip>>24)&0xff, (ip>>16)&0xff, (ip>>8)&0xff, (ip>>0)&0xff); 274 | } 275 | 276 | /*------------------------------------netlink begin--------------------------------------------------*/ 277 | static void netlink_cleanup(void) 278 | { 279 | netlink_kernel_release(nl_sk); 280 | device_destroy(cls, devId); 281 | class_destroy(cls); 282 | unregister_chrdev_region(devId, 1); 283 | } 284 | 285 | static void netlink_send(int pid, uint8_t *message, int len) 286 | { 287 | struct sk_buff *skb_1; 288 | struct nlmsghdr *nlh; 289 | if(!message || !nl_sk) { 290 | return; 291 | } 292 | skb_1 = alloc_skb(NLMSG_SPACE(len), GFP_KERNEL); 293 | if( !skb_1 ) { 294 | printk(KERN_ERR "alloc_skb error!\n"); 295 | } 296 | nlh = nlmsg_put(skb_1, 0, 0, 0, len, 0); 297 | NETLINK_CB(skb_1).portid = 0; 298 | NETLINK_CB(skb_1).dst_group = 0; 299 | memcpy(NLMSG_DATA(nlh), message, len); 300 | netlink_unicast(nl_sk, skb_1, pid, MSG_DONTWAIT); 301 | } 302 | 303 | static void netlink_input(struct sk_buff *__skb) 304 | { 305 | int i; 306 | struct sk_buff *skb; 307 | char str[1000]; 308 | char buff[20], buff2[20]; 309 | struct nlmsghdr *nlh; 310 | if( !__skb ) { 311 | return; 312 | } 313 | skb = skb_get(__skb); 314 | if( skb->len < NLMSG_SPACE(0)) { 315 | return; 316 | } 317 | nlh = nlmsg_hdr(skb); 318 | memset(str, 0, sizeof(str)); 319 | memcpy(str, NLMSG_DATA(nlh), 1000); 320 | //user_process.pid = nlh->nlmsg_pid; 321 | switch (str[0]) 322 | { 323 | case 0: 324 | //flush rules 325 | rnum = str[1]; 326 | memcpy(rules, str + 2, rnum * sizeof(Rule)); 327 | for(i = 0; i < rnum; i++){ 328 | printk("\n\n\n\n\nrnum:%d\n", i); 329 | printk("src_ip:%s\n", rules[i].src_ip); 330 | printk("dst_ip:%s\n", rules[i].dst_ip); 331 | printk("src_port:%d\n", rules[i].src_port); 332 | printk("dst_port:%d\n", rules[i].dst_port); 333 | printk("protocol:%d\n", rules[i].protocol); 334 | printk("log:%d\n", rules[i].log); 335 | printk("action:%d\n", rules[i].action); 336 | } 337 | break; 338 | case 1: 339 | //flush nat rules 340 | nnum = str[1]; 341 | memcpy(&net_ip, str + 2, sizeof(unsigned)); 342 | memcpy(&net_mask, str + 6, sizeof(unsigned)); 343 | memcpy(&firewall_ip, str + 10, sizeof(unsigned)); 344 | memcpy(&natTable[1], str + 14, nnum * sizeof(NatEntry)); 345 | natTable[0].firewall_port = 30001; 346 | natTable[0].nat_port = 30001; 347 | natTable[0].nat_ip = ipstr_to_num("192.168.1.1"); 348 | nnum++; 349 | printk("\n\n\n\n\nglobal_fireip:%s\nnet_ip:%s\nnet_mask:%x\n", addr_from_net(buff,ntohl(firewall_ip)), addr_from_net(buff2,ntohl(net_ip)), net_mask); 350 | for(i = 0; i < nnum; i++){ 351 | printk("nnum:%d\n", i); 352 | printk("nat_ip:%s\nfirewall_port:%u\nnat_port:%u\n", addr_from_net(buff2, natTable[i].nat_ip), natTable[i].firewall_port, natTable[i].nat_port); 353 | } 354 | break; 355 | case 2: 356 | //get logs 357 | for(i = 0; i < lnum; i++){ 358 | printk("\n\n\n\n\nlnum:%d\n", i); 359 | printk("src_ip:%s\n", addr_from_net(buff,ntohl(logs[i].src_ip))); 360 | printk("dst_ip:%s\n", addr_from_net(buff,ntohl(logs[i].dst_ip))); 361 | printk("src_port:%hu\n", logs[i].src_port); 362 | printk("dst_port:%hu\n", logs[i].dst_port); 363 | printk("protocol:%hhu\n", logs[i].protocol); 364 | printk("action:%hhu\n", logs[i].action); 365 | } 366 | netlink_send(nlh->nlmsg_pid, (uint8_t *)logs, lnum * sizeof(Log)); 367 | break; 368 | case 3: 369 | //get connections 370 | UpdateHashList(); 371 | for(i = 0; i < cnum; i++){ 372 | printk("\n\n\n\n\nlnum:%d\n", i); 373 | printk("src_ip:%s\n", addr_from_net(buff,ntohl(cons2[i].src_ip))); 374 | printk("dst_ip:%s\n", addr_from_net(buff,ntohl(cons2[i].dst_ip))); 375 | printk("src_port:%hu\n", cons2[i].src_port); 376 | printk("dst_port:%hu\n", cons2[i].dst_port); 377 | printk("protocol:%hhu\n", cons2[i].protocol); 378 | } 379 | netlink_send(nlh->nlmsg_pid, (uint8_t *)cons2, cnum * sizeof(Connection)); 380 | default: 381 | break; 382 | } 383 | return; 384 | } 385 | 386 | 387 | /*------------------------------------hook function--------------------------------------------------*/ 388 | void GetPort(struct sk_buff *skb, struct iphdr *hdr, unsigned short *src_port, unsigned short *dst_port){ 389 | struct tcphdr *mytcphdr; 390 | struct udphdr *myudphdr; 391 | switch(hdr->protocol){ 392 | case TCP: 393 | //printk("TCP package\n"); 394 | mytcphdr = (struct tcphdr *)(skb->data + (hdr->ihl * 4)); 395 | *src_port = ntohs(mytcphdr->source); 396 | *dst_port = ntohs(mytcphdr->dest); 397 | break; 398 | case UDP: 399 | //printk("UDP package\n"); 400 | myudphdr = (struct udphdr *)(skb->data + (hdr->ihl * 4)); 401 | *src_port = ntohs(myudphdr->source); 402 | *dst_port = ntohs(myudphdr->dest); 403 | break; 404 | case ICMP: 405 | //printk("ICMP package\n"); 406 | *src_port = 30001; 407 | *dst_port = 30001; 408 | break; 409 | default: 410 | printk("UNKNOW PROTOCOL\n"); 411 | *src_port = 0; 412 | *dst_port = 0; 413 | break; 414 | } 415 | } 416 | 417 | unsigned int hook_func(unsigned int hooknum, 418 | struct sk_buff *skb, 419 | const struct net_device *in, 420 | const struct net_device *out, 421 | int(*okfn)(struct sk_buff*)) 422 | { 423 | int ret, i; 424 | short src_port, dst_port; 425 | struct iphdr *hdr; 426 | //printk("in pre routing\n"); 427 | hdr = ip_hdr(skb); 428 | 429 | //get port information 430 | GetPort(skb, hdr, &src_port, &dst_port); 431 | //status list 432 | ret = CHashCheck(hdr->saddr, hdr->daddr, hdr->protocol, src_port, dst_port); 433 | if(ret == 101) return NF_ACCEPT; 434 | else if(ret == 102){ 435 | printk("connections list full!\n"); 436 | return NF_DROP; 437 | } 438 | else if(ret < 0 || ret >= 101){ 439 | printk("connections list error!\n"); 440 | return NF_DROP; 441 | } 442 | 443 | //rules matching 444 | for(i = 0; i < rnum;i ++){ 445 | printk("matching the %dth rules......\n", i); 446 | if(strcmp(rules[i].src_ip, "any") && !IsMatch(ntohl(hdr->saddr), rules[i].src_ip)) continue; 447 | if(strcmp(rules[i].dst_ip, "any") && !IsMatch(ntohl(hdr->daddr), rules[i].dst_ip)) continue; 448 | if(rules[i].protocol != ANY && rules[i].protocol != hdr->protocol) continue; 449 | if(rules[i].src_port != ANY && src_port != rules[i].src_port) continue; 450 | if(rules[i].dst_port != ANY && dst_port != rules[i].dst_port) continue; 451 | if(rules[i].log && lnum < 1000){ 452 | logs[lnum].dst_ip = hdr->daddr; 453 | logs[lnum].src_ip = hdr->saddr; 454 | logs[lnum].dst_port = dst_port; 455 | logs[lnum].src_port = src_port; 456 | logs[lnum].protocol = hdr->protocol; 457 | logs[lnum].action = rules[i].action; 458 | lnum++; 459 | } 460 | if(rules[i].action){ 461 | CHashInsert(hdr->saddr, hdr->daddr, hdr->protocol, src_port, dst_port, ret); 462 | printk("insert a connection with hash in %d\n", ret); 463 | return NF_ACCEPT; 464 | } 465 | else return NF_DROP; 466 | } 467 | 468 | CHashInsert(hdr->saddr, hdr->daddr, hdr->protocol, src_port, dst_port, ret); 469 | printk("insert a connection with hash in %d\n", ret); 470 | return NF_ACCEPT; 471 | } 472 | 473 | unsigned int hook_func_nat_in(unsigned int hooknum, 474 | struct sk_buff *skb, 475 | const struct net_device *in, 476 | const struct net_device *out, 477 | int(*okfn)(struct sk_buff*)) 478 | { 479 | int i, tot_len, hdr_len; 480 | unsigned short src_port, dst_port; 481 | struct iphdr *hdr; 482 | struct tcphdr *tcph; 483 | struct udphdr *udph; 484 | hdr = ip_hdr(skb); 485 | printk("nat_in:%s->%s\n", in->name, out->name); 486 | printk("this pkt src ip is "); 487 | print_ip(ntohl(hdr->saddr)); 488 | printk("this pkt dst ip is "); 489 | print_ip(ntohl(hdr->daddr)); 490 | GetPort(skb, hdr, &src_port, &dst_port); 491 | printk("src_port:%hu dst_port:%hu\n", src_port, dst_port); 492 | for(i = 0; i < nnum; i++){ 493 | if(ntohl(hdr->daddr) == firewall_ip && dst_port == natTable[i].firewall_port){ 494 | printk("match dnat rules!\n"); 495 | hdr->daddr = ntohl(natTable[i].nat_ip); 496 | hdr_len = ip_hdrlen(skb); 497 | tot_len = ntohs(hdr->tot_len); 498 | hdr->check = 0; 499 | hdr->check = ip_fast_csum(hdr,hdr->ihl); 500 | 501 | switch(hdr->protocol) { 502 | case TCP: 503 | tcph = (struct tcphdr *)(skb->data + (hdr->ihl * 4)); 504 | tcph->dest = htons(natTable[i].nat_port); 505 | tcph->check = 0; 506 | skb->csum = csum_partial((unsigned char *)tcph, tot_len - hdr_len,0); 507 | tcph->check = csum_tcpudp_magic(hdr->saddr, 508 | hdr->daddr, 509 | ntohs(hdr->tot_len) - hdr_len,hdr->protocol, 510 | skb->csum); 511 | break; 512 | case UDP: 513 | udph = (struct udphdr *)(skb->data + (hdr->ihl * 4)); 514 | udph->dest = htons(natTable[i].nat_port); 515 | udph->check = 0; 516 | skb->csum = csum_partial((unsigned char *)udph, tot_len - hdr_len,0); 517 | udph->check = csum_tcpudp_magic(hdr->saddr, 518 | hdr->daddr, 519 | ntohs(hdr->tot_len) - hdr_len,hdr->protocol, 520 | skb->csum); 521 | break; 522 | case ICMP: 523 | break; 524 | } 525 | 526 | printk("this pkt src ip is "); 527 | print_ip(ntohl(hdr->saddr)); 528 | printk("this pkt dst ip is "); 529 | print_ip(ntohl(hdr->daddr)); 530 | printk("\n"); 531 | return NF_ACCEPT; 532 | } 533 | } 534 | 535 | printk("this pkt src ip is "); 536 | print_ip(ntohl(hdr->saddr)); 537 | printk("this pkt dst ip is "); 538 | print_ip(ntohl(hdr->daddr)); 539 | printk("\n"); 540 | return NF_ACCEPT; 541 | } 542 | 543 | //进行源地址nat转换,如果nat列表中不存在,则添加一条 544 | unsigned int hook_func_nat_out(unsigned int hooknum, 545 | struct sk_buff *skb, 546 | const struct net_device *in, 547 | const struct net_device *out, 548 | int(*okfn)(struct sk_buff*)) 549 | { 550 | int i, tot_len, hdr_len; 551 | unsigned short src_port, dst_port; 552 | struct iphdr *hdr; 553 | struct tcphdr *tcph; 554 | struct udphdr *udph; 555 | hdr = ip_hdr(skb); 556 | printk("nat out:%s->%s\n", in->name, out->name); 557 | printk("this pkt src ip is "); 558 | print_ip(ntohl(hdr->saddr)); 559 | printk("this pkt dst ip is "); 560 | print_ip(ntohl(hdr->daddr)); 561 | GetPort(skb, hdr, &src_port, &dst_port); 562 | printk("src_port:%u dst_port:%u\n", src_port, dst_port); 563 | for(i = 0; i < nnum; i++){ 564 | if(ntohl(hdr->saddr) == natTable[i].nat_ip && src_port == natTable[i].nat_port){ 565 | printk("match snat rules!\n"); 566 | hdr->saddr = ntohl(firewall_ip); 567 | hdr_len = ip_hdrlen(skb); 568 | tot_len = ntohs(hdr->tot_len); 569 | hdr->check = 0; 570 | hdr->check = ip_fast_csum(hdr,hdr->ihl); 571 | 572 | switch(hdr->protocol) { 573 | case TCP: 574 | tcph = (struct tcphdr *)(skb->data + (hdr->ihl * 4)); 575 | tcph->source = htons(natTable[i].firewall_port); 576 | tcph->check = 0; 577 | skb->csum = csum_partial((unsigned char *)tcph, tot_len - hdr_len,0); 578 | tcph->check = csum_tcpudp_magic(hdr->saddr, 579 | hdr->daddr, 580 | ntohs(hdr->tot_len) - hdr_len,hdr->protocol, 581 | skb->csum); 582 | break; 583 | case UDP: 584 | udph = (struct udphdr *)(skb->data + (hdr->ihl * 4)); 585 | udph->source = htons(natTable[i].firewall_port); 586 | udph->check = 0; 587 | skb->csum = csum_partial((unsigned char *)udph, tot_len - hdr_len,0); 588 | udph->check = csum_tcpudp_magic(hdr->saddr, 589 | hdr->daddr, 590 | ntohs(hdr->tot_len) - hdr_len,hdr->protocol, 591 | skb->csum); 592 | break; 593 | case ICMP: 594 | break; 595 | } 596 | 597 | printk("this pkt src ip is "); 598 | print_ip(ntohl(hdr->saddr)); 599 | printk("this pkt dst ip is "); 600 | print_ip(ntohl(hdr->daddr)); 601 | printk("\n"); 602 | return NF_ACCEPT; 603 | } 604 | } 605 | 606 | if((ntohl(hdr->saddr) & net_mask) == (net_ip & net_mask)){ 607 | printk("add a nat rule!\n"); 608 | if(hdr->protocol == ICMP){ 609 | natTable[0].nat_ip = ntohl(hdr->saddr); 610 | natTable[0].nat_port = 30001; 611 | natTable[0].firewall_port = 30001; 612 | return NF_REPEAT; 613 | } 614 | natTable[nnum].nat_ip = ntohl(hdr->saddr); 615 | natTable[nnum].nat_port = src_port; 616 | natTable[nnum].firewall_port = firewall_port; 617 | firewall_port++; 618 | nnum++; 619 | return NF_REPEAT; 620 | } 621 | 622 | printk("this pkt src ip is "); 623 | print_ip(ntohl(hdr->saddr)); 624 | printk("this pkt dst ip is "); 625 | print_ip(ntohl(hdr->daddr)); 626 | printk("\n"); 627 | return NF_ACCEPT; 628 | } 629 | 630 | static int myfw_init(void) 631 | { 632 | int result; 633 | nf_register_hook(&input_filter); 634 | nf_register_hook(&output_filter); 635 | nf_register_hook(&input_nat_filter); 636 | nf_register_hook(&output_nat_filter); 637 | 638 | if(( result = alloc_chrdev_region(&devId, 0, 1, "stone-alloc-dev") ) != 0) { 639 | printk(KERN_WARNING "register dev id error:%d\n", result); 640 | netlink_cleanup(); 641 | return -1; 642 | } 643 | else printk(KERN_WARNING "register dev id success!\n"); 644 | //动态创建设备节点 645 | cls = class_create(THIS_MODULE, "stone-class"); 646 | if(IS_ERR(cls)) { 647 | printk(KERN_WARNING "create class error!\n"); 648 | netlink_cleanup(); 649 | return -1; 650 | } 651 | if(device_create(cls, NULL, devId, "", "hello%d", 0) == NULL) { 652 | printk(KERN_WARNING "create device error!\n"); 653 | netlink_cleanup(); 654 | return -1; 655 | } 656 | 657 | nl_sk = netlink_kernel_create(&init_net, NETLINK_TEST, &nkc); 658 | if( !nl_sk ) { 659 | printk(KERN_ERR "[netlink] create netlink socket error!\n"); 660 | netlink_cleanup(); 661 | return -1; 662 | } 663 | printk(KERN_ALERT "netlink init success!\n"); 664 | return 0; 665 | } 666 | 667 | static void myfw_exit(void) 668 | { 669 | printk("kexec test exit...\n"); 670 | nf_unregister_hook(&input_filter); 671 | nf_unregister_hook(&output_filter); 672 | nf_unregister_hook(&input_nat_filter); 673 | nf_unregister_hook(&output_nat_filter); 674 | netlink_cleanup(); 675 | } 676 | 677 | module_init(myfw_init); 678 | module_exit(myfw_exit); --------------------------------------------------------------------------------