局域网截包程序设计

局域网截包程序设计,第1张

#define RCVALL_ON 1

#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 )


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/8182087.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-14
下一篇 2023-04-14

发表评论

登录后才能评论

评论列表(0条)

保存