如何分析udp报文,从而获取源地址

如何分析udp报文,从而获取源地址,第1张

1、写了一个UDP 的小程序,有一个UDP 的server,而且有UDP的client。

然后执行server和client,然后用tcpdump将该端口的UDP数据报文抓取出来。

执行的过程是这样的。

client向server发送"xiyou"

server向client应答"wangzhe"

client程序在主机example上运行(192.168.1.144)

server程序在主机linux上运行(192.168.1.101)

------------------------------------------------------------------------------------------------------------

2、UDP数据报文。

linux@linux:~$ sudo tcpdump -vvv -X udp port 7777

[sudo] password for linux:

tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes

11:03:01.923227 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto UDP (17), length 48)

example.local.43521 >linux.7777: [udp sum ok] UDP, length 20

0x0000: 4500 0030 0000 4000 4011 b677 c0a8 0190 E..0..@.@..w....

0x0010: c0a8 0165 aa01 1e61 001c 4c34 7869 796f ...e...a..L4xiyo

0x0020: 7500 0000 0000 0000 0000 0000 0000 0000 u...............

11:03:01.923343 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto UDP (17), length 48)

linux.7777 >example.local.43521: [bad udp cksum 6869!] UDP, length 20

0x0000: 4500 0030 0000 4000 4011 b677 c0a8 0165 E..0..@.@..w...e

0x0010: c0a8 0190 1e61 aa01 001c 8473 7761 6e67 .....a.....swang

0x0020: 7a68 6500 0000 0000 0000 0000 0000 0000 zhe.............

由上面的报文可知,有两个UDP数据报文。

第一个报文是example主机上的client向server发送数据。

4500 0030 0000 4000 4011 b677 c0a8 0190 c0a8 0165 这20个数据是IP首部。

aa01 1e61 001c 4c34 这8个字节是UDP的首部。

7869 796f 7500 0000 0000 0000 0000 0000 0000 0000 这20个数据是我用sendto函数发送的

数据。

而将char req[20] = "xiyou" 的ASCII码(16进制)就是:

78 69 79 6f 75 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

第二个报文是linux向主机example做出的应答。

4500 0030 0000 4000 4011 b677 c0a8 0165 c0a8 0190 这20个数据是IP首部。

1e61 aa01 001c 8473 这8个字节是UDP首部。

7761 6e67 7a68 6500 0000 0000 0000 0000 0000 0000 这20个数据是应用层的数据。

而将char reply[20] = "wangzhe"的ASCII码(16进制)就是:

77 61 6e 67 7a 68 65 0 0 0 0 0 0 0 0 0 0 0 0 0

由此看出,应用层的数据没有夹杂其他的参数,全部是数据,均是字符的ASCII码。

-----------------------------------------------------------------------

附带网络程序:

udp_server.c

#include <stdio.h>

#include <stdlib.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <sys/types.h>

#include <string.h>

int main(void)

{

struct sockaddr_in server,client

int sockfd

int cli_len = 0,n

char req[20] = {0},reply[20] = {0}

sockfd = socket(AF_INET,SOCK_DGRAM,0)

if (sockfd <0) {

perror("socket error!\n")

exit(-1)

}

memset(&server,0,sizeof(struct sockaddr_in))

server.sin_family = AF_INET

server.sin_addr.s_addr = htonl(INADDR_ANY)

server.sin_port = htons(7777)

if (bind(sockfd,(struct sockaddr *)&server,sizeof(server)) <0) {

perror("bind error!\n")

exit(-1)

}

for () {

cli_len = sizeof(struct sockaddr_in)

n = recvfrom(sockfd,req,20,0,(struct sockaddr *)&client,&cli_len)

if (n <0) {

perror("recvfrom error!\n")

exit(-1)

}

printf("hello!\n")

strncpy(reply,"wangzhe",sizeof("wangzhe"))

if (sendto(sockfd,reply,20,0,(struct sockaddr *)&client,sizeof(client)) != 20) {

perror("sendto error!\n")

exit(-1)

}

}

return 0

}

-----------------------------------------------------------------------------------------------------------

udp_client.c

#include <stdio.h>

#include <stdlib.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <sys/types.h>

#include <string.h>

int main(void)

{

int sockfd,n

struct sockaddr_in server

char req[20]={0},reply[20]={0}

sockfd = socket(AF_INET,SOCK_DGRAM,0)

if (sockfd <0) {

perror("socket error!\n")

exit(-1)

}

memset(&server,0,sizeof(server))

server.sin_family = AF_INET

server.sin_addr.s_addr = inet_addr("192.168.1.101")

server.sin_port = htons(7777)

strncpy(req,"xiyou",sizeof("xiyou"))

printf("sendto req to server:%s\n",req)

if (sendto(sockfd,req,20,0,(struct sockaddr *)&server,sizeof(server)) != 20) {

perror("sendto error!\n")

exit(-1)

}

if ((n = recvfrom(sockfd,reply,20,0,(struct sockaddr *)NULL,(int *)NULL)) <0) {

perror("recvfrom error!\n")

exit(-1)

}

printf("recv reply from server :%s\n",reply)

exit(0)

}

    本文总结六种查看Linux IP地址的方法,方便以后的运维开发工作。

    在介绍前先学习一下三个命令行筛选的主要的指令,也是频繁使用到的命令。

1、head。 head 命令可用于查看文件的开头部分的内容,有一个常用的参数 -n 用于显示行数,默认为 10。

运行head --help查看说明信息:

-q 隐藏文件名

-v 显示文件名

-c<数目>显示的字节数。

-n<行数>显示的行数。

2、grep。 grep 命令用于查找文件里符合条件的字符串。运行grep --help查看说明信息,参数太多主要有以下几种:

grep -r递归选择。

grep -v反选,显示不包含匹配文本的所有行。

grep -n显示符合样式的那一行之前。

grep -A显示符合范本样式的那一列之外,并显示该行之后的内容。

3、awk。 强大的文本分析工具,命令使用过于复杂(awk --help),只需要知道 awk '{print$2}'为打印第二行数据。

4、tail 。tail命令可用于查看文件的结束部分的内容,有一个常用的参数 -n 用于显示行数,默认为 10。tail --help查看主要的参数:

tail -n显示最后多少行

tail -c显示最后十个字符

tail -f 循环读取,跟踪显示最后十行

5、cut。 显示每行从开头算起的文字。

cut -b :以字节为单位进行分割。

cut -c :以字符为单位进行分割

cut -d :自定义分隔符,默认为制表符

cut -f :与-d一起使用,指定显示哪个区域

无线网卡地址:

echo wlan0=`ifconfig  wlan0 | head -n2 | grep inet | awk '{print$2}'`

有线网卡地址:

echo eth0=`ifconfig  eth0 | head -n2 | grep inet | awk '{print$2}'`

或者命令:

ifconfig | grep "inet " | cut -d: -f2 | awk '{print $1}' | grep -v "^127."

无线网卡地址:

ip address | grep wlan0 | awk '{print$2}'

有线网卡地址:

ip address | grep eth0 | awk '{print$2}'

或者

echo eth0=`ip address show  eth0 | head -n4 | grep inet | awk '{print$2}'

echo wlan0=`ip address show wlan0 | head -n4 | grep inet | awk '{print$2}'

运行hostname -help命令查看说明信息:

Program options:

    -a, --alias            alias names

    -A, --all-fqdns        all long host names (FQDNs)

    -b, --boot            set default hostname if none available

    -d, --domain          DNS domain name

    -f, --fqdn, --long    long host name (FQDN)

    -F, --file            read host name or NIS domain name from given file

    -i, --ip-address      addresses for the host name

    -I, --all-ip-addresses all addresses for the host

    -s, --short            short host name

    -y, --yp, --nis        NIS/YP domain name

hostname -i得到环回地址127.0.1.1, hostname -I得到具体的网卡信息192.168.31.82 。

php语言查看ip就是使用函数shell_exec来执行shell命令。

比如:

<?php

  echo shell_exec("echo wlan0=`ifconfig  wlan0 | head -n2 | grep inet | awk '{print$2}'`")

?>

然后执行php ip.php 。shell_exec()里面可以放置任何shell命令。这个方法的意义在于php可以通过网页对外提供服务。

#!/usr/bin/env python

import socket

import fcntl

import struct

def get_ip_address(ifname):

    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

    return socket.inet_ntoa(fcntl.ioctl(

      s.fileno(),

      0x8915,  # SIOCGIFADDR

      struct.pack('256s', ifname[:15])

  )[20:24])

Local_wlan0=get_ip_address("wlan0")

Local_lo=get_ip_address("lo")

#Local_eth0=get_ip_address("eth0")

print Local_wlan0

print Local_lo

#print Local_eth0

利用socket包,然后执行python  ip.py 得到wlan0信息。

#!/usr/bin/env python

import os

def get_ip():

out = os.popen("echo wlan0=`ifconfig  wlan0 | head -n2 | grep inet | awk '{print$2}'`").read()

print out

if __name__ == '__main__':

get_ip()

和php的shell_exec函数类似,os.popen()里面可以放置任何shell命令。注意有个函数os.system的结果只是命令执行结果的返回值,执行成功为0;os.popen()可以读出执行的内容,输出的结果比较特殊,带换行符\n 。

下面以Kali Linux为例,演示获取IP地址的方法 (1)设置网络接口为自动获取IP地址。在Kali Linux的收藏夹中单击图标,将显示所有的程序,如图1.8所示。(2)单击“设置”图标,将打开“设置”窗口,如图1.9所示。(3)选择“网络”选项,单击有线连接中的齿轮按钮,将显示“有线”对话框,如图1.10所示。(4)勾选“自动连接”复选框。然后,单击IPv4标签,将显示IPv4选项卡,如图1.11所示。(5)在该界面选择“自动(DHCP)”选项。然后,单击“应用”按钮。接下来,就可以请求获取IP地址了。执行命令如下所示: root@daxueba:~# dhclient eth0 –d Internet Systems Consortium DHCP Client 4.3.5 Copyright 2004-2016 Internet Systems Consortium. All rights reserved. For info, please visit https://www.isc.org/software/dhcp/ Listening on LPF/eth0/00:0c:29:25:89:95 Sending on LPF/eth0/00:0c:29:25:89:95 Sending on Socket/fallback DHCPDISCOVER on eth0 to 255.255.255.255 port 67 interval 4 DHCPREQUEST of 192.168.0.12 on eth0 to 255.255.255.255 port 67 DHCPOFFER of 192.168.0.12 from 192.168.0.10 DHCPACK of 192.168.0.12 from 192.168.0.100 bound to 192.168.0.12 -- renewal in 277 seconds. 从输出的信息中,可以看到成功获取到IP地址192.168.0.12。由此可以说明,搭建的DHCP服务测试成功。此时,用户查看地址租约文件dhcpd.leases,也可以看到分配的IP地址。如下所示: root@daxueba:~# cat /var/lib/dhcp/dhcpd.leases # The format of this file is documented in the dhcpd.leases(5) manual page. # This lease file was written by isc-dhcp-4.3.5 # authoring-byte-order entry is generated, DO NOT DELETE authoring-byte-order little-endian lease 192.168.0.10 {  starts 1 2018/07/02 10:15:00  ends 1 2018/07/02 10:25:00  cltt 1 2018/07/02 10:15:00  binding state active  next binding state free  rewind binding state free  hardware ethernet 00:0c:29:5c:ae:aa  client-hostname "daxueba" } lease 192.168.0.11 {  starts 1 2018/07/02 10:18:17  ends 1 2018/07/02 10:28:17  cltt 1 2018/07/02 10:18:17  binding state active  next binding state free  rewind binding state free  hardware ethernet 00:0c:29:99:92:4f  uid "\001\000\014)\231\222O"  set vendor-class-identifier = "MSFT 5.0"  client-hostname "Test" } lease 192.168.0.12 {  starts 1 2018/07/02 10:34:56  ends 1 2018/07/02 10:44:56  cltt 1 2018/07/02 10:34:56  binding state active  next binding state free  rewind binding state free  hardware ethernet 00:0c:29:25:89:95  client-hostname "daxueba" } 从输出的信息中,可以看到DHCP服务分配出去的IP地址及对应租约信息。


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

原文地址: http://outofmemory.cn/yw/8994509.html

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

发表评论

登录后才能评论

评论列表(0条)

保存