计算机网络 day7 扫描IP脚本 - 路由器 - ping某网址的过程
目录
实验:编写一个扫描脚本,知道本局域网里哪些ip在使用,哪些没有使用? 使用的ip对应的mac地址都要显示出来
思路一:通过ping命令获取在线的IP地址,然后通过截取arp缓存表里的数据获得IP地址对应的mac地址
思路二:通过ping命令获取在线的IP地址,然后对在线的IP地址通过arping命令获取对应的mac地址
路由的优先级:直连路由 > 静态路由 > 动态路由 > 默认路由
PC0(192.168.1.1/24) --》 ping 192.168.1.254
PC0(192.168.1.1/24) --》 ping 192.168.2.1
network 和 NetworkManager关系:
network 是一个给linux机器配置网络参数(ip,子网掩码,dns,网关等)。
NetworkManager 是linux系统里管理所有的网络连接的服务,可以禁用网卡,启用网卡。
network依赖于NetworkManage,NetworkManage将网卡禁用,network服务就没有办法给网卡配置ip地址了
nmcli(network manager client)是 network manager服务的客户端命令,可以给服务传递参数,进行设置
nmcli n 可以查看网络是否 被禁用
nmcli n on 启用网络
nmcli n off 禁用网络
示例:
实验:编写一个扫描脚本,知道本局域网里哪些ip在使用,哪些没有使用? 使用的ip对应的mac地址都要显示出来
IP地址范围(仅供参考):192.168.2.0/24 192.168.2.1 ~ 254
ping 192.168.2.1
使用shell、python或者go去编写局域网扫描工具,获取正在使用的ip和对应的mac地址
告诉哪些ip地址在使用,哪些没有使用?
去了解下,python/go里有哪些类似于ping命令的库(扫描的库)
ping库
socket库
pythonping
python_arptable
ipaddress
计算机程序执行的两种不同方式:
串行: 按照顺序进行 --》效率低,耗时比较长
并行: 同时执行 --》效率高,耗时短
shell语言编写扫描脚本
思路一:通过ping命令获取在线的IP地址,然后通过截取arp缓存表里的数据获得IP地址对应的mac地址
[root@sc-server shell]# cat scan_lan.sh
#!/bin/bash
# lan network 192.168.1.0
#清空文件
>ip_used.txt
>ip_unused.txt
# ping local host
for i in {1..254}
do
(if ping -c 1 -w 1 192.168.1.$i &>/dev/null ;then
echo "192.168.1.$i is used" |tee -a ip_used.txt
else
echo "192.168.1.$i is not used"|tee -a ip_unused.txt
fi)&
done
wait
#统计有多少ip在使用,多少没有使用
num1=$(wc -l < ip_used.txt)
num2=$(wc -l <ip_unused.txt)
echo "total ip used number: $num1"
echo "total ip unused number: $num2"
#输出ip和mac的对应关系---》arp缓存表里的内容
arp -n|grep -v "incomplete"|tail -n +2|awk '{print $1,$3}' >ip_mac.txt
echo "ip和mac地址"
cat ip_mac.txt
[root@sc-server shell]#
(命令)& 启动一个子进程去执行命令,在后台执行,不影响前台程序执行,达到我们想要的并发效果
wait 父进程等待子程序执行完毕,然后退出
思路二:通过ping命令获取在线的IP地址,然后对在线的IP地址通过arping命令获取对应的mac地址
#/bin/bash
#创建文件保存IP地址和MAC地址
>used_ip_mac.txt
>unused_ip.txt
>used_ip.txt
#得到自己的IP地址和mac地址
output1=$(ip add|grep "ens33:" -A2|head -n 3 | tail -n 1 |awk -F " " '{print $2}'|awk -F "/" '{print $1}')
output2=$(ip add|grep "ens33:" -A2|head -n 2 | tail -n 1 |awk -F " " '{print $2}')
#遍历整个网段,一个一个IP地址的arping
for i in {1..254}
do
(if ping 192.168.2.$i -c 1 -w 1 &>/dev/null ;then
echo "192.168.2.$i" >> used_ip.txt
if [ "192.168.2.$i" != "$output1" ];then
arping -I ens33 192.168.2.$i -w 1 -c 1|awk -F " " '{print $4,$5}'|head -n 2|tail -n 1 >> used_ip_mac.txt
else
echo "1"
fi
else
echo "192.168.2.$i" >> unused_ip.txt
fi)&
done
wait
#统计没有使用的ip地址的个数
num=$(cat unused_ip.txt |wc -l)
echo "Unused ip: $num" >>unused_ip.txt
#统计可以使用的ip地址的个数
num=$(cat used_ip.txt |wc -l)
echo "Used ip: $num" >>used_ip.txt
#添加自己的IP地址和MAC地址
echo "${output1} ${output2}" >> used_ip_mac.txt
python语言编写扫描脚本
思路:通过socket库获取自己的IP地址,然后通过pythonping库获取在线的IP地址,然后通过正则表达式访问arp缓存表并筛选出IP对应的mac地址,最后将程序通过多线程完成
import os
import re
import threading
from pythonping import ping
import socket
import uuid
import ipaddress
ip_list = []
ip_mac_list = []
target = []
sort_ip_list = []
#查找出自己的IP地址和MAC地址(cmd里面使用 ipconfig /all)
def local_ip_mac1():
# 获取本机IP地址
ip_address = socket.gethostbyname(socket.gethostname())
# 获取本机MAC地址
# 将读取的倒叙的全大写的MAC地址保存在列表list中
list = [('{:02x}'.format((uuid.getnode() >> i) & 0xFF)).upper() for i in range(0, 48, 8)]
mac_address = '-'.join(list[::-1])
return ip_address,mac_address
# 我们使用 socket.gethostname() 获取主机名,然后使用 socket.gethostbyname() 函数根据主机名获取对应的 IP 地址。
# 我们使用 uuid.getnode() 函数获取一个唯一的标识符,然后将其转换为十六进制表示,并以冒号分隔每两个字符。
# print(local_ip_mac1())
# 判断该网段IP地址能否ping通 ip是否在线
def ip_online(target):
ping_result = ping(target,timeout=0.3)
if ping_result.success():
print(f"Ping {target} 成功!")
# print(f"平均响应时间: {ping_result.rtt_avg_ms} ms")
ip_list.append(target)
else:
print(f"Ping {target} 失败!")
# 通过IP查MAC
def ip2mac(ip): # 通过IP查MAC
loc_ip, mac = local_ip_mac1()
if ip == loc_ip:
return mac
cmd = f'arp -a {ip}'
output = os.popen(cmd)
outstr = ' '.join(list(output))
if '未找到 ARP 项' not in outstr: # 排除本机
macs = re.findall('(([A-Fa-f0-9]{2}-){5}[A-Fa-f0-9]{2})', outstr, re.S)
for i in macs[0]:
if len(i) == 17:
return i
#多线程扫描
def scan(ip_online, ip):
# 执行扫描操作
# 创建线程列表
threads = []
# 遍历 IP 列表,为每个 IP 创建一个线程并启动它
for ip in target:
t = threading.Thread(target=ip_online, args=(ip,))
t.start()
threads.append(t)
# 等待所有线程完成
for t in threads:
t.join()
#IP地址排序
def sorted1(ip_list):
#定义列表
ip_list2 = []
ip_list3 = []
# 将str类型的ip地址转换成IPv4Address类型的IP地址,方便排序
for i in ip_list:
ip_network = ipaddress.ip_address(i)
ip_list2.append(ip_network)
ip_list2 = sorted(ip_list2)
# print(ip_list2)
# 将排序好的IPv4Address地址转换成str类型的并输出
for i in ip_list2:
# print(i,type(i))
ip_str1 = i.__str__()
# print(ip_str1,type(ip_str1))
ip_list3.append(ip_str1)
return ip_list3
if __name__ == '__main__':
# 判定IP地址范围
for i in range(1, 255):
target.append(f"192.168.2.{i}")
# 执行多线程
scan(ip_online,target)
# 输出在线的IP地址列表
# print(ip_list)
# 排序IP地址
sort_ip_list = sorted1(ip_list)
print(sort_ip_list)
#将得到的IP地址和mac地址放入ip_mac_list列表中
for ip in sort_ip_list:
ip_mac_list.append(ip + " " + ip2mac(ip))
# 输出ip_mac_list表
print(ip_mac_list)
路由器(router)
路由器的功能:
能实现跨网段通信,将数据从一个网络转发到另一个网络。
跨越从源主机到目标主机的一个互联网络来转发数据包的过程
在转发数据包的过程中,根据某个理由选择最佳路径帮助我们转发数据
路由工作在网络层,它通过路由选择和路由转发完成自己的功能
交换机工作在数据链路层
根据“MAC地址表”转发数据
硬件转发
路由器的工作原理
1.查看ip包的目的ip地址
2.计算出目标网段
3.到路由表里查看是否有到目标网段的路由
4.如果有,就转发,没有就告诉客户机不能到达
步骤图:
步骤:
1、主机1.1要发送数据到4.1
2、路由器A收到数据,查看数据包中的目标地址为4.1,查找路由表
3、路由器A根据路由表转发数据到S0口
4、路由器B接收到数据包,查看数据包的目标地址,并查找路由表
5、路由器B根据路由表转发数据到E0口
6、主机4.1接收到数据包
路由器转发数据包的封装过程
路由表:
路由表路由器中维护的路由条目的集合
路由器根据路由表做路径选择
路由表格式:
目标网段 接口(下一跳)
电脑、路由器、手机等配置了IP地址的设备都有路由表
路由表里的一条记录(一行)称呼为一个路由条目
查看路由表的方式(Linux):
[root@iZ2ze3xtpuz7jd2c0ex7nzZ ~]# ip route
default via 172.31.95.253 dev eth0
169.254.0.0/16 dev eth0 scope link metric 1002
172.31.80.0/20 dev eth0 proto kernel scope link src 172.31.84.18
[root@iZ2ze3xtpuz7jd2c0ex7nzZ ~]#
#路由表里的一条记录(一行)称呼为一个路由条目
[root@iZ2ze3xtpuz7jd2c0ex7nzZ ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 172.31.95.253 0.0.0.0 UG 0 0 0 eth0 默认路由
169.254.0.0 0.0.0.0 255.255.0.0 U 1002 0 0 eth0 直连路由
172.31.80.0 0.0.0.0 255.255.240.0 U 0 0 0 eth0 直连路由
[root@iZ2ze3xtpuz7jd2c0ex7nzZ ~]#
0.0.0.0 代表任意地址
路由表的方式(Windows)
C:\Users\23843>route print
IPv4 路由表
===========================================================================
活动路由:
网络目标 网络掩码 网关 接口 跃点数
0.0.0.0 0.0.0.0 192.168.2.1 192.168.2.43 45
127.0.0.0 255.0.0.0 在链路上 127.0.0.1 331
127.0.0.1 255.255.255.255 在链路上 127.0.0.1 331
127.255.255.255 255.255.255.255 在链路上 127.0.0.1 331
192.168.2.0 255.255.255.0 在链路上 192.168.2.43 301
如果路由表里没有对应的路由条目,路由器就会丢弃数据,不进行转发
路由的类型:
1、直连路由:直接和路由
2、非直连路由
2.1 静态路由
2.2 动态路由
2.3 默认路由
常用的路由类型:
1、直连路由 (directly connected)
接口配置IP地址,并且接口需要激活(端口UP状态),形成直连路由 --》自动产生
2、静态路由 (static)
需要管理员手工配置的,是单向的,因此缺乏灵活性
3、动态路由 (Dynamic)
使用动态路由协议自动学习和更新路由表的路由方式。
4、默认路由 (default)
只要配置默认网关就是添加一条默认路由,当没有匹配到合适的直连、静态、动态路由的时候,就会走默认路由,如果没有配置默认路由就会丢失数据
当路由器在路由表中找不到目标网络的路由条目时,路由器把请求转发到默认路由接口
路由的优先级:直连路由 > 静态路由 > 动态路由 > 默认路由
给路由器添加静态路由的命令
ip route 192.168.30.0 255.255.255.0 192.168.2.1
目标网段 子网掩码 下一跳地址
下一跳地址对应的IP
一般给末节的网络配置默认路由
给路由器添加默认路由的命令
ip route 0.0.0.0 0.0.0.0 192.168.2.1
目标网段 子网掩码 下一跳地址
ping某网址的过程
PC0(192.168.1.1/24) --》 ping 192.168.1.254
步骤:
1、拿192.168.1.254 跟自己的子网掩码进行与运算得出目标网段 192.168.1.0
192.168.1.254
255.255.255.0得:192.168.1.0 (目标网段)
2、查找本机里的路由表,发现走直连路由能到达,然后进行数据封装
源ip:192.168.1.1 目的ip:192.168.1.254
3、发送数据包给路由器的LAN口(默认网关)
PC0(192.168.1.1/24) --》 ping 192.168.2.1
步骤:
1、拿192.168.2.1 跟自己的子网掩码进行与运算得出目标网段 192.168.2.0
192.168.2.1
255.255.255.0得:192.168.2.0 (目标网段)
2、查找本机里的路由表,发现静态、直连、动态路由内都没有该网段,因此走默认路由,然后进行数据封装
源ip:192.168.1.1 目的ip:192.168.2.1
根据默认路由的下一跳地址192.168.1.254,查询arp缓存表,是否有192.168.1.254的mac地址,如果有直接使用,如果没有就发arp广播得到192.168.1.254的mac地址
3、封装帧头部: 源mac地址是自己 目的mac地址是 网关的mac地址
4、将数据送到交换机,交换机会根据目的mac地址做转发,送给网关
5、数据送到了路由器的LAN口(默认网关),拿192.168.2.1 跟自己(路由器)的子网掩码进行与运算得出目标网段 192.168.2.0,路由器然后查看路由表,发现192.168.2.1是自己的直连路由,然后直接将数据包通过直连路由转发给了192.168.2.1。
故障排除:
1、分层检查
从物理层检查,查看端口状态来排除接口、线缆等问题
查看IP地址和路由等的配置是否正确
2、分段检查
将网络划分成多个小的段,逐段排除错误
课后实验:
实验成果:
更多推荐
所有评论(0)