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 相关文章推荐
Python3实现将文件树中所有文件和子目录归档到tar压缩文件的方法
May 22 Python
在Django的form中使用CSS进行设计的方法
Jul 18 Python
通过数据库向Django模型添加字段的示例
Jul 21 Python
python如何定义带参数的装饰器
Mar 20 Python
Python wxPython库使用wx.ListBox创建列表框示例
Sep 03 Python
pyqt远程批量执行Linux命令程序的方法
Feb 14 Python
python list多级排序知识点总结
Oct 23 Python
使用卷积神经网络(CNN)做人脸识别的示例代码
Mar 27 Python
tensorflow从ckpt和从.pb文件读取变量的值方式
May 26 Python
python利用递归方法实现求集合的幂集
Sep 07 Python
Python偏函数实现原理及应用
Nov 20 Python
PO模式在selenium自动化测试框架的优势
Mar 20 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
优化NFR之一 --MSSQL Hello Buffer Overflow
2006/10/09 PHP
xajax写的留言本
2006/11/25 PHP
PHP memcache扩展的三种安装方法
2009/04/26 PHP
php文件缓存类汇总
2014/11/21 PHP
PHP获取用户访问IP地址的5种方法
2016/05/16 PHP
Yii框架表单模型和验证用法
2016/05/20 PHP
制作特殊字的脚本
2006/06/26 Javascript
JavaScript方法和技巧大全
2006/12/27 Javascript
jquery+ajax+C#实现无刷新操作数据库数据的简单实例
2014/02/08 Javascript
jQuery+php实时获取及响应文本框输入内容的方法
2016/05/24 Javascript
JavaScript函数节流概念与用法实例详解
2016/06/20 Javascript
JavaScript ES6的新特性使用新方法定义Class
2016/06/28 Javascript
如何解决IONIC页面底部被遮住无法向上滚动问题
2016/09/06 Javascript
详解vue过滤器在v2.0版本用法
2017/06/01 Javascript
jQuery Validate插件ajax方式验证输入值的实例
2017/12/21 jQuery
AngularJS实现的自定义过滤器简单示例
2019/02/02 Javascript
JavaScript函数定义方法实例详解
2019/03/05 Javascript
jquery实现动态创建form并提交的方法示例
2019/05/27 jQuery
详解基于Wepy开发小程序插件(推荐)
2019/08/01 Javascript
微信小程序仿今日头条导航栏滚动解析
2019/08/20 Javascript
通过实例了解Nodejs模块系统及require机制
2020/07/16 NodeJs
vue 通过绑定事件获取当前行的id操作
2020/07/27 Javascript
[05:39]2014DOTA2西雅图国际邀请赛 淘汰赛7月14日TOPPLAY
2014/07/14 DOTA
[04:48]DOTA2上海特锦赛小组赛第三日 TOP10精彩集锦
2016/02/28 DOTA
[01:04:02]DOTA2-DPC中国联赛 正赛 Elephant vs IG BO3 第二场 1月24日
2021/03/11 DOTA
Java Web开发过程中登陆模块的验证码的实现方式总结
2016/05/25 Python
python使用opencv对图像mask处理的方法
2019/07/05 Python
python实现异常信息堆栈输出到日志文件
2019/12/26 Python
Django解决frame拒绝问题的方法
2020/12/18 Python
Html5实现iPhone开机界面示例代码
2013/06/30 HTML / CSS
惠普美国官方商店:HP Official Store
2016/08/28 全球购物
学生安全责任书
2014/04/15 职场文书
孩子教育的心得体会
2014/09/01 职场文书
农村党员对照检查材料
2014/09/24 职场文书
会议通知格式范文
2015/04/15 职场文书
详解PHP用mb_string处理windows中文字符
2021/05/26 PHP