#define MAX_ADDR_LEN 16 //点分十进制地址的最大长度
#define MAX_PROTO_TEXT_LEN 16 //子协议名称(如"TCP")最大长度
#define WINSOCK_VERSION MAKEWORD(2, 2)
#pragma comment(lib, "Ws2_32.lib")
#include <stdio.h>
#include <winsock2.h>
#include <mstcpip.h>
#include <conio.h>
typedef struct iphdr //定义IP首部
{
unsigned char h_lenver//4位首部长度+4位IP版本蚂衫号
unsigned char tos//8位服务类型TOS
unsigned short total_len//16位总长度(字节)
unsigned short ident//16位标识
unsigned short frag_and_flags//3位标志位
unsigned char ttl//孝物帆8位生存时间 TTL
unsigned char proto//8位协议 (TCP, UDP 或其他)
unsigned short checksum//16位IP首部校验和
unsigned int sourceIP//32位源IP地址
unsigned int destIP//32位目的IP地址
}IPHeader
typedef struct _tcphdr//定义TCP首部
{
USHORT th_sport//16位源端口
USHORT th_dport//16位目的端口
unsigned int th_seq//32位序列号
unsigned int th_ack//32位确认号
unsigned char th_lenres//4位首部长度/6位保留字
unsigned char th_flag//6位标志位
USHORT th_win//16位窗口大小
USHORT th_sum//16位校验和
USHORT th_urp//16位紧急数据偏移量
}TCP_HEADER
typedef struct _udphdr //定义UDP首部
{
unsigned short uh_sport//16位源端口
unsigned short uh_dport//16位目的端口
unsigned short uh_len//16位长度
unsigned short uh_sum//16位校验和
}UDP_HEADER
typedef struct _icmphdr //定义ICMP首部
{
BYTE i_type //8位类型
BYTE i_code //8位代码
USHORT i_cksum //16位校验和
USHORT i_id //识别号(一般用进程号作为识别号)
USHORT i_seq //报文序列号
ULONG timestamp //时巧雹间戳
}ICMP_HEADER
int iTTL,iLEN,iBYTES
char szSourceIP[MAX_ADDR_LEN], szDestIP[MAX_ADDR_LEN]
int iSourcePort,iDestPort
int fflag=0//file flag
#define PACKAGE_SIZE sizeof(IPHeader)+1000
void HandleError(char *func)
//functions
int DecodeTcpPack(char *, int,FILE *)//TCP解包函数
int DecodeUdpPack(char *, int,FILE *)//UDP解包函数
int DecodeIcmpPack(char *, int,FILE *)//ICMP解包函数
//MAIN
int main(int argc, char *argv[])
{
sockaddr_in saSource,saDest
WSAData wsaData
char buf[PACKAGE_SIZE]
WSAStartup(WINSOCK_VERSION, &wsaData)
SOCKET sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP)
if(sock == SOCKET_ERROR)
{
HandleError("socket")
WSACleanup()
return -1
}
//获取本机IP地址
struct sockaddr_in addr
memset(&addr, 0, sizeof(addr))
//addr.sin_addr.S_un.S_addr = inet_addr("192.168.1.101")
char name[256]
PHOSTENT hostinfo
if( gethostname ( name, sizeof(name)) == 0)
{
if((hostinfo = gethostbyname(name)) != NULL)
{
memcpy(&(addr.sin_addr.S_un.S_addr) , (struct in_addr *)*hostinfo->h_addr_list , sizeof((struct in_addr *)*hostinfo->h_addr_list ))
}
}
addr.sin_family = AF_INET
if(bind(sock, (struct sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR)//bind
{
HandleError("bind")
}
//设置SOCK_RAW为SIO_RCVALL,以便接收所有的IP包
int on = RCVALL_ON
DWORD num
if(WSAIoctl(sock, SIO_RCVALL, &on, sizeof(on), NULL, 0, &num, NULL, NULL) == SOCKET_ERROR)
{
HandleError("wsaIoctl set")
}
struct sockaddr_in from
int fromlen
int size
FILE *fp
if((fp=fopen("log.txt","w+"))==NULL)
{
printf("open file errer,can't save list to file")
fflag=1
}
//侦听IP报文
while(!kbhit())
{
memset(buf, 0, sizeof(num))
memset(&from, 0, sizeof(from))
fromlen = sizeof(from)
size=recvfrom(sock, buf, PACKAGE_SIZE, 0, (struct sockaddr*)&from, &fromlen)
if(size == SOCKET_ERROR)
{
if(WSAGetLastError() == WSAEMSGSIZE)
{
HandleError("recvfrom")
continue
}
}
IPHeader *iph=(IPHeader *)buf
/**/
//源地址
saSource.sin_addr.s_addr = iph->sourceIP
strncpy(szSourceIP, inet_ntoa(saSource.sin_addr), MAX_ADDR_LEN)
//目的地址
saDest.sin_addr.s_addr = iph->destIP
strncpy(szDestIP, inet_ntoa(saDest.sin_addr), MAX_ADDR_LEN)
iTTL = iph->ttl
//计算IP首部的长度
int IpHeadLen = 4 * (iph->h_lenver &0xf)
//根据协议类型分别调用相应的函数
switch(iph->proto)
{
case IPPROTO_ICMP:
DecodeIcmpPack(buf+IpHeadLen, size,fp)
break
case IPPROTO_IGMP:
printf("IGMP ")
printf("%15s: ->%15s: ", szSourceIP, szDestIP)
printf("%d",size)
printf("%s/n", buf)
break
case IPPROTO_TCP:
DecodeTcpPack((buf+IpHeadLen),size,fp)
break
case IPPROTO_UDP:
DecodeUdpPack(buf+IpHeadLen, size,fp)
break
default:
printf("unknown datagram from %s/n", inet_ntoa(from.sin_addr))
printf("%s/n", buf)
break
}//end switch
Sleep(200)
}//end while
fclose(fp)
closesocket(sock)
WSACleanup()
printf("Stopped!/n")
getch()
return 0
}//end of main
//TCP解包程序
int DecodeTcpPack(char * TcpBuf, int iBufSize,FILE *fp)
{
unsigned char FlagMaskFlagMask = 1
int i
TCP_HEADER *tcph
tcph = (TCP_HEADER*)TcpBuf
//计算TCP首部长度
int TcpHeadLen = tcph->th_lenres>>4
TcpHeadLen *= sizeof(unsigned long)
char *TcpData=TcpBuf+TcpHeadLen
iSourcePort = ntohs(tcph->th_sport)
iDestPort = ntohs(tcph->th_dport)
//输出
printf("TCP ")
printf("%15s:%5d ->%15s:%5d ", szSourceIP, iSourcePort, szDestIP, iDestPort)
printf("TTL=%3d ", iTTL)
if(fflag==1)
//判断TCP标志位
for( i=0i<6i++ )
{
if((tcph->th_flag) &FlagMask)
printf("1")
else printf("0")
FlagMask=FlagMask<<1
}
printf(" bytes=%4d", iBufSize)
printf("/n")
if(fflag=1)//写入文件
fprintf(fp,"TCP %15s:%5d ->%15s:%5d TTL=%3d ------ bytes=%4d/n"
,szSourceIP, iSourcePort, szDestIP, iDestPort, iTTL,iBufSize)
return 0
}
//UDP解包程序
int DecodeUdpPack(char * UdpBuf, int iBufSize,FILE *fp)
{
UDP_HEADER *udph
udph = (UDP_HEADER*)UdpBuf
iSourcePort = ntohs(udph->uh_sport)
iDestPort = ntohs(udph->uh_dport)
//输出
printf("UDP ")
printf("%15s:%5d ->%15s:%5d ", szSourceIP, iSourcePort, szDestIP, iDestPort)
printf("TTL=%3d ", iTTL)
printf("Len=%4d ", ntohs(udph->uh_len))
printf("bytes=%4d", iBufSize)
printf("/n")
if(fflag=1)//写入文件
fprintf(fp,"UDP %15s:%5d ->%15s:%5d TTL=%3d Len=%4d bytes=%4d/n"
,szSourceIP, iSourcePort, szDestIP, iDestPort, iTTL, ntohs(udph->uh_len), iBufSize)
return 0
}
//ICMP解包程序
int DecodeIcmpPack(char * IcmpBuf, int iBufSize,FILE *fp)
{
ICMP_HEADER * icmph
icmph = (ICMP_HEADER * )IcmpBuf
int iIcmpType = icmph->i_type
int iIcmpCode = icmph->i_code
//输出
printf("ICMP ")
printf("%15s ->%15s", szSourceIP, szDestIP)
printf("TTL=%3d ", iTTL)
printf("Type%2d,%d ",iIcmpType,iIcmpCode)
printf("bytes=%4d", iBufSize)
printf("/n")
if(fflag=1)//写入文件
fprintf(fp,"ICMP %15s ->%15sTTL=%3d Type%2d,%d bytes=%4d"
, szSourceIP, szDestIP, iTTL,iIcmpType,iIcmpCode, iBufSize)
return 0
}
void HandleError(char *func)
{
char info[65]= {0}
_snprintf(info, 64, "%s: %d/n", func, WSAGetLastError())
printf(info)
}
第一: 这种语法是在C语言规范中没有定义的,
gcc编译开启-Wall会提示:警告:‘a’上的运算结果可能是未定义的 [-Wsequence-point]
第埋链二:请参考《C语言程序设计_现代方法(第2版)》
第三:如果非要清楚原理请看反汇编
#include <stdio.h>弯谨孙int main(int argc, const char *argv[])
{
int a = 3
int b
b = (++a) + (++a)
printf("b = %d\n", b)
return 晌衫0
} .section .rodata
.LC0:
.string "b = %d\n"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $32, %esp
movl $3, 28(%esp) # 28(%esp) 是变量 a = 3
addl $1, 28(%esp) # a++ //a == 4
addl $1, 28(%esp) # a++ //a == 5
movl 28(%esp), %eax # eax = a
addl %eax, %eax # eax = eax + eax //eax = 10
movl %eax, 24(%esp) # b = eax //b = 10
movl 24(%esp), %eax
movl %eax, 4(%esp)
movl $.LC0, (%esp)
call printf
movl $0, %eax
leave
ret
.size main, .-main
.ident "GCC: (Gentoo 4.7.3-r1 p1.3, pie-0.5.5) 4.7.3"
.section .note.GNU-stack,"",@progbits
DELPHI很好用,我就是用DELPHI,他的语种是PASCAL,你可以去网上搜一些DELPHI教材,先学会PASCAL。PASCAL很容易,语法简介:1.标记(TOKEN)
1.1 特别符号(Symbols)
字母(Letters) : A..Z , a..z
数字(Digits) : 0..9
十六进位数字(Hex Digits) : 0..9,A..F(OR a..f)
空白(Blank) : ASCII 32
单字元符号:+-*/=<>[].,():^@{}$#
多字元符号:<=,>=,:=,..,(*,*),(.,.)
1.2 识别字(信察Identifiers)
表示:常数,型态,变数,程序,函数,程式单元,程式,栏位....
长度:63位内有效,不分大小写
字首:字母,_
识别字不得培改重复,若有重复必需采 限定识别字 : Unit1.IdentName
1.3 标笺(Label) : 0..9999 or 识别字
1.4 字元字串
'ATTN' ----------- ATTN
'滑中茄You''ll see' ---- Yoy'll see
'' --------------- 空字串
' ' -------------- 空白字元
'Line 1'#13#10'Line 2' ------ Line 1
Line 2
1.5 注释
{ xxxxxxx }
{ xxxxxxxx
xxxxxx
xxxxx }
// xxxxxxxx
2.常数宣告 (使用标记 = )
2.1一般常数宣告
CONST
Min = 0
Max = 100
Center = ( Max - Min ) Div 2
Blank = Chr(32)
NumChr = Ord('Z') - Ord('A') + 1
ErrMsg = 'Out Of Rang'
ErrDtl = 'Out Of Rang' + ':Item 10'
Numeric = [ '0'..'9' ]
Alpha = [ 'A'..'Z','a'..'z']
AlphNum = Alpha + Numeric
2.1型态常数(Typed constant)宣告
CONST
MaxInt : Integer = 9999
FixReal : Real = -0.12
ListStr : String[4] = 'This'
AA : Pchar = 'abcedf'
Dim : Array[0..1,0..1,0..1] of Integer = (((0,1),(2,3)),((4,5),(6,7)))
{ Dim(0,0,0) = 0 Dim(0,0,1) = 1
Dim(0,1,0) = 2 Dim(0,1,1) = 3
Dim(1,0,0) = 4 Dim(1,0,1) = 5
Dim(1,1,0) = 6 Dim(1,1,1) = 7 }
--------------------------------
TYPE
Trec = record
fl1,fl2 : Integer
end
CONST
IntRec : Trec = ( fl1:1fl2:2)
------------------------------------------
3.型态宣告 (使用标记 = ) : 当宣告一个变数时,必须指明其型态
3.1 例子(1)
TYPE
Trang = Integer
TNumber = Integer
TColor = ( Red , Green , Blue )
TCharVal = Ord('A')..Ord('Z')
TtestIndex = 1..100
TtestValue = -99..99
TtestList = Array[TtestIndex] of Ttestvalue
ptestList = ^TtestList=>指标型态
Tdate = Class
Year : Integer
Month : 1..12
Day : 1..31
Procedure SetDate(D,M,Y:Integer)
Function ShowDate : String
end
TMeasureList = Array[1..50] of TMeasuredate
Tname = String[80]=>定长度
Tsex = (Male , Female)=>0 1
PpersonData = record
Name , FirstName : Tname
Age : Integer
Married : Boolean
TFather,TChild,TSibling : PPersonData
Case s: Tsex of =>0和1之间
Maie : ( Bearded : Boolean )
Female : (Pregnant : Boolean )
End
TPersonBuf = Array[0..Size(TPsersonData) - 1 ] of Byte
TPeople = File Of TPersonData =>定type
3.2 简单型态
3.2.1序数型态
(1)整数型态:
基础型态(Fundmental)
Shortint-128..127 8-bit
Smallint-32768..32767 16-bit
Longint-2147483648..214748364732-bit
Byte 0..255 8-bit
Word 0.65535 16-bit
通用型态(Generic)
Integer -2147483648..214748364732-bit
Cardinal0..2147483647 32-bit
若16bit
Integer -32768..32767 16-bit
Cardinal0.65535 16-bit
(2)字元型态
基础型态(Fundmental)
AnsiChar ASCII1-Byt
WideChar Unicode 2-Byt
通用型态(Generic)
Char ASCII1-Byt
(3)列举型态(Enumerated Type)
==============================================
TColor = ( Red , Green , Blue )
==============================================
(4)逻辑型态(Boolean Type)
基础型态(Fundmental)
ByteBool 0..1 1-Byt
WordBool 0..1 2-Byt
LongBool 0..1 4-Byt
通用型态(Generic)
Boolean 1-Byt
==============================================
Married : Boolean
False < True
Ord(False) = 0
Ord(True) = 1
Succ(False)=True
Pred(True)=False
==============================================
(5)子集型态(Subrang type)
==============================================
TtestIndex = 1..100
==============================================
3.2.2实数型态
型态 有效位数 位元组大小
Real 11-12 6
Single 7-84
Douible15-16 8
ExTended 10-20 10
Comp 19-20 8
Currency 19-20 8
===================================================
例子 Real 6byt共48 bit
1-12-40 41-48
s f e
有效值 v
if ( e > 0 ) and ( e <= 255 ) then
v = (-1)**s * 2 ** (e - 129) * (1.f)
else if e = 0 then v = 0
===================================================
3.3 字串型态
3.3.1 基础型态(Fundmental)
(1) ShortString 短字串 1-255 (又称pascal string)
(2) AnsiString 长字串 1-2G
(3) PChr Null-Terminated string
3.3.2 通用型态(Generic)
String 32位元时 等於 AnsiString
16位元时 等於 ShortString
===================================================
(1) 字串为一以零为基底的字元阵列(Zero-base character array)
例
-----------------------
TYPE
TStringBuf = Array[0..79] of Char
const
StringBuf : TStringBuf = 'This is test'
-----------------------
(2) var s : ShortString
Length(s) = Ord(s[0])
(3) 长字串以4-byt指标,指到动态配置之记忆体,没有[0]之长度数值
一个动态记忆体配置之长字串会自动以一空字元(null Character)结束
(4) PChr 以字元阵列来储存,结尾以(null Character)结束,使用指标来管理
(5) PChr型态与String型态在指定叙述上是相容
例:
-----------------------------
var p:pchr
begin
p := 'this is test'
end
-----------------------------
Procedure PrintStr(Str:Pchr)
呼叫时可用
PrintStr('This is test')
-----------------------------
3.4 结构型态(Strictured type)
3.4.1 阵列型态(Array type)
TDim1 = Array[0..79] of Char
TDim2 = Array[1..3,1..10] of Char
VAR
Dim1 : Tdim1
I : Integer
begin
for I := Low(Dim1) to High(Dim1) do
Dim1[I] := #32
end
===================================================
3.4.2 记录型态(Record Type)
TYPE
TdateRec = Record
Year : Integer
Month : 1..12
Day : 1..31
end
何谓变动栏位 ?
3.4.3 集合型态(Set Type)
TYPE
Tmenber = ( Lee , White , Ston )
Tmenbers = Set Of Tmenber
var Members : Tmenbers
begin
Menbers := [ White , Ston ]
end
集合型态不能超过256个可能值
3.4.4 档案型态(File Type)
(1)记录型态档案
TYPE
Temployee = record
name : string[10]
address : string[50]
end
TemployeeFile = File Of Temployee
var
EmployeeFile : TemployeeFile
同 EmployeeFile : File Of Temployee
(2)文件型态档案
TMyTextFile = TextFile
var
MyTextFile : TMyTextFile
or
MyTextFile : TextFile
ReadText : String
-----------------------------
AssignFile( MyTextFile , 'c:\MyFile.txt')
Reset( MyTextFile )
While Not Eof( MyTextFile ) do
begin
Readln( MyTextFile , ReadText )
end
CloseFile( MyTextFile )
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)