windows客户端上安装vscode和putty。
我纯粹是把vscode作为一个远程书写工具。编译工作是通过putty在服务器中执行make命令完成。因此我的vscode只安装了SSH插件和C/C++插件。为了让vscode在书写C/C++代码有智能提示,我在vscode配置文件c_cpp_properties.json中添加了头文件路径:
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**",
"/usr/src/kernels/3.10.0-1160.15.2.el7.x86_64/include/**",
"/usr/src/kernels/3.10.0-1160.15.2.el7.x86_64/arch/x86/include/**"
],
"defines": [
"__KERNEL__",
"__GNUC__"],
"compilerPath": "/usr/bin/gcc",
"cStandard": "gnu17",
"cppStandard": "c++14",
"intelliSenseMode": "linux-gcc-x64"
}
],
"version": 4
}
我之前使用的阿里云centos8上面是预装了linux内核源码的,相关一些设置阿里云应该都替用户弄好了。后来换了另一运营商的centos7,没有预装内核源码。安装内核源码并不困难,但安装完毕后暴露出许多问题。
首先是代码中的头文件飘红,似乎c_cpp_properties.json并不管用。不理它强行make编译,结果抛出海量错误。经研究是安装内核源码后没有添加gcc头文件搜索路径所致,可以在vi /etc/profile 在尾部添加:
# C
export C_INCLUDE_PATH=/usr/src/kernels/3.10.0-1160.15.2.el7.x86_64/include/**:/usr/src/kernels/3.10.0-1160.15.2.el7.x86_64/arch/x86/include/**
# CPP
export CPLUS_INCLUDE_PATH=/usr/src/kernels/3.10.0-1160.15.2.el7.x86_64/include/**:/usr/src/kernels/3.10.0-1160.15.2.el7.x86_64/arch/x86/include/**
然后执行source /etc/profile使更改生效。
vscode只是作为一个远程书写工具,除了我输入的代码外,其它相关参数,都是vscode在读取远程服务器上配置后显示的
第二个问题是centos7默认安装的gcc版本较低,不支持新的C/C++语言特性,可能会造成编译错误,需要升级gcc。
第三个问题是编译时提示“Cannot use CONFIG_STACK_VALIDATION, please install libelf-dev or elfutils-libelf-devel”
解决方法是“yum install elfutils-libelf-devel”
第四个问题是编译时提示“module verification failed: signature and/or required key missing - tainting kernel”
解决方法是在Makefile第一行添加“CONFIG_MODULE_SIG=n”,注意重新编译前先rmmod掉刚才加载的同名内核驱动。
下面是我centos7下netfilter示例程序,它会在加载入内核后10分钟内禁止icmp协议,使得对网站ping操作失效。
#include <linux/time.h>
#include <linux/netdevice.h>
#include "linux/module.h"
#include "linux/netfilter_ipv4.h"
#include "linux/kernel.h"
#include "linux/kern_levels.h"
#include "linux/skbuff.h"
#include "linux/ip.h"
#include <linux/inet.h>
#include "linux/if_ether.h"
#include "linux/if_packet.h"
#include "linux/init.h"
static struct timespec start;
static struct timespec now;
/*copyright statement*/
MODULE_LICENSE("Dual BSD/GPL");
static unsigned int nf_hook_out(unsigned int hooknum,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff*))
{
struct sk_buff *sk = skb;
struct iphdr *iph=ip_hdr(sk);
now = current_kernel_time();
if(iph->protocol==IPPROTO_ICMP)
{
if(now.tv_sec - start.tv_sec < 600){
return NF_DROP;
}
else{
return NF_ACCEPT;
}
}else
{
return NF_ACCEPT;
}
}
static struct nf_hook_ops nfout=
{
.list = {NULL,NULL},
.hook = nf_hook_out,
.hooknum = NF_INET_LOCAL_OUT,
.pf = PF_INET,
.priority = NF_IP_PRI_FIRST
};
/*initialization module*/
static int __init banping_init(void)
{
nf_register_hook(&nfout);
start = current_kernel_time();
printk(KERN_ALERT"Banping module init%ld\n",start.tv_sec);
return 0;
}
/*clear module*/
static void __exit banping_exit(void)
{
nf_unregister_hook(&nfout);
printk(KERN_ALERT"Banping module exit\n");
}
module_init(banping_init);
module_exit(banping_exit);
MODULE_AUTHOR("FEI FENG");
MODULE_DESCRIPTION("Ban ping");
MODULE_VERSION("0.0.1");
CONFIG_MODULE_SIG=n
KERNELDIR :=/usr/src/kernels/3.10.0-1160.15.2.el7.x86_64
CURRENT_PATH :=$(shell pwd)
obj-m := netflt.o
build:kernel_modules
kernel_modules:
$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) modules
clean:
$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean