Python写的一个简单DNS服务器实例


Posted in Python onJune 04, 2014

因为突然有个邪恶的想法,想在自己的Android平板上面搭建一个DNS服务器,因为平板上之前安装过SL4A和Python的解释器,也想继续学学Python因此,就打算用Python实现了。

在Google上面找了一下,Python实现的DNS,没找到我所希望的答案,因此就决定自己来实现了。

现在所实现的没什么高深的,只是能够对A记录查询进行简单的匹配和回复。

实现的代码如下:

'''
Created on 2012-10-15
@author: RobinTang
'''
import socketserver
import struct
# DNS Query
class SinDNSQuery:
    def __init__(self, data):
        i = 1
        self.name = ''
        while True:
            d = data[i]
            if d == 0:
                break;
            if d < 32:
                self.name = self.name + '.'
            else:
                self.name = self.name + chr(d)
            i = i + 1
        self.querybytes = data[0:i + 1]
        (self.type, self.classify) = struct.unpack('>HH', data[i + 1:i + 5])
        self.len = i + 5
    def getbytes(self):
        return self.querybytes + struct.pack('>HH', self.type, self.classify)
# DNS Answer RRS
# this class is also can be use as Authority RRS or Additional RRS 
class SinDNSAnswer:
    def __init__(self, ip):
        self.name = 49164
        self.type = 1
        self.classify = 1
        self.timetolive = 190
        self.datalength = 4
        self.ip = ip
    def getbytes(self):
        res = struct.pack('>HHHLH', self.name, self.type, self.classify, self.timetolive, self.datalength)
        s = self.ip.split('.')
        res = res + struct.pack('BBBB', int(s[0]), int(s[1]), int(s[2]), int(s[3]))
        return res
# DNS frame
# must initialized by a DNS query frame
class SinDNSFrame:
    def __init__(self, data):
        (self.id, self.flags, self.quests, self.answers, self.author, self.addition) = struct.unpack('>HHHHHH', data[0:12])
        self.query = SinDNSQuery(data[12:])
    def getname(self):
        return self.query.name
    def setip(self, ip):
        self.answer = SinDNSAnswer(ip)
        self.answers = 1
        self.flags = 33152
    def getbytes(self):
        res = struct.pack('>HHHHHH', self.id, self.flags, self.quests, self.answers, self.author, self.addition)
        res = res + self.query.getbytes()
        if self.answers != 0:
            res = res + self.answer.getbytes()
        return res
# A UDPHandler to handle DNS query
class SinDNSUDPHandler(socketserver.BaseRequestHandler):
    def handle(self):
        data = self.request[0].strip()
        dns = SinDNSFrame(data)
        socket = self.request[1]
        namemap = SinDNSServer.namemap
        if(dns.query.type==1):
            # If this is query a A record, then response it
            name = dns.getname();
            if namemap.__contains__(name):
                # If have record, response it
                dns.setip(namemap[name])
                socket.sendto(dns.getbytes(), self.client_address)
            elif namemap.__contains__('*'):
                # Response default address
                dns.setip(namemap['*'])
                socket.sendto(dns.getbytes(), self.client_address)
            else:
                # ignore it
                socket.sendto(data, self.client_address)
        else:
            # If this is not query a A record, ignore it
            socket.sendto(data, self.client_address)
# DNS Server
# It only support A record query
# user it, U can create a simple DNS server
class SinDNSServer:
    def __init__(self, port=53):
        SinDNSServer.namemap = {}
        self.port = port
    def addname(self, name, ip):
        SinDNSServer.namemap[name] = ip
    def start(self):
        HOST, PORT = "0.0.0.0", self.port
        server = socketserver.UDPServer((HOST, PORT), SinDNSUDPHandler)
        server.serve_forever()
# Now, test it
if __name__ == "__main__":
    sev = SinDNSServer()
    sev.addname('www.aa.com', '192.168.0.1')    # add a A record
    sev.addname('www.bb.com', '192.168.0.2')    # add a A record
    sev.addname('*', '0.0.0.0') # default address
    sev.start() # start DNS server
# Now, U can use "nslookup" command to test it
# Such as "nslookup www.aa.com"
Python 相关文章推荐
详细介绍Python语言中的按位运算符
Nov 26 Python
python连接mysql调用存储过程示例
Mar 05 Python
python网络编程之读取网站根目录实例
Sep 30 Python
Python的Django框架中URLconf相关的一些技巧整理
Jul 18 Python
Ubuntu下安装PyV8
Mar 13 Python
解析Python中的__getitem__专有方法
Jun 27 Python
Python 私有函数的实例详解
Sep 11 Python
对python捕获ctrl+c手工中断程序的两种方法详解
Dec 26 Python
详解Python logging调用Logger.info方法的处理过程
Feb 12 Python
Python 变量的创建过程详解
Sep 02 Python
python实现数字炸弹游戏
Jul 17 Python
Scrapy中如何向Spider传入参数的方法实现
Sep 28 Python
python写的ARP攻击代码实例
Jun 04 #Python
python和C语言混合编程实例
Jun 04 #Python
python实现的一个p2p文件传输实例
Jun 04 #Python
python实现文件分组复制到不同目录的例子
Jun 04 #Python
python实现的udp协议Server和Client代码实例
Jun 04 #Python
Python实现同时兼容老版和新版Socket协议的一个简单WebSocket服务器
Jun 04 #Python
Python程序员鲜为人知但你应该知道的17个问题
Jun 04 #Python
You might like
测试您的 PHP 水平的题目
2007/05/30 PHP
php 生成自动创建文件夹并上传文件的示例代码
2014/03/07 PHP
Windows下的PHP安装文件线程安全和非线程安全的区别
2014/04/23 PHP
typecho插件编写教程(四):插件挂载
2015/05/28 PHP
Yii2实现自定义独立验证器的方法
2017/05/05 PHP
详解PHP防止直接访问.php 文件的实现方法
2017/07/28 PHP
Yii 访问 Gii(脚手架)时出现 403 错误
2018/06/06 PHP
PHP实现通过文本文件统计页面访问量功能示例
2019/02/13 PHP
laravel orm 关联条件查询代码
2019/10/21 PHP
JS事件在IE与FF中的区别详细解析
2013/11/20 Javascript
三种检测iPhone/iPad设备方向的方法
2014/04/23 Javascript
jQuery+jsp实现省市县三级联动效果(附源码)
2015/12/03 Javascript
Bootstrap 折叠(Collapse)插件用法实例详解
2016/06/01 Javascript
AngularJS中实现动画效果的方法
2016/07/28 Javascript
关于react-router/react-router-dom v4 history不能访问问题的解决
2018/01/08 Javascript
JavaScript中 ES6变量的结构赋值
2018/07/10 Javascript
mpvue将vue项目转换为小程序
2018/09/30 Javascript
新版小程序登录授权的方法
2018/12/12 Javascript
Vue 3.0 前瞻Vue Function API新特性体验
2019/08/12 Javascript
解决vue 退出动画无效的问题
2020/08/09 Javascript
[29:59]完美世界DOTA2联赛PWL S3 Forest vs access 第二场 12.11
2020/12/13 DOTA
python实现mysql的单引号字符串过滤方法
2015/11/14 Python
Python Threading 线程/互斥锁/死锁/GIL锁
2019/07/21 Python
pandas如何处理缺失值
2019/07/31 Python
Django 拼接两个queryset 或是两个不可以相加的对象实例
2020/03/28 Python
Python通过yagmail实现发送邮件代码解析
2020/10/27 Python
美国帽子俱乐部商店:Hat Club
2019/07/05 全球购物
高一自我鉴定
2013/12/17 职场文书
学习十八大坚定理想信念心得体会
2014/03/11 职场文书
党日活动总结
2014/05/07 职场文书
离婚上诉状范文
2015/05/23 职场文书
爱的教育读书笔记
2015/06/26 职场文书
一篇文章弄懂MySQL查询语句的执行过程
2021/05/07 MySQL
聊一聊python常用的编程模块
2021/05/14 Python
Nginx进程调度问题详解
2021/09/25 Servers
讲解Python实例练习逆序输出字符串
2022/05/06 Python