|
首先,使用C编写模块psnd,如下,将其放入某个目录下,如sendpacket。
psnd.c
1 #include
2
3 #include
4 #include
5
6 #include
7 #include
8
9 static pcap_t *gfp;
10
11 static PyObject *list_device(PyObject *self, PyObject *args)
12 {
13 pcap_if_t *alldevs;
14 pcap_if_t *d;
15 int i=0;
16 char errbuf[PCAP_ERRBUF_SIZE];
17
18 /* Retrieve the device list from the local machine */
19 if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL /* auth is not needed */, &alldevs, errbuf) == -1)
20 {
21 fprintf(stderr,"Error in pcap_findalldevs_ex: %s\n", errbuf);
22 exit(1);
23 }
24
25 /* Print the list */
26 for(d= alldevs; d != NULL; d= d->next)
27 {
28 printf("%d. %s", ++i, d->name);
29 if (d->description)
30 printf(" (%s)\n", d->description);
31 else
32 printf(" (No description available)\n");
33 }
34
35 if (i == 0)
36 {
37 printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
38 return NULL;
39 }
40
41 /* We don't need any more the device list. Free it */
42 pcap_freealldevs(alldevs);
43
44 return Py_BuildValue("i",0);
45 }
46
47
48 static PyObject *open_device(PyObject *self, PyObject *args)
49 {
50 const char *name;
51 char errbuf[PCAP_ERRBUF_SIZE];
52
53 if (! PyArg_ParseTuple(args, "s", &name))
54 return NULL;
55 /* Open the output device */
56 if ( (gfp= pcap_open(name, // name of the device
57 100, // portion of the packet to capture (only the first 100 bytes)
58 PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode
59 1000, // read timeout
60 NULL, // authentication on the remote machine
61 errbuf // error buffer
62 ) ) == NULL)
63 {
64 fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", name);
65 return NULL;
66 }
67 return Py_BuildValue("i",0);
68 }
69
70
71 static PyObject *send_packet(PyObject *self, PyObject *args)
72 {
73 int len = 0;
74 const char *pEth = NULL;
75
76 int ret,i,j,k = 0;
77
78 if (! PyArg_ParseTuple(args, "s#", &pEth,&len)){
79 printf("Parse arge error,pEth = %p,len = %d\n",pEth,len);
80 return NULL;
81 }
82 // if(!gfp){
83 // fprintf(stderr,"\nInvalid fp,check if device have been opened");
84 // return NULL;
85 // }
86 assert(gfp);
87 #if 0
88 for(i = len; i > 16; i -= 16){
89 for(j = 0; j < 16; j++)
90 fprintf(stderr,"%02x ",(u_char)pEth[k++]);
91 fprintf(stderr,"\n");
92 }
93 for(; i > 0; i--)
94 fprintf(stderr,"%02x ",(u_char)pEth[k++]);
95 #endif
96 /* Send down the packet */
97 ret = pcap_sendpacket(gfp, pEth, len /* size */);
98 if (ret != 0)
99 {
100 fprintf(stderr,"\nError sending the packet: \n", pcap_geterr(gfp));
101 return NULL;
102 }
103
104 return Py_BuildValue("i",ret);
105 }
106
107 static PyMethodDef sendPacketMethods[] =
108 {
109 {"list_device", list_device, METH_VARARGS, "list all devices."},
110 {"open_device", open_device, METH_VARARGS, "open the specific device."},
111 {"send_packet", send_packet, METH_VARARGS, "send packet use mehtod in winpcap."},
112 {NULL, NULL, 0, NULL}
113 };
114
115 PyMODINIT_FUNC initpsnd()
116 {
117 Py_InitModule("psnd", sendPacketMethods);
118 }
二,定义一个安装脚本,我们使用pcap的setup.py改写,改变地方如下,同样放入sendpacket目录下。
setup.py
...
def _pcap_config( self, dirs = [ None ] ):
cfg = {}
if not dirs[0]:
dirs = glob.glob( 'c:/wpdpack*' )
...
psnd = Extension('psnd',
sources = ['psnd.c'],
include_dirs = pcap_config.get( 'include_dirs', '' ),
library_dirs = pcap_config.get( 'library_dirs', '' ),
libraries = pcap_config.get( 'libraries', '' ),
extra_compile_args = pcap_config.get( 'extra_compile_args', '' ))
pcap_cmds = { 'config':config_pcap, 'clean':clean_pcap, 'test': test_pcap}
setup (name = 'psnd',
version = '1.0',
description = 'This is a winpcap send package',
cmdclass = pcap_cmds,
ext_modules = [psnd])
脚本中c:/wpdpack*指pcap软件包的安装目录。在命令行下执行该脚本,脚本生成好的python模块psnd.pyd在build\lib.win32-2.5目录(根据python版本有不同)下,将其拷贝到C:\Python25\Lib\site-packages(根据python安装目录有不同)下。
三,安装一个网络协议数据包封装模块dpkt,然后就可以直接用python编写发包程序了,如下示例代码,其中name取了自己的网卡名:
send_packet.py
1 import sys
2 import socket
3 import random,getopt
4 import signal
5 import time
6 import psnd,dpkt
7
8 name = "rpcap://\Device\NPF_{41BF634C-A329-467C-8138-70537490C47A}"
9
10 stop = False
11 now = time.time()
12 count = 0
13
14 def sendPacket(data,protocol,ip_list):
15 ip = dpkt.ip.IP(id=0, src=ip_list[random.randint(0,ip_range - 1)],
16 dst=ip_list[random.randint(0,ip_range - 1)],
17 p=protocol)
18 ip.data = data
19 ip.len += len(data)
20
21 eth = dpkt.ethernet.Ethernet(dst='\x00\x2B\xB9\xF2\x82\xEC',src='\x00\xd0\xd0\xc5\x49\x1b')
22 eth.data = ip
23
24 #print dpkt.dpkt.hexdump(eth.pack())
25 psnd.send_packet(eth.pack())
26
27 def handler(signo, frame):
28 stop = True
29 print "time used ", time.time() - now, " seconds,","send number ",count
30
31
32 if __name__ == '__main__':
33 opts, args = getopt.getopt(sys.argv[1:], 'i:p:r:',["ip=","port=","prot="])
34
35 signal.signal(signal.SIGINT, handler)
36
37 ip_range ,port_range ,protocol_range = 10,10,10
38
39 for o,v in opts:
40 if o in ("-i","--ip"):
41 ip_range = int(v)
42 elif o in ("-p","--port"):
43 port_range = int(v)
44 elif o in ("-r","--prot"):
45 protocol_range = int(v)
46
47 psnd.list_device()
48 psnd.open_device(name)
49
50 n = raw_input("\nchose your network interface:")
51
52 #generate ip list
53 ip_list = []
54 for i in range(ip_range):
55 rip = ''
56 for j in range(4):
57 rip += chr(random.randint(1,255))
58 ip_list.append(rip)
59
60 now = time.time()
61 #while not stop:
62 for i in range(3):
63 u = dpkt.udp.UDP(sport=random.randint(1,port_range),
64 dport=random.randint(1,port_range))
65 u.data = 'hello world'
66 u.ulen += len(u.data)
67
68 t = dpkt.tcp.TCP(sport=random.randint(1,port_range),
69 dport=random.randint(1,port_range),
70 flags=random.randint(1,255))
71 t.data = 'how are you?'
72
73 print dpkt.dpkt.hexdump(t.pack())
74 #sendPacket(u,dpkt.ip.IP_PROTO_UDP,ip_list)
75 #sendPacket(t,dpkt.ip.IP_PROTO_TCP,ip_list)
76 count += 2
|
|