Решил оставить скрипт - за неделю ни разу не отвалился. (если все же будут косяки - порекомендовали попробовать freeBSD с netgraph'ом)
Вот скрипт
#!/usr/bin/env python
import socket, sys, struct, datetime
from struct import *
#ethtool -K eth1 tx off
BUF_SIZE = 1600 # > 1500
ETH_P_ALL = 3 # To receive all Ethernet protocols
InterfaceIN = "eth1"
InterfaceOUT = "eth0"
# Open socket for input packets
sockINPUT = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(ETH_P_ALL))
sockINPUT.bind((InterfaceIN, 0))
sockINPUT.setblocking(1)
# Open socket for output packets
sockOUTPUT = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(ETH_P_ALL))
sockOUTPUT.bind((InterfaceOUT, 0))
sockOUTPUT.setblocking(1)
print 'Raw socket opened'
while True:
packet = sockINPUT.recvfrom(65565)
packet = packet[0]
#parse ethernet header
eth_length = 14
eth_header = packet[:eth_length]
eth = unpack('!6s6sH' , eth_header)
eth_protocol = socket.ntohs(eth[2])
if eth_protocol == 8 :
ip_header = packet[eth_length:20+eth_length]
#now unpack them :)
iph = unpack('!BBHHHBBH4s4s' , ip_header)
version_ihl = iph[0]
version = version_ihl >> 4
ihl = version_ihl & 0xF
iph_length = ihl * 4
#ttl = iph[5]
protocol = iph[6]
s_addr = socket.inet_ntoa(iph[8]);
d_addr = socket.inet_ntoa(iph[9]);
#print dir(cap_out)
print str(datetime.datetime.now())+' Source Address : ' + str(s_addr) + ' Destination Address : ' + str(d_addr)
#UDP packets
#UDP packets
if protocol == 17 :
#print 'Version : ' + str(version) + ' IP Header Length : ' + str(ihl) + ' TTL : ' + str(ttl) + ' Protocol : ' + str(protocol) + ' Source Address : ' + str(s_addr) + ' Destination Address : ' + $
u = iph_length + eth_length
udph_length = 8
udp_header = packet[u:u+4]
#now unpack them :)
udph = unpack('!HH' , udp_header)
#print type(udp_header)
source_port = udph[0]
dest_port = udph[1]
#length = udph[2]
#checksum = udph[3]
#38906
if source_port == 38906:
#print 'Source Port : ' + str(source_port) + ' Dest Port : ' + str(dest_port)
#print packet
udp_header = pack('!HH' , 5060, dest_port)
packet = packet[:u]+ udp_header + packet[u+4:]
#print UDP headers
print 'UDP sport : ' + str(source_port) + ' dport : ' + str(dest_port)
sockOUTPUT.send(packet)
sockINPUT.close()
sockOUTPUT.close()