当我使用Rest服务转发scapy数据包时内容被破坏

时间:2014-08-08 11:09:12

标签: java python rest scapy opendaylight

我正在尝试将scapy形成的网络数据包转发到其他服务,但不知何故数据包在接收方(休息服务端)被破坏。

我使用scapy形成了网络数据包:

0000  1a 0b 0c 14 05 16 00 00 00 00 00 00 08 00 45 00   ..............E.
0010  01 10 00 01 00 00 40 11 f0 d2 05 05 05 04 7f 00   ......@.........
0020  00 01 00 44 00 43 00 fc 85 7f 01 00 00 00 00 00   ...D.C..........
0030  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
0040  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
0050  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
0060  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
0070  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
0080  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
0090  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
00a0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
00b0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
00c0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
00d0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
00e0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
00f0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
0100  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
0110  00 00 00 00 00 00 63 82 53 63 35 01 01 ff         ......c.Sc5...

我使用python代码将捕获的scapy数据包转发到Web服务:

h = httplib2.Http(".cache")
h.add_credentials("user","passworkd")
data = urllib.urlencode({"packet":pack})
resp, content = h.request(url, "POST", data, headers={'Content-Type': 'applicatoin/x-www-form-urlencodede'})

在服务器端(在java中实现)我打印了获取的数据包(字节流),它显示了以下输出(与发送数据包不同):

  

1a0b0c140516000000000000080045000110000100004011efbfbdefbfbd050505047f0000010044004300efbfbd7f010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063efbfbd5363350101efbfbd

编辑:

Java服务器端处理:

@Path("/test")
    @POST
    @StatusCodes({
        @ResponseCode(code = 200, condition = "Destination reachable"),
        @ResponseCode(code = 503, condition = "Internal error"),
        @ResponseCode(code = 503, condition = "Destination unreachable") })
    public Response rcvDHCPPkt(@FormParam("packet") String packet) {

        String pkt_decode = URLDecoder.decode(packet, "UTF-8"); // tried with and without it.

        // here it shows the packet corruption. I tried to print packet also it has same problem.
        System.out.println("packet received:" + byteArrayToHex(packet_decode.getBytes()));

使用以下函数打印十六进制等效值。

   public static String byteArrayToHex(byte[] a) {
               StringBuilder sb = new StringBuilder(a.length * 2);
               for(byte b: a)
                  sb.append(String.format("%02x", b & 0xff));
               return sb.toString();
            }

如果我错过了什么,请建议我。我怀疑urlencoding或网络字节排序有两个问题。

1 个答案:

答案 0 :(得分:0)

我不认为这是一个url编码问题,至少不是在Python端。在这里,我将数据包发送到在我的本地计算机上运行的nc服务器。 Python代码是:

import urllib
import httplib2
from binascii import unhexlify

data = '1a0b0c140516000000000000080045000110000100004011f0d2050505047f0000010044004300fc857f010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063825363350101ff'

h = httplib2.Http(".cache")
h.add_credentials("user", "passworkd")
data = urllib.urlencode({"packet": unhexlify(data)})
resp, content = h.request('http://localhost:12345', "POST", data, headers={'Content-Type': 'applicatoin/x-www-form-urlencodede'})

以下是nc收到的内容:

$ nc -l localhost 12345
POST / HTTP/1.1
Host: localhost:12345
Content-Length: 851
content-type: applicatoin/x-www-form-urlencodede
accept-encoding: gzip, deflate
user-agent: Python-httplib2/0.9 (gzip)

packet=%1A%0B%0C%14%05%16%00%00%00%00%00%00%08%00E%00%01%10%00%01%00%00%40%11%F0%D2%05%05%05%04%7F%00%00%01%00D%00C%00%FC%85%7F%01%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00c%82Sc5%01%01%FF

如果您对urllib.unquote()收到的数据运行nc,则会成功与原始数据进行比较...因此,客户端无编码问题。


但是我确实注意到您没有为Content-Type标头使用正确的MIME类型:

headers={'Content-Type': 'applicatoin/x-www-form-urlencodede'}

应该是

headers = {'Content-Type': 'application/x-www-form-urlencoded'}

我的猜测是,由于Content-Type标头无效,您的Java服务器会错误解释数据包数据。