又更新了一点子3.0

最后代码更新到3.0了呜呜呜
这次的改进:ftp客户端和服务器端的确认以及输出

更新了一小下子2.0

后面代码已经改成最新的了

实验要求:






在网上扒了一段代码,然后自己又添了一点,明个就要验收了,没做完嘻嘻。上实验课的时候再完善一下子。

#define WIN32
#include<iostream>
#include<sstream>
#include<string>
#include<map>
#include<fstream>
#include <pcap.h>
#pragma warning(disable:4996)
using namespace std;
map<string, string[3]> ftp;
bool flag;
ofstream out("mark.txt");
typedef struct mac_header
{u_char dest_addr[6];u_char src_addr[6];u_char type[2];
} mac_header;/* IPv4 首部 ,20字节*/
typedef struct ip_header {u_char  ver_ihl;        // 版本 (4 bits) + 首部长度 (4 bits)  u_char  tos;            // 服务类型(Type of service)  u_short tlen;           // 总长(Total length)  u_short identification; // 标识(Identification)  u_short flags_fo;       // 标志位(Flags) (3 bits) + 段偏移量(Fragment offset) (13 bits)  u_char  ttl;            // 存活时间(Time to live)  u_char  proto;          // 协议(Protocol)  u_short crc;            // 首部校验和(Header checksum)  u_char  saddr[4];      // 源地址(Source address)  u_char  daddr[4];      // 目的地址(Destination address)  u_int   op_pad;         // 选项与填充(Option + Padding)
}ip_header;
//TCP头部,总长度20字节
typedef struct tcp_header
{u_short sport;            //源端口号  u_short dport;             //目的端口号  u_int th_seq;                //序列号  u_int th_ack;               //确认号  u_int th1 : 4;              //tcp头部长度  u_int th_res : 4;             //6位中的4位首部长度  u_int th_res2 : 2;            //6位中的2位首部长度  u_char th_flags;            //6位标志位  u_short th_win;             //16位窗口大小  u_short th_sum;             //16位tcp检验和  u_short th_urp;             //16位紧急指针
}tcp_header;/* 回调函数原型 */
void packet_handler(u_char* param, const struct pcap_pkthdr* header, const u_char* pkt_data);
string get_request_m_ip_message(const u_char* pkt_data);
string get_response_m_ip_message(const u_char* pkt_data);
void print(const struct pcap_pkthdr* header, string m_ip_message, const u_char* pkt_data);int main()
{flag = false;pcap_if_t* alldevs;pcap_if_t* d;int inum;int i = 0;pcap_t* adhandle;char errbuf[PCAP_ERRBUF_SIZE];u_int netmask;char packet_filter[] = "tcp";struct bpf_program fcode;/* 获得设备列表 */if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1){fprintf(stderr, "Error in pcap_findalldevs: %s\n", errbuf);exit(1);}/* 打印列表 */for (d = alldevs; d; d = d->next){printf("%d. %s", ++i, d->name);if (d->description)printf(" (%s)\n", d->description);elseprintf(" (No description available)\n");}if (i == 0){printf("\nNo interfaces found! Make sure WinPcap is installed.\n");return -1;}printf("Enter the interface number (1-%d):", i);cin >> inum;if (inum < 1 || inum > i){printf("\nInterface number out of range.\n");/* 释放设备列表 */pcap_freealldevs(alldevs);return -1;}/* 跳转到已选设备 */for (d = alldevs, i = 0; i < inum - 1; d = d->next, i++);/* 打开适配器 */if ((adhandle = pcap_open(d->name,  // 设备名  65536,     // 要捕捉的数据包的部分  // 65535保证能捕获到不同数据链路层上的每个数据包的全部内容  PCAP_OPENFLAG_PROMISCUOUS,         // 混杂模式  1000,      // 读取超时时间  NULL,      // 远程机器验证  errbuf     // 错误缓冲池  )) == NULL){fprintf(stderr, "\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);/* 释放设备列表 */pcap_freealldevs(alldevs);return -1;}/* 检查数据链路层,为了简单,我们只考虑以太网 */if (pcap_datalink(adhandle) != DLT_EN10MB){fprintf(stderr, "\nThis program works only on Ethernet networks.\n");/* 释放设备列表 */pcap_freealldevs(alldevs);return -1;}if (d->addresses != NULL)/* 获得接口第一个地址的掩码 */netmask = ((struct sockaddr_in*)(d->addresses->netmask))->sin_addr.S_un.S_addr;else/* 如果接口没有地址,那么我们假设一个C类的掩码 */netmask = 0xffffff;//编译过滤器  if (pcap_compile(adhandle, &fcode, packet_filter, 1, netmask) < 0){fprintf(stderr, "\nUnable to compile the packet filter. Check the syntax.\n");/* 释放设备列表 */pcap_freealldevs(alldevs);return -1;}//设置过滤器  if (pcap_setfilter(adhandle, &fcode) < 0){fprintf(stderr, "\nError setting the filter.\n");/* 释放设备列表 */pcap_freealldevs(alldevs);return -1;}printf("\nlistening on %s...\n", d->description);/* 释放设备列表 */pcap_freealldevs(alldevs);/* 开始捕捉 */pcap_loop(adhandle, 0, packet_handler, NULL);out.close();return 0;
}static int cnt = 0;/* 回调函数,当收到每一个数据包时会被libpcap所调用 */
void packet_handler(u_char* param, const struct pcap_pkthdr* header, const u_char* pkt_data)
{int head = 54;//14位以太网头,20位ip头,20位tcp头  //选择出command为USER和PASS的包,当然这里就简单的以首字母来代表了,反正其他的  //command 没有以U和P开头的  string com;string m_ip_message;//对数据包的处理,先提前前四个字符,查看是什么命令for (int i = 0; i < 4; i++)com += (char)pkt_data[head + i];if (com == "USER"){m_ip_message = get_request_m_ip_message(pkt_data);string user;ostringstream sout;for (int i = head + 5; pkt_data[i] != 13; i++){sout << pkt_data[i];}user = sout.str();ftp[m_ip_message][0] = user;print(header, m_ip_message, pkt_data);}else if (com == "PASS"){m_ip_message = get_request_m_ip_message(pkt_data);string pass;ostringstream sout;for (int i = head + 5; pkt_data[i] != 13; i++){sout << pkt_data[i];}pass = sout.str();ftp[m_ip_message][1] = pass;print(header, m_ip_message, pkt_data);}else if (com == "230 "){m_ip_message = get_response_m_ip_message(pkt_data);ftp[m_ip_message][2] = "SUCCEED";print(header, m_ip_message,pkt_data);}else if (com == "530 "){m_ip_message = get_response_m_ip_message(pkt_data);ftp[m_ip_message][2] = "FAILD";print(header, m_ip_message,pkt_data);}}
string get_request_m_ip_message(const u_char* pkt_data)
{mac_header* mh;ip_header* ih;string m_ip_message;string str;//empty stringostringstream sout;int length = sizeof(mac_header) + sizeof(ip_header);mh = (mac_header*)pkt_data;ih = (ip_header*)(pkt_data + sizeof(mac_header));//sout << "SRC MAC:";//sout << "DESC MAC:";for (int i = 0; i < 3; i++)sout << dec << (int)(ih->saddr[i]) << ".";sout << (int)(ih->saddr[3]) << ",";for (int i = 0; i < 5; i++)sout << hex << (int)(mh->dest_addr[i]) << "-";sout << (int)(mh->dest_addr[5]) << ",";for (int i = 0; i < 3; i++)sout << dec << (int)(ih->daddr[i]) << ".";sout << (int)(ih->daddr[3]);m_ip_message = sout.str();return m_ip_message;
}
string get_response_m_ip_message(const u_char* pkt_data)
{mac_header* mh;ip_header* ih;string m_ip_message;string str;//empty stringostringstream sout;int length = sizeof(mac_header) + sizeof(ip_header);mh = (mac_header*)pkt_data;ih = (ip_header*)(pkt_data + sizeof(mac_header));for (int i = 0; i < 5; i++)sout << hex << (int)(mh->dest_addr[i]) << "-";sout << (int)(mh->dest_addr[5]) << ",";for (int i = 0; i < 3; i++)sout << dec << (int)(ih->daddr[i]) << ".";sout << (int)(ih->daddr[3]) << ",";for (int i = 0; i < 5; i++)sout << hex << (int)(mh->src_addr[i]) << "-";sout << (int)(mh->src_addr[5]) << ",";for (int i = 0; i < 3; i++)sout << dec << (int)(ih->saddr[i]) << ".";sout << (int)(ih->saddr[3]);m_ip_message = sout.str();return m_ip_message;
}void print(const struct pcap_pkthdr* header, string m_ip_message,const u_char* pkt_data)
{mac_header* mh;ip_header* ih;mh = (mac_header*)pkt_data;ih = (ip_header*)(pkt_data + sizeof(mac_header));tcp_header* th;th = (tcp_header*)(pkt_data + 34);cnt++;cout << "No." << cnt << endl << endl;time_t tt = time(NULL);tm* t = localtime(&tt);cout << "Time:";printf("%d:%d:%d(%d)", t->tm_hour, t->tm_min, t->tm_sec, header->ts.tv_usec);cout << endl;//计算tcp报文数据长度还有点子错/*u_int len = ih->tlen-ih->ver_ihl-th->th1;cout << "TCP_Data_Length:" << len << endl;*/cout << "get an ip packet" << endl;cout << "get a tcp packet" << endl;cout << "源端口:" << ntohs(th->sport) << endl;cout << "目的端口:" << ntohs(th->dport) << endl;u_short server = 21;//这里需要自己写服务器的端口,才能在后面判断到底是客户端到服务器端还是服务器端到客户端if (ntohs(th->dport) == server)cout << "ftp:client->server" << endl;elsecout << "ftp:server->client" << endl;cout << "SRC MAC ";for (int i = 0; i < 5; i++) {//源MAC地址printf("%02X-", mh->src_addr[i]);}printf("%02X,", mh->src_addr[5]);cout << endl;cout << "SOURCE IP ";for (int i = 0; i < 3; i++) {//源IP地址printf("%d.", ih->saddr[i]);}//fprintf_s(file, "%d,", ih->saddr[3]);printf("%d,", ih->saddr[3]);cout << endl;cout << "DEST MAC ";for (int i = 0; i < 5; i++) {//目的MAC地址printf("%02X-", mh->dest_addr[i]);}printf("%02X,", mh->dest_addr[5]);cout << endl;cout << "DEST IP ";for (int i = 0; i < 3; i++) {//目的IP地址printf("%d.", ih->daddr[i]);}printf("%d,", ih->daddr[3]);cout << endl;u_short dport;u_char flags = '\0';dport = ntohs(th->dport);flags = th->th_flags;printf("6比特标志位:\n");bool URG = flags & 0x20;bool ACK = flags & 0x10;bool PSH = flags & 0x08;bool RST = flags & 0x04;bool SYN = flags & 0x02;bool FIN = flags & 0x01;printf("URG=%d\tACK=%d\tPSH=%d\tRST=%d\tSYN=%d\tFIN=%d\n", URG, ACK, PSH, RST, SYN, FIN);if (SYN) printf("握手包");else if (FIN)printf("挥手包");cout << endl;cout << "USER:" << ftp[m_ip_message][0]<<" ";cout<< "PASSWORD:"<<ftp[m_ip_message][1]<<" ";cout << ftp[m_ip_message][2] << endl;ftp.erase(m_ip_message);cout << endl << endl;
}

实现效果

tcp:

最后一行需要小改,因为源MAC,目的MAC,源IP和目的IP之前已经输出了,后面又输出了一次,但是我要回宿舍了,明天再改。最后面三个分别代表用户名密码和成功与否。

计算机网络实验:用 WinPCAP 监听并解析 FTP 命令和捕获TCP握手包和挥手包相关推荐

  1. 事件监听中的冒泡流和捕获流有趣现象

    事件监听中的冒泡流和捕获流有趣现象 这两天在看js权威指南的时候看见addEventListener的第二个参数为使用哪一种事件流,实践了一下,然后想到一个有趣的事,如果两个一起用会怎么样. 首先看看 ...

  2. 【网络与系统安全实验】网络监听及防御技术

    网络监听及防御技术 网络监听概述 基础知识 网络监听的概念 网络监听技术又叫做网络嗅探技术,顾名思义这是一种在他方未察觉的情况下捕获其通信报文或通信内容的技术. 在网络安全领域,网络监听技术对于网络攻 ...

  3. 串口监听工具listen_串口命令解析

    第一篇文章我相信很多人不看都能做的出来,但是,用过微软SerialPort类的人,都遇到过这个尴尬,关闭串口的时候会让软件死锁.天哪,我可不是武断,算了.不要太绝对了.99.9%的人吧,都遇到过这个问 ...

  4. linux WOL 唤醒信号监听,解析

    wol 本质也是一个网络包,用于局域网内部唤醒只用. WOL 包分析 使用工具Wake On Lan 配置wol.mac 地址,ip.mac 地址(255.255.255.255),然后出发一下. 使 ...

  5. windows重启oracle监听口令,oracle_windows下命令启动oracle监听和服务

    1.检查监听器状态 C:\Users\Administrator>lsnrctl status 2.启动监听程序 C:\Users\Administrator>lsnrctl start ...

  6. 开启1521端口监听_Oracle数据库常用命令、Linux监听配置、Oracle linux下开放1521端口...

    一.Linux下Oracle数据库常用命令 Oracle用户下执行: $ sqlplus system/manager @ file.sql 执行sql脚本文件 $ sqlplus system/ma ...

  7. 计算机监听的端口,侦听计算机的指定端口并分析其数据包,监听,本,解析

    # 可以用80端口进行试验,只要打开浏览器浏览网页即可捕获数据包 import os ###################################### ########## ####### ...

  8. 手摸手系列之---camel ftp监听接收解析xml报文并入库生成Java对象实战

    前言 版本: SpringBoot 2.4 camel 3.5.0 最近在做跟一个第三方系统的对接,主要流程就是对方生成XML格式的报文,需要我方将其报文发送到海关申报,然后将申报完的数据再组装成XM ...

  9. 燕山大学计算机网络实验(windows网络配置方法及基本网络命令、交换机和路由器的使用、小型校园网络模拟搭建)

    项目源码以及报告获取,可看我专栏简介 实验1 windows网络配置方法及基本网络命令 1.1 实验内容和要求 1.查看本机网络配置,根据配置信息,把本机地址改为静态地址,并使用ipconfig.pi ...

最新文章

  1. linux mysql 权限设置_Linux下mysql新建账号及权限设置
  2. 关于K型车模同学反馈问题
  3. 突然Windows系统声音没有,怎么修复?
  4. python 统计使用技巧
  5. C++二维数组名的再探索
  6. SAP Spartacus cypress集成测试执行失败的一些常见原因
  7. asp.net接受表单验证格式后再提交数据_如何解析 el-form-renderer 表单渲染器1.14.0...
  8. TypeScript:数组
  9. Cookie与Session的区别-总结很好的文章
  10. 远程桌面/远程登陆中强行登陆(他人退出)与切换回话(登陆后切换到上次别的登陆)3389...
  11. Android源码下载编译(TI)
  12. SHELL脚本获取某天的上一周日期(星期一为第一天)
  13. Spring XML 注入
  14. Ros学习笔记(一)Ros中HelloWorld实现(C++/Python)
  15. 让对方计算机死机的代码,微信让对方死机代码是什么?一串代码卡死微信
  16. 经典的二叉树的先根、中根和后根遍历序列题
  17. JavaScript_ES5和ES6
  18. 东华软件张涵诚:政府大数据应用的案例和数据价值释放的方法
  19. 一英寸芯片大小_芯片特征尺寸背后的秘密是什么
  20. 浅谈安科瑞电能预付费系统在大电力客户中的设计及应用分析

热门文章

  1. Ajax使用,爬取微博正文,点赞,评论数。
  2. 【综合案例】信用卡虚拟交易识别
  3. 基于SpringBoot 的报销系统
  4. android输出日期格式,如何在Android中将“ yyyy-MM-dd'T'HH:mm:ss.SSSXXX”日期格式解析为简单格式?...
  5. Wondershare Filmora视频叠加教程-轻松制作画中画效果
  6. Termius常用快捷键
  7. Startrails 重叠图片
  8. C# 文件操作类大全
  9. 用Java开发HTTP代理服务器
  10. 在线存储、近线存储、离线存储、数据迁移