lost and found ( for me ? )

Showing posts with label httpd. Show all posts
Showing posts with label httpd. Show all posts

scapy : simple web server with scapy

Here’s an explanation of how to make simple web server with scapy.
I am newbie to scapy and TCP , so it might be many mistakes in this post..

# apt-cache policy python-scapy | grep -i installed
 Installed: 2.2.0-1


client ( 192.168.10.205 ) -- web ( scapy 192.168.10.15 )

Before making simple web server with scapy , check HTTP pcap data with scapy.
It’s useful to learn how to build data stream with scapy.

The following is pcap date capture on web server.
( at this moment , I used Apache as an web server )

client ( 192.168.10.205 ) --- Apache ( 192.168.10.15 )


client # wget http://192.168.10.15 -O -

# tshark -nr wget.pcap
 1   0.000000 192.168.10.205 -> 192.168.10.15 TCP 74 39202 > 80 [SYN] Seq=0 Win=14600 Len=0 MSS=1460 SACK_PERM=1 TSval=85784530 TSecr=0 WS=32
 2   0.001248 192.168.10.15 -> 192.168.10.205 TCP 74 80 > 39202 [SYN, ACK] Seq=0 Ack=1 Win=14480 Len=0 MSS=1460 SACK_PERM=1 TSval=155546502 TSecr=85784530 WS=128
 3   0.001302 192.168.10.205 -> 192.168.10.15 TCP 66 39202 > 80 [ACK] Seq=1 Ack=1 Win=14624 Len=0 TSval=85784530 TSecr=155546502
 4   0.001616 192.168.10.205 -> 192.168.10.15 HTTP 179 GET / HTTP/1.1
 5   0.004509 192.168.10.15 -> 192.168.10.205 TCP 66 80 > 39202 [ACK] Seq=1 Ack=114 Win=14592 Len=0 TSval=155546503 TSecr=85784530
 6   0.004529 192.168.10.15 -> 192.168.10.205 HTTP 384 HTTP/1.1 200 OK  (text/html)
 7   0.004540 192.168.10.205 -> 192.168.10.15 TCP 66 39202 > 80 [ACK] Seq=114 Ack=319 Win=15680 Len=0 TSval=85784531 TSecr=155546503
 8   0.017647 192.168.10.205 -> 192.168.10.15 TCP 66 39202 > 80 [FIN, ACK] Seq=114 Ack=319 Win=15680 Len=0 TSval=85784534 TSecr=155546503
 9   0.017944 192.168.10.15 -> 192.168.10.205 TCP 66 80 > 39202 [FIN, ACK] Seq=319 Ack=115 Win=14592 Len=0 TSval=155546507 TSecr=85784534
10   0.017967 192.168.10.205 -> 192.168.10.15 TCP 66 39202 > 80 [ACK] Seq=115 Ack=320 Win=15680 Len=0 TSval=85784534 TSecr=155546507


read pcap with scapy.

If you have not installed scapy , you can install it with “apt-get install python-scapy”
10 packets ( a[0] , a[1] … a[9] )
# scapy
>>> a = rdpcap("wget.pcap")
>>> a
<wget.pcap: TCP:10 UDP:0 ICMP:0 Other:0>

>>> a.show()
0000 Ether / IP / TCP 192.168.10.205:39202 > 192.168.10.15:http S   <- a[0]
0001 Ether / IP / TCP 192.168.10.15:http > 192.168.10.205:39202 SA  <- a[1]
0002 Ether / IP / TCP 192.168.10.205:39202 > 192.168.10.15:http A
0003 Ether / IP / TCP 192.168.10.205:39202 > 192.168.10.15:http PA / Raw
0004 Ether / IP / TCP 192.168.10.15:http > 192.168.10.205:39202 A
0005 Ether / IP / TCP 192.168.10.15:http > 192.168.10.205:39202 PA / Raw
0006 Ether / IP / TCP 192.168.10.205:39202 > 192.168.10.15:http A
0007 Ether / IP / TCP 192.168.10.205:39202 > 192.168.10.15:http FA
0008 Ether / IP / TCP 192.168.10.15:http > 192.168.10.205:39202 FA
0009 Ether / IP / TCP 192.168.10.205:39202 > 192.168.10.15:http A  <- a[9]


a[0] : client -> web : syn
a[1] : web -> client ; syn,ack
a[2] : client -> web : ack
a[3] : client -> web : ack , HTTP GET
a[4] : web -> client : ack
a[5] : web -> client : ack , HTTP Response
a[6] : client -> web : ack
a[7] : client -> web : fin , ack
a[8] : web -> client : fin , ack
a[9] : client -> web : fin

[ syn , syn ack , ack ]

a[0] :syn packet ( client -> web )
>>> a[0].show
<bound method Ether.show of <Ether  dst=00:26:55:e1:ee:ee src=52:54:00:7b:72:35 type=IPv4 |<IP  version=4L ihl=5L tos=0x0 len=60 id=29010 flags=DF frag=0L ttl=64 proto=tcp chksum=0x333d src=192.168.10.205 dst=192.168.10.15 options=[] |<TCP  sport=39202 dport=http seq=1395951232 ack=0 dataofs=10L reserved=0L flags=S window=14600 chksum=0x965b urgptr=0 options=[('MSS', 1460), ('SAckOK', ''), ('Timestamp', (85784530, 0)), ('NOP', None), ('WScale', 5)] |>>>>


a[1] : syn , ack packet ( web -> client )
>>> a[1].show
<bound method Ether.show of <Ether  dst=52:54:00:7b:72:35 src=00:26:55:e1:ee:ee type=IPv4 |<IP  version=4L ihl=5L tos=0x0 len=60 id=0 flags=DF frag=0L ttl=64 proto=tcp chksum=0xa48f src=192.168.10.15 dst=192.168.10.205 options=[] |<TCP  sport=http dport=39202 seq=245303587 ack=1395951233 dataofs=10L reserved=0L flags=SA window=14480 chksum=0x965b urgptr=0 options=[('MSS', 1460), ('SAckOK', ''), ('Timestamp', (155546502, 85784530)), ('NOP', None), ('WScale', 7)] |>>>>


a[2] : ack packet ( client -> web )
>>> a[2].show
<bound method Ether.show of <Ether  dst=00:26:55:e1:ee:ee src=52:54:00:7b:72:35 type=IPv4 |<IP  version=4L ihl=5L tos=0x0 len=52 id=29011 flags=DF frag=0L ttl=64 proto=tcp chksum=0x3344 src=192.168.10.205 dst=192.168.10.15 options=[] |<TCP  sport=39202 dport=http seq=1395951233 ack=245303588 dataofs=8L reserved=0L flags=A window=457 chksum=0x9653 urgptr=0 options=[('NOP', None), ('NOP', None), ('Timestamp', (85784530, 155546502))] |>>>>


about ack # of a[2] ( web -> client )

ack # of a[2] ( web -> client ) must be client’s seq # ( a[0] ) plus 1

Let’s check pcap file.

the following is seq # of syn packet ( client -> web )
>>> a[0].seq
1395951232


and the following is ack # of syn , ack packet ( web -> client )
>>> a[1].ack
1395951233  <- ack # of syn,ack is client’s seq # plus 1

>>> a[1].ack == a[0].seq + 1
True


Here’s a sample script of syn , syn ack , ack part is like this :
# cat -n http_simple_server.py
    1  #!/usr/bin/env python
    2  from scapy.all import *
    3
    4  # sniff one packet from 192.168.10.205 ( tcp syn packet )
    5  a=sniff(count=1,filter="tcp and host 192.168.10.205 and port 80")
    6
    7  # get client's TCP Sport , Dport , seq number from syn packet
    8  sport_num=a[0].sport
    9  dport_num=a[0].dport
   10  seq_num=a[0].seq
   11  ack_num=a[0].seq+1
   12
   13  # build IP layer
   14  ip=IP(src="192.168.10.15",dst="192.168.10.205")
   15
   16  # build TCP layer
   17  tcp_synack=TCP(sport=dport_num, dport=sport_num,flags="SA", seq=seq_num, ack=ack_num, options=[('MSS', 1460), ('SAckOK', ''), ('NOP', None), ('WScale', 7)])
   18
   19  # send SYN ACK packet to client and get ack packet from client
   20  answer=sr1(ip/tcp_synack)


[ http get and that response ]

Next , we need to handle HTTP GET ( client -> web ) , ack ( web -> client ) and HTTP response ( web -> client )

a[3] : HTTP get request from client ( client -> web )
>>> a[3]
<Ether  dst=00:26:55:e1:ee:ee src=52:54:00:7b:72:35 type=IPv4 |<IP  version=4L ihl=5L tos=0x0 len=165 id=29012 flags=DF frag=0L ttl=64 proto=tcp chksum=0x32d2 src=192.168.10.205 dst=192.168.10.15 options=[] |<TCP  sport=39202 dport=http seq=1395951233 ack=245303588 dataofs=8L reserved=0L flags=PA window=457 chksum=0x96c4 urgptr=0 options=[('NOP', None), ('NOP', None), ('Timestamp', (85784530, 155546502))] |<Raw  load='GET / HTTP/1.1\r\nUser-Agent: Wget/1.13.4 (linux-gnu)\r\nAccept: */*\r\nHost: 192.168.10.15\r\nConnection: Keep-Alive\r\n\r\n' |>>>>


a[4] : ack to client ( web -> client )
>>> a[4]
<Ether  dst=52:54:00:7b:72:35 src=00:26:55:e1:ee:ee type=IPv4 |<IP  version=4L ihl=5L tos=0x0 len=52 id=31395 flags=DF frag=0L ttl=64 proto=tcp chksum=0x29f4 src=192.168.10.15 dst=192.168.10.205 options=[] |<TCP  sport=http dport=39202 seq=245303588 ack=1395951346 dataofs=8L reserved=0L flags=A window=114 chksum=0x9653 urgptr=0 optio


a[5] : HTTP response to client ( web -> client )
>>> a[5]
<Ether  dst=52:54:00:7b:72:35 src=00:26:55:e1:ee:ee type=IPv4 |<IP  version=4L ihl=5L tos=0x0 len=370 id=31396 flags=DF frag=0L ttl=64 proto=tcp chksum=0x28b5 src=192.168.10.15 dst=192.168.10.205 options=[] |<TCP  sport=http dport=39202 seq=245303588 ack=1395951346 dataofs=8L reserved=0L flags=PA window=114 chksum=0x9791 urgptr=0 options=[('NOP', None), ('NOP', None), ('Timestamp', (155546503, 85784530))] |<Raw  load='HTTP/1.1 200 OK\r\nDate: Mon, 10 Dec 2012 06:33:53 GMT\r\nServer: Apache/2.2.22 (Ubuntu)\r\nLast-Modified: Mon, 10 Dec 2012 06:18:23 GMT\r\nETag: "1062407-6-4d079884fb4f2"\r\nAccept-Ranges: bytes\r\nContent-Length: 6\r\nVary: Accept-Encoding\r\nKeep-Alive: timeout=5, max=100\r\nConnection: Keep-Alive\r\nContent-Type: text/html\r\n\r\nhello\n' |>>>>


a[4] : ack to client ( web -> client )

a[4]’s ack # must be a[3]’s seq + length of a[3]’ http payload.
let’s calculate to check whether or not this formula is correct.
>>> a[4].ack
1395951346

>>> a[3].seq
1395951233

>>> a[3].load
'GET / HTTP/1.1\r\nUser-Agent: Wget/1.13.4 (linux-gnu)\r\nAccept: */*\r\nHost: 192.168.10.15\r\nConnection: Keep-Alive\r\n\r\n'

>>> len(a[3].load)
113

>>> a[3].seq+len(a[3].load)
1395951346

>>> a[4].ack == a[3].seq+len(a[3].load)
True


a[4]’s seq # must be a[1]’s seq # + 1
>>> a[1].seq+1 == a[4].seq
True


a[1] is syn ack to client ( web -> client )

a[5] : HTTP response ( web -> client )
>>> a[5]
<Ether  dst=52:54:00:7b:72:35 src=00:26:55:e1:ee:ee type=IPv4 |<IP  version=4L ihl=5L tos=0x0 len=370 id=31396 flags=DF frag=0L ttl=64 proto=tcp chksum=0x28b5 src=192.168.10.15 dst=192.168.10.205 options=[] |<TCP  sport=http dport=39202 seq=245303588 ack=1395951346 dataofs=8L reserved=0L flags=PA window=114 chksum=0x9791 urgptr=0 options=[('NOP', None), ('NOP', None), ('Timestamp', (155546503, 85784530))] |<Raw  load='HTTP/1.1 200 OK\r\nDate: Mon, 10 Dec 2012 06:33:53 GMT\r\nServer: Apache/2.2.22 (Ubuntu)\r\nLast-Modified: Mon, 10 Dec 2012 06:18:23 GMT\r\nETag: "1062407-6-4d079884fb4f2"\r\nAccept-Ranges: bytes\r\nContent-Length: 6\r\nVary: Accept-Encoding\r\nKeep-Alive: timeout=5, max=100\r\nConnection: Keep-Alive\r\nContent-Type: text/html\r\n\r\nhello\n' |>>>>


a[5]’s ack # equals a[4]’s ack #
>>> a[4].ack == a[5].ack
True


a[5]’s seq # equals a[4]’s seq #
>>> a[5].seq == a[4].seq
True


[ close connections ]

a[6] , a[7] , a[8] , a[9]
0006 Ether / IP / TCP 192.168.10.205:39202 > 192.168.10.15:http A  <- a[6]
0007 Ether / IP / TCP 192.168.10.205:39202 > 192.168.10.15:http FA  <- a[7]
0008 Ether / IP / TCP 192.168.10.15:http > 192.168.10.205:39202 FA  <- a[8]
0009 Ether / IP / TCP 192.168.10.205:39202 > 192.168.10.15:http A  <- a[9]


a[6] : ack : client -> web

ack [6]’s ack # is a[5] seq + len(a[5].load)
>>> a[5].load
'HTTP/1.1 200 OK\r\nDate: Mon, 10 Dec 2012 06:33:53 GMT\r\nServer: Apache/2.2.22 (Ubuntu)\r\nLast-Modified: Mon, 10 Dec 2012 06:18:23 GMT\r\nETag: "1062407-6-4d079884fb4f2"\r\nAccept-Ranges: bytes\r\nContent-Length: 6\r\nVary: Accept-Encoding\r\nKeep-Alive: timeout=5, max=100\r\nConnection: Keep-Alive\r\nContent-Type: text/html\r\n\r\nhello\n'
>>> len(a[5].load)
318
>>> a[5].seq + len(a[5].load)
245303906
>>> a[6].ack
245303906
>>>
>>> a[6].ack == a[5].seq + len(a[5].load)
True


a[6]’s seq # is a[3].seq + len(a[3].load)
>>> a[3].load
'GET / HTTP/1.1\r\nUser-Agent: Wget/1.13.4 (linux-gnu)\r\nAccept: */*\r\nHost: 192.168.10.15\r\nConnection: Keep-Alive\r\n\r\n'

>>> len(a[3].load)
113

>>> a[3].seq + len(a[3].load)
1395951346
>>>

>>> a[3].seq
1395951233

>>> a[6].seq
1395951346

>>>
>>> a[6].seq == a[3].seq + len(a[3].load)
True


a[7] : fin , ack ( web -> client )

seq # of a[7] equals a[6]’s seq #
>>> a[7].seq == a[6].seq
True


ack # of a[7] equals a[6]’s ack #
>>> a[7].ack == a[6].ack
True


a[8] : fin , ack ( web -> client )

seq # of a[8] equals a[7]’s ack
>>> a[8].seq == a[7].ack
True


ack # of a[8] equals a[7]’s ack + plus 1
>>> a[8].ack == a[7].seq+1
True


a[9] : ack ( client -> web )

a[9]’s seq # equals a[8]’s ack
>>> a[9].seq == a[8].ack
True



a[9]’s ack # equals
>>> a[9].ack == a[8].seq+1
True


Let’s make simple web server with scapy.
# cat -n http_server_scapy.py
    1  #!/usr/bin/env python
    2  from scapy.all import *
    3  import os
    4
    5  # a[0] sniff one packet ( syn packet ) from 192.168.10.205
    6  a=sniff(count=1,filter="tcp and port 80 and host 192.168.10.205")
    7
    8  # prepare for a[1] : web -> client syn , ack
    9  Sport_num=a[0].sport
   10
   11  Seq_num1=a[0].seq  # for a[1]
   12  Ack_num1=a[0].seq+1 # for a[1]
   13
   14  # a[1] build IP layer
   15  ip=IP(src="192.168.10.15",dst="192.168.10.205")
   16
   17  # a[1] build TCP layer ( syn,ack : web -> client )
   18  tcp_synack1=TCP(sport=80, dport=Sport_num,flags="SA", seq=Seq_num1, ack=Ack_num1, options=[('MSS', 1460), ('SAckOK', ''), ('NOP', None), ('WScale', 7)])
   19
   20  # a[1] : SYN ACK packet (sr1) to client and put client's response into answer2
   21  answer2=sr1(ip/tcp_synack1)
   22
   23  # a[3] recieve the HTTP GET ( client -> web )
   24  GEThttp = sniff(filter="tcp and port 80 and host 192.168.10.205",count=1,prn=lambda x:x.sprintf("{IP:%IP.src%: %TCP.dport%}"))
   25
   26  # a[4] ack , seq number ( web -> client )
   27  Ack_num4=Ack_num1+len(GEThttp[0].load)
   28  Seq_num4=Seq_num1+1
   29
   30  # a[4] build TCP layer
   31  tcp_ack4=TCP(sport=80, dport=Sport_num, flags="AP", seq=Seq_num4, ack=Ack_num4, options=[('MSS', 1460), ('SAckOK', ''), ('NOP', None), ('WScale', 7)])
   32
   33  # a[5] send ack to client
   34  sr1(ip/tcp_ack4)
   35
   36  # a[6] build HTTP response ( web -> client )
   37  html1='HTTP/1.1 200 OK\r\nDate: Mon, 10 Dec 2012 06:33:53 GMT\r\nServer: Apache/2.2.22 (Ubuntu)\r\nLast-Modified: Mon, 10 Dec 2012 06:18:23 GMT\r\nETag: "1062407-6-4d079884fb4f2"\r\nAccept-Ranges: bytes\r\nContent-Length: 6\r\nVary: Accept-Encoding\r\nKeep-Alive: timeout=5, max=100\r\nConnection: Keep-Alive\r\nContent-Type: text/html\r\n\r\nhello\n'
   38
   39  # a[5] build TCP layer
   40  tcp5=TCP(sport=80, dport=Sport_num, flags="PA", seq=Seq_num4, ack=Ack_num4, options=[('MSS', 1460), ('SAckOK', ''), ('NOP', None), ('WScale', 7)])
   41
   42  # a[5] send HTTP response ( web -> client )
   43  answer6=sr1(ip/tcp5/html1)
   44
   45  # close connection ( web -> client )
   46  tcp6=TCP(sport=80, dport=Sport_num, flags="FA",seq=Seq_num4, ack=Ack_num4,options=[('MSS', 1460), ('SAckOK', ''), ('NOP', None), ('WScale', 7)])
   47
   48  # close connection ( web -> client )
   49  send(ip/tcp5)


Let’s test the script

client ( 192.168.10.205 ) --- scapy web server ( 192.168.10.15 )

Before running the script , add iptables rule to avoid the scapy web server from sending RST to the client.

on the scapy web server
# iptables –F
# iptables -A OUTPUT -p tcp --tcp-flags RST RST -j DROP


run the script on the scapy web server
# ./http_server_scapy.py
WARNING: No route found for IPv6 destination :: (no default route?)


wget from the client.
Okay.
# wget -d http://192.168.10.15 -O -
Setting --output-document (outputdocument) to -
DEBUG output created by Wget 1.13.4 on linux-gnu.

URI encoding = `ANSI_X3.4-1968'
--2012-12-11 17:46:52--  http://192.168.10.15/
Connecting to 192.168.10.15:80... connected.
Created socket 3.
Releasing 0x0000000001cf5650 (new refcount 0).
Deleting unused 0x0000000001cf5650.

---request begin---
GET / HTTP/1.1
User-Agent: Wget/1.13.4 (linux-gnu)
Accept: */*
Host: 192.168.10.15
Connection: Keep-Alive

---request end---
HTTP request sent, awaiting response...
---response begin---
HTTP/1.1 200 OK
Date: Mon, 10 Dec 2012 01:33:53 GMT
Server: Apache/2.2.22 (Ubuntu)
Last-Modified: Mon, 10 Dec 2012 06:18:23 GMT
ETag: "1062407-6-4d079884fb4f2"
Accept-Ranges: bytes
Content-Length: 6
Vary: Accept-Encoding
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html

---response end---
200 OK
Registered socket 3 for persistent reuse.
Length: 6 [text/html]
Saving to: `STDOUT'

0% [                                       ] 0           --.-K/s              hello
100%[======================================>] 6           --.-K/s   in 0s

2012-12-11 23:46:53 (454 KB/s) - written to stdout [6/6]


on the scapy web server
# ./http_server_scapy.py
WARNING: No route found for IPv6 destination :: (no default route?)
Begin emission:
......Finished to send 1 packets.
*
Received 7 packets, got 1 answers, remaining 0 packets
Begin emission:
.Finished to send 1 packets.
.*
Received 3 packets, got 1 answers, remaining 0 packets
Begin emission:
.Finished to send 1 packets.
*
Received 2 packets, got 1 answers, remaining 0 packets
.
Sent 1 packets.


cap data on the client.
nn , it seems that clients and server could not close connections..
anyway , I was able to establish TCP connection and send/receive HTTP data with scapy.
# tshark –nr foo.pcap
tshark: Lua: Error during loading:
[string "/usr/share/wireshark/init.lua"]:45: dofile has been disabled
Running as user "root" and group "root". This could be dangerous.
 1   0.000000 192.168.10.205 -> 192.168.10.15 TCP 74 54804 > 80 [SYN] Seq=0 Win=14600 Len=0 MSS=1460 SACK_PERM=1 TSval=366365 TSecr=0 WS=32
 2   0.115611 192.168.10.15 -> 192.168.10.205 TCP 66 80 > 54804 [SYN, ACK] Seq=0 Ack=1 Win=8192 Len=0 MSS=1460 SACK_PERM=1 WS=128
 3   0.115657 192.168.10.205 -> 192.168.10.15 TCP 54 54804 > 80 [ACK] Seq=1 Ack=1 Win=14624 Len=0
 4   0.121249 192.168.10.205 -> 192.168.10.15 HTTP 167 GET / HTTP/1.1
 5   0.467028 192.168.10.205 -> 192.168.10.15 HTTP 167 [TCP Retransmission] GET / HTTP/1.1
 6   0.489140 192.168.10.15 -> 192.168.10.205 TCP 66 80 > 54804 [PSH, ACK] Seq=1 Ack=7 Win=1048576 Len=0 MSS=1460 SACK_PERM=1 WS=128
 7   0.669716 192.168.10.15 -> 192.168.10.205 HTTP 384 HTTP/1.1 200 OK  (text/html)
 8   0.669755 192.168.10.205 -> 192.168.10.15 TCP 54 54804 > 80 [ACK] Seq=114 Ack=319 Win=15680 Len=0
 9   0.682858 192.168.10.205 -> 192.168.10.15 TCP 54 54804 > 80 [FIN, ACK] Seq=114 Ack=319 Win=15680 Len=0
10   0.752542 192.168.10.15 -> 192.168.10.205 TCP 66 80 > 54804 [PSH, ACK] Seq=1 Ack=7 Win=1048576 Len=0 MSS=1460 SACK_PERM=1 WS=128
11   0.752569 192.168.10.205 -> 192.168.10.15 TCP 54 [TCP Dup ACK 9#1] 54804 > 80 [ACK] Seq=115 Ack=319 Win=15680 Len=0
12   1.162999 192.168.10.205 -> 192.168.10.15 HTTP 161 [TCP Retransmission] HTTP/1.1
13   2.559061 192.168.10.205 -> 192.168.10.15 HTTP 161 [TCP Retransmission] HTTP/1.1


When I run the script , I sometimes face the following error.
# ./http_server_scapy.py
WARNING: No route found for IPv6 destination :: (no default route?)
Traceback (most recent call last):
 File "./http_server_scapy.py", line 11, in <module>
   Seq_num1=a[0].seq  # for a[1]
 File "/usr/lib/python2.7/dist-packages/scapy/packet.py", line 176, in __getattr__
   fld,v = self.getfield_and_val(attr)
 File "/usr/lib/python2.7/dist-packages/scapy/packet.py", line 172, in getfield_and_val
   return self.payload.getfield_and_val(attr)
 File "/usr/lib/python2.7/dist-packages/scapy/packet.py", line 172, in getfield_and_val
   return self.payload.getfield_and_val(attr)
 File "/usr/lib/python2.7/dist-packages/scapy/packet.py", line 172, in getfield_and_val
   return self.payload.getfield_and_val(attr)
 File "/usr/lib/python2.7/dist-packages/scapy/packet.py", line 172, in getfield_and_val
   return self.payload.getfield_and_val(attr)
 File "/usr/lib/python2.7/dist-packages/scapy/packet.py", line 1057, in getfield_and_val
   raise AttributeError(attr)
AttributeError: seq
#


If you see similar errors , please run the script until you succeed.
# ./http_server_scapy.py
WARNING: No route found for IPv6 destination :: (no default route?)

apache: 存在しないページのリクエストがきたときに、あるページをかえす方法

  ErrorDocument 404 のコメントアウトを外し、表示したいオブジェクトを指定する。


# egrep -i \^errordocument /etc/httpd/conf/httpd.conf
ErrorDocument 404 /hello.html

# apachectl restart


- status code 404 をかえし、そのレスポンス内に返すオブジェクトもかえす

Hypertext Transfer Protocol
    HTTP/1.1 404 Not Found\r\n
        Request Version: HTTP/1.1
        Response Code: 404
    Date: Mon, 12 Apr 2010 11:04:08 GMT\r\n
    Server: Apache/2.2.3 (CentOS)\r\n
    Last-Modified: Mon, 12 Apr 2010 10:58:53 GMT\r\n
    ETag: "4cc975-6-7d75540"\r\n
    Accept-Ranges: bytes\r\n
    Content-Length: 6\r\n
        [Content length: 6]
    Connection: close\r\n
    Content-Type: text/html; charset=UTF-8\r\n
    \r\n
Line-based text data: text/html
    hello\n  <- 返すオブジェクトの内容 ( hello )

- client の URLリクエスト部は変わらない 

Hypertext Transfer Protocol
    GET /no_object HTTP/1.1\r\n

Apache: mod_status モジュール

mod_status はステータス確認モジュール

# cat /etc/redhat-release
CentOS release 5.4 (Final)

# httpd -v
Server version: Apache/2.2.3
Server built:   Sep  3 2009 17:38:51

- httpd.conf

ExtendedStatus On

    SetHandler server-status

# apachectl restart

# apachectl status
                       Apache Server Status for localhost

   Server Version: Apache/2.2.3 (CentOS)

   Server Built: Sep 3 2009 17:38:51

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

   Current Time: Saturday, 10-Apr-2010 01:29:46 JST

   Restart Time: Saturday, 10-Apr-2010 01:29:28 JST

   Parent Server Generation: 1

   Server uptime: 17 seconds

   Total accesses: 0 - Total Traffic: 0 kB

   CPU Usage: u0 s0 cu0 cs0

   0 requests/sec - 0 B/second -

   1 requests currently being processed, 7 idle workers

 W_______........................................................
 ................................................................
 ................................................................
 ................................................................

   Scoreboard Key:
   "_" Waiting for Connection, "S" Starting up, "R" Reading Request,
   "W" Sending Reply, "K" Keepalive (read), "D" DNS Lookup,
   "C" Closing connection, "L" Logging, "G" Gracefully finishing,
   "I" Idle cleanup of worker, "." Open slot with no current process
#

# apachectl fullstatus
                       Apache Server Status for localhost

   Server Version: Apache/2.2.3 (CentOS)

   Server Built: Sep 3 2009 17:38:51

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

   Current Time: Saturday, 10-Apr-2010 01:30:14 JST

   Restart Time: Saturday, 10-Apr-2010 01:29:28 JST

   Parent Server Generation: 1

   Server uptime: 45 seconds

   Total accesses: 1 - Total Traffic: 2 kB

   CPU Usage: u0 s0 cu0 cs0

   .0222 requests/sec - 45 B/second - 2048 B/request

   1 requests currently being processed, 7 idle workers

 _W______........................................................
 ................................................................
 ................................................................
 ................................................................

   Scoreboard Key:
   "_" Waiting for Connection, "S" Starting up, "R" Reading Request,
   "W" Sending Reply, "K" Keepalive (read), "D" DNS Lookup,
   "C" Closing connection, "L" Logging, "G" Gracefully finishing,
   "I" Idle cleanup of worker, "." Open slot with no current process

Srv PID   Acc  M CPU  SS    Req    Conn Child Slot  Client   VHost    Request
                                                                   GET
0-1 2846 0/1/1 _ 0.00 27 0         0.0  0.00  0.00 127.0.0.1 127.1 /server-status
                                                                   HTTP/1.1
                                                                   GET
1-1 2847 0/0/0 W 0.00 0  479705379 0.0  0.00  0.00 127.0.0.1 127.1 /server-status
                                                                   HTTP/1.1

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

    Srv  Child Server number - generation
    PID  OS process ID
    Acc  Number of accesses this connection / this child / this slot
     M   Mode of operation
    CPU  CPU usage, number of seconds
    SS   Seconds since beginning of most recent request
    Req  Milliseconds required to process most recent request
   Conn  Kilobytes transferred this connection
   Child Megabytes transferred this child
   Slot  Total megabytes transferred this slot

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

    Apache/2.2.3 (CentOS) Server at localhost Port 80
#

ブラウザからも状態を確認できる。 http://127.1/server-status


Apache: IP-based Virtual Host

# httpd -v | head -1
Server version: Apache/2.2.3

192.168.100.1 , 192.168.100.3

- httpd.conf for IP-based Virtual Host

-- start --

# Listen 80

#
# ServerName www1.example.com
# DocumentRoot /var/www/html/www1
#



#
# ServerName www3.example.com
# DocumentRoot /var/www/html/www3
#


-- end --

ServerAdmin , ErrorLog , TransferLog ディレクティブを省略すると
デフォルト値が適用される。

# mkdir /var/www/html/www1
# mkdir /var/www/html/www3

# echo "www1" > /var/www/html/www1/index.html
# echo "www3" > /var/www/html/www3/index.html

# /etc/init.d/httpd start

- telnet で確認

# telnet 192.168.100.1 80
Trying 192.168.100.1...
Connected to 192.168.100.1 (192.168.100.1).
Escape character is '^]'.
GET / HTTP/1.0

HTTP/1.1 200 OK
Server: Apache/2.2.3 (CentOS)
ETag: "64e6c5-5-9bd2c780"
Accept-Ranges: bytes
Content-Length: 5
Connection: close
Content-Type: text/html; charset=UTF-8

www1 <- OK
Connection closed by foreign host.
#

# telnet 192.168.100.3 80
Trying 192.168.100.3...
Connected to 192.168.100.3 (192.168.100.3).
Escape character is '^]'.
GET / HTTP/1.0

HTTP/1.1 200 OK
Server: Apache/2.2.3 (CentOS)
ETag: "64e6c6-5-9c3d9740"
Accept-Ranges: bytes
Content-Length: 5
Connection: close
Content-Type: text/html; charset=UTF-8

www3 <- OK
Connection closed by foreign host.
#

get things done.