iptables配置笔记

tinyfisher 发表于 2012-12-05
1.配置准备
#iptables -F //清除原有规则
#iptables -X //清除自定义链
 
2.定义策略
#iptables -P INPUT DROP //默认丢弃,即丢弃所有的包
#iptables -P OUTPUT DROP
#iptables -P FORWARD DROP
 
3.典型的规则配置实例
# iptables -A INPUT|OUTPUT|FORWARD -s 源IP -d 目的IP -p tcp|udp|icmp --sport 源端口--dport 目的端口 -j ACCEPT|DROP
 
4.添加规则
####################
#开放HTTP
####################
#iptables -A INPUT -p tcp --sport 80 -j ACCEPT //针对本机,若本机不需要,可省略
#iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT
#iptables -A FORWARD -p tcp --sport 80 -j ACCEPT //允许转发
#iptables -A FORWARD -p tcp --dport 80 -j ACCEPT //下面类似
 
####################
#开放DNS
####################
#iptables -A INPUT -p udp --sport 53 -j ACCEPT
#iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
#iptables -A FORWARD -p udp --sport 53 -j ACCEPT
#iptables -A FORWARD -p udp --dport 53 -j ACCEPT
 
####################
#开放SMTP和POP3
####################
#iptables -A INPUT -p tcp --sport 25 -j ACCEPT
#iptables -A OUTPUT -p tcp --dport 25 -j ACCEPT
#iptables -A INPUT -p tcp --sport 110 -j ACCEPT
#iptables -A OUTPUT -p tcp --dport 110 -j ACCEPT
#iptables -A FORWARD -p tcp --sport 25 -j ACCEPT
#iptables -A FORWARD -p tcp --dport 25 -j ACCEPT
#iptables -A FORWARD -p tcp --sport 110 -j ACCEPT
#iptables -A FORWARD -p tcp --dport 110 -j ACCEPT
 
####################
#开放SSH
####################
#iptables -A INPUT -p tcp --sport 22 -j ACCEPT
#iptables -A OUTPUT -p tcp --dport 22 -j ACCEPT
#iptables -A FORWARD -p tcp --sport 22 -j ACCEPT
#iptables -A FORWARD -p tcp --dport 22 -j ACCEPT
 
####################
#开放Telnet
####################
#iptables -A INPUT -p tcp --sport 23 -j ACCEPT
#iptables -A OUTPUT -p tcp --dport 23 -j ACCEPT
#iptables -A FORWARD -p tcp --sport 23 -j ACCEPT
#iptables -A FORWARD -p tcp --dport 23 -j ACCEPT
 
####################
#开放FTP
####################
#iptables -A INPUT -p tcp --sport 21 -j ACCEPT
#iptables -A OUTPUT -p tcp --dport 21 -j ACCEPT
#iptables -A FORWARD -p tcp --sport 21 -j ACCEPT
#iptables -A FORWARD -p tcp --dport 21 -j ACCEPT
#iptables -A INPUT -p tcp --sport 20 -j ACCEPT
#iptables -A OUTPUT -p tcp --dport 20 -j ACCEPT
#iptables -A FORWARD -p tcp --sport 20 -j ACCEPT
#iptables -A FORWARD -p tcp --dport 20 -j ACCEPT
 
####################
#开放SSL
####################
#iptables -A INPUT -p tcp --sport 443 -j ACCEPT
#iptables -A OUTPUT -p tcp --dport 443 -j ACCEPT
#iptables -A FORWARD -p tcp --sport 443 -j ACCEPT
#iptables -A FORWARD -p tcp --dport 443 -j ACCEPT
 
####################
#开放ICMP
####################
#iptables -A INPUT -p icmp -j ACCEPT
#iptables -A OUTPUT -p icmp -j ACCEPT
#iptables -A FORWARD -p icmp -j ACCEPT
#iptables -A FORWARD -p icmp -j ACCEPT
 
####################
#开放TCP
####################
#iptables -A INPUT -p tcp -j ACCEPT
#iptables -A OUTPUT -p tcp -j ACCEPT
#iptables -A FORWARD -p tcp -j ACCEPT
#iptables -A FORWARD -p tcp -j ACCEPT
 
####################
#开放udp
####################
#iptables -A INPUT -p udp -j ACCEPT
#iptables -A OUTPUT -p udp -j ACCEPT
#iptables -A FORWARD -p udp -j ACCEPT
#iptables -A FORWARD -p udp -j ACCEPT
 
####################
#实现NAT
####################
#iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j SNAT --to-source 1.2.3.4
#iptables -t nat -A PREROUTING -d 192.168.1.0/24 -i eth1 -j DNAT --to-destination 1.2.3.4
 
####################
#规则的保存和重载
####################
#iptables-save -c > /etc/iptables-save
#iptables-restore -c < /etc/iptables-save
####################
#根据数据出入网卡匹配,假设eth0连接内网,eth1连接外网
####################
#iptables –A INPUT –i eth0 –j ACCEPT  //从eth0流入的数据都接收
#iptables – A FORWARD – o eth1 –j ACCEPT //从eth1流出的数据都转发 以上是一些基本配置,可以开放更多的服务,还可以进行更详尽的匹配,如源目地址,出入网卡等,以后可以根据要求进一步设置。

makefile 编写问题记录

tinyfisher 发表于 2012-11-23

最近写了个小程序,用到了pow()函数,我们都知道需要添加头文件<math.h>,以及在gcc编译的侍侯加上-lm选项,但是这个-lm选项的位值也是有讲究的,我之前的makefile如下:

solution:solution.o
     gcc  -lm solution.o  -o solution 
solution.o:solution.c
     gcc  -c  solution.c

报出错误:undefined reference to pow

原因是-lm的位置在solution.o之前,所以编译器链接的时侯先去链接lm库,之后无法解释solution.o里的pow函数

对于C/C++编译而言,读取编译选项是按照从左到右的顺序执行的。那么当编译器遇到源文件的时候,就开始对源文件中用到的函数进行解析,找到相对应的函数的函数体或者说是实现(Definition of Function)。这个过程是按照先遇到不能解析的函数(unresolved function),然后在源文件选项后面的一些选项中寻找可能的函数体的信息,是这样的一个顺序进行的。那么我们可以发现对于 Makefile,由于包含函数体或者函数定义信息的编译选项出现在源文件之前,那么当编译器在源文件中遇到不能解析的函数时,在源文件之后的选项中寻找相关的信息,那么就出现了编译错误,也就是无法找到相关的函数定义。

所以正确的makefile如下:

solution:solution.o
     gcc  solution.o  -o solution  -lm
solution.o:solution.c
     gcc  -c  solution.c

总结:始终将-l库函数选项放在编译命令的最右边

DP实例之01背包问题C语言实现

tinyfisher 发表于 2012-11-02

####问题描述: 有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放。

用子问题定义状态:即f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。则其状态转移方程便是:f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}

用二维数组记录每个子问题的值,避免重复计算,行从0到N,列从0到V。f[][0]=0,f[0][]=0;

很容易算出01背包的时间和空间复杂度,O(V*N)

C语言代码实现如下:

int Bag()  
{  
    int i,j;  
    int num=4;      //有4个物品  
    int vol=10;     //背包容量为10  
    int w[5]={0,3,1,4,3}; //此处需要多添加一个首元素元素0,因为下面的循环从1开始,若不添加0,则i-1会出现数组越界  
    int v[5]={0,1,3,4,2};//此处需要多添加一个首元素元素0,因为下面的循环从1开始,若不添加0,则i-1会出现数组越界  
    int f[5][11]={0}; //用来保存结果 ,以上几个数组长度都比num,vol多一个  
    for(i=1;i<=num;i++)  //状态方程  
    {  
        for(j=1;j<=vol;j++)  
        {  
            if (w[j]>j)                            //如果第i个物品放不进背包  
                f[i][j]=f[i-1][j];  
            else if(f[i-1][j]>(f[i-1][j-w[i]]+v[i]))    //状态方程 取<span style="font-size: 14px;">max{f[i-1][v],f[i-1][v-c[i]]+w[i]}</span>  
                f[i][j]=f[i-1][j];  
            else  
                f[i][j]=f[i-1][j-w[i]]+v[i];  
        }  
    }  
    return f[4][10];  
}  

关于回调函数

tinyfisher 发表于 2012-10-07

###关于回调函数,搜集了一些网上的说法: 1.形象的例子:

你饿了,想吃饭,就一会去问你妈一声”开饭没有啊?”这就正常函数调用. 但是今天你妈包饺子,花的时间比较长,你跑啊跑啊,就烦了.于是你给你妈说,我先出去玩会,开饭的时候打我手机.等过了一阵,你妈给你打电话说”开饭啦,快回来吃饭吧!”

*其中,你告诉你妈打手机找你,就是个你把回调函数句柄保存到你妈的动作.你妈打电话叫你,就是个回调过程. *

2.为什么使用回调函数

本质上都是“你想让别人的代码执行你的代码,而别人的代码你又不能动”这种需求下产生的

别人给你的不是源代码,是一个已经编译好的模块,并且不会给你源代码,那是商业机密,留给你一个接口,你把你要执行的代码以回调函数的形式交给这个接口,由别人编写的模块在需要的时候调用

**3.怎么调用回调函数 **

使用回调函数实际上就是在调用某个函数(通常是API函数)时,将自己的一个函数(这个函数为回调函数)的地址作为参数传递给那个函数。而那个函数在需要的时候,利用传递的地址调用回调函数,这时你可以利用这个机会在回调函数中处理消息或完成一定的操作。至于如何定义回调函数,跟具体使用的API函数有关,一般在帮助中有说明回调函数的参数和返回值等。C++中一般要求在回调函数前加CALLBACK,这主要是说明该函数的调用方式。

分段和分页内存管理

tinyfisher 发表于 2012-09-23

两者描述

打个比方,比如说你去听课,带了一个纸质笔记本做笔记。笔记本有100张纸,课程有语文、数学、英语三门,对于这个笔记本的使用,为了便于以后复习方便,你可以有两种选择。

第一种是,你从本子的第一张纸开始用,并且事先在本子上做划分:第2张到第30张纸记语文笔记,第31到60张纸记数学笔记,第61到100张纸记英语笔记,最后在第一张纸做个列表,记录着三门笔记各自的范围。这就是分段管理,第一张纸叫段表。

第二种是,你从第二张纸开始做笔记,各种课的笔记是连在一起的:第2张纸是数学,第3张是语文,第4张英语……最后呢,你在第一张纸做了一个目录,记录着语文笔记在第3、7、14、15张纸……,数学笔记在第2、6、8、9、11……,英语笔记在第4、5、12……。这就是分页管理,第一张纸叫页表。你要复习哪一门课,就到页表里查寻相关的纸的编号,然后翻到那一页去复习

两者的优缺点:

在段式存储管理中,将程序的地址空间划分为若干段(segment),如代码段,数据段,堆栈段;这样每个进程有一个二维地址空间,相互独立,互不干扰。*段式管理的优点是:没有内碎片(因为段大小可变,改变段大小来消除内碎片)。但段换入换出时,会产生外碎片(比如4k的段换5k的段,会产生1k的外碎片) *

在页式存储管理中,将程序的逻辑地址划分为固定大小的页(page),而物理内存划分为同样大小的页框,程序加载时,可以将任意一页放入内存中任意一个页框,这些页框不必连续,从而实现了离散分离。*页式存储管理的优点是:没有外碎片(因为页的大小固定),但会产生内碎片(一个页可能填充不满) *

两者的不同点:

(1) 分页仅仅是由于系统管理的需要而不是用户的需要。段则是信息的逻辑单位,它含有一组其意义相对完整的信息。分段的目的是为了能更好地满足用户的需要。

(2) 页的大小固定且由系统决定,由系统把逻辑地址划分为页号和页内地址两部分,是由机器硬件实现的,因而在系统中只能有一种大小的页面;而段的长度却不固定,决定于用户所编写的程序,通常由编译程序在对源程序进行编译时,根据信息的性质来划分。

(3) 分页的作业地址空间是一维的,即单一的线性地址空间,程序员只需利用一个记忆符,即可表示一个地址;而分段的作业地址空间则是二维的,程序员在标识一个地址时,既需给出段名,又需给出段内地址。

两者结合——段页式存储管理:

1.基本思想:

分页系统能有效地提高内存的利用率,而分段系统能反映程序的逻辑结构,便于段的共享与保护,将分页与分段两种存储方式结合起来,就形成了段页式存储管理方式。

在段页式存储管理系统中,作业的地址空间首先被分成若干个逻辑分段,每段都有自己的段号,然后再将每段分成若干个大小相等的页。对于主存空间也分成大小相等的页,主存的分配以页为单位。

段页式系统中,作业的地址结构包含三部分的内容:段号,页号,页内位移量

程序员按照分段系统的地址结构将地址分为段号与段内位移量,地址变换机构将段内位移量分解为页号和页内位移量。

为实现段页式存储管理,系统应为每个进程设置一个段表,包括每段的段号,该段的页表始址和页表长度。每个段有自己的页表,记录段中的每一页的页号和存放在主存中的物理块号。

2.地址变换的过程:

(1)程序执行时,从PCB中取出段表始址和段表长度,装入段表寄存器。

(2)由地址变换机构将逻辑地址自动分成段号、页号和页内地址。

(3)将段号与段表长度进行比较,若段号大于或等于段表长度,则表示本次访问的地址已超越进程的地址空间,产生越界中断。

(4)将段表始址与段号和段表项长度的乘积相加,便得到该段表项在段表中的位置。

(5)取出段描述子得到该段的页表始址和页表长度。

(6)将页号与页表长度进行比较,若页号大于或等于页表长度,则表示本次访问的地址已超越进程的地址空间,产生越界中断。

(7)将页表始址与页号和页表项长度的乘积相加,便得到该页表项在页表中的位置。

(8)取出页描述子得到该页的物理块号。

(9)对该页的存取控制进行检查。

(10)将物理块号送入物理地址寄存器中,再将有效地址寄存器中的页内地址直接送入物理地址寄存器的块内地址字段中,拼接得到实际的物理地址。