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模拟登陆Tom邮箱示例分享
Jan 13 Python
Python的函数嵌套的使用方法
Jan 24 Python
Python实现基于权重的随机数2种方法
Apr 28 Python
Python json 错误xx is not JSON serializable解决办法
Mar 15 Python
python中的Elasticsearch操作汇总
Oct 30 Python
Python3标准库之functools管理函数的工具详解
Feb 27 Python
使用python客户端访问impala的操作方式
Mar 28 Python
基于python调用jenkins-cli实现快速发布
Aug 14 Python
Python datetime 如何处理时区信息
Sep 02 Python
python安装cx_Oracle和wxPython的方法
Sep 14 Python
浅谈Python中的正则表达式
Jun 28 Python
python代码实现扫码关注公众号登录的实战
Nov 01 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 cli 方式 在crotab中运行解决
2010/02/08 PHP
初识php MVC
2014/09/10 PHP
ThinkPHP实现动态包含文件的方法
2014/11/29 PHP
PHP抓取淘宝商品的用户晒单评论+图片+搜索商品列表实例
2016/04/14 PHP
php实现银联商务公众号+服务窗支付的示例代码
2019/10/12 PHP
提高网站性能之 如何对待JavaScript
2009/10/31 Javascript
JavaScript setTimeout和setInterval的使用方法 说明
2010/03/25 Javascript
TextArea设置MaxLength属性最大输入值的js代码
2012/12/21 Javascript
jQuery随便控制任意div隐藏的方法
2013/06/28 Javascript
javascript中自定义对象的属性方法分享
2013/07/12 Javascript
js中把JSON字符串转换成JSON对象最好的方法
2014/03/21 Javascript
JS中attr和prop属性的区别以及优先选择示例介绍
2014/06/30 Javascript
JS组件Bootstrap实现下拉菜单效果代码
2016/04/26 Javascript
jquery+CSS3实现3D拖拽相册效果
2016/07/18 Javascript
js实现下一页页码效果
2017/03/07 Javascript
Node.js中流(stream)的使用方法示例
2017/07/16 Javascript
微信小程序项目实践之主页tab选项实现
2018/07/18 Javascript
[07:39]第一届亚洲邀请赛回顾视频
2017/02/14 DOTA
[01:33:14]LGD vs VP Supermajor 败者组决赛 BO3 第二场 6.10
2018/07/04 DOTA
Python使用Matplotlib模块时坐标轴标题中文及各种特殊符号显示方法
2018/05/04 Python
pycharm下查看python的变量类型和变量内容的方法
2018/06/26 Python
详解Python循环作用域与闭包
2019/03/21 Python
使用Pytorch来拟合函数方式
2020/01/14 Python
python 实现图片修复(可用于去水印)
2020/11/19 Python
纯css3制作的火影忍者写轮眼开眼至轮回眼及进化过程实例
2014/11/11 HTML / CSS
阿迪达斯墨西哥官方网站:adidas墨西哥
2017/11/03 全球购物
Timberland法国官网:购买靴子、鞋子、衣服、夹克和配饰
2019/11/30 全球购物
说一下Linux下有关用户和组管理的命令
2016/01/04 面试题
晚会邀请函范文
2014/01/24 职场文书
表演方阵解说词
2014/02/08 职场文书
语文教育专业求职信
2014/06/28 职场文书
2015年乡镇工作总结范文
2015/04/22 职场文书
2015小学师德工作总结
2015/07/21 职场文书
《画家和牧童》教学反思
2016/02/17 职场文书
Python+Appium实现自动抢微信红包
2021/05/21 Python
pandas中对文本类型数据的处理小结
2021/11/01 Python