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使用MySQLdb for Python操作数据库教程
Oct 11 Python
Python实现过滤单个Android程序日志脚本分享
Jan 16 Python
Python中基本的日期时间处理的学习教程
Oct 16 Python
Python实现通过文件路径获取文件hash值的方法
Apr 29 Python
python中数据爬虫requests库使用方法详解
Feb 11 Python
基于python指定包的安装路径方法
Oct 27 Python
关于python字符串方法分类详解
Aug 20 Python
Python 通过截图匹配原图中的位置(opencv)实例
Aug 27 Python
TensorFlow——Checkpoint为模型添加检查点的实例
Jan 21 Python
django3.02模板中的超链接配置实例代码
Feb 04 Python
使用Python获取当前工作目录和执行命令的位置
Mar 09 Python
python实现感知机模型的示例
Sep 30 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获取音频文件的相关信息
2015/06/22 PHP
番茄的表单验证类代码修改版
2008/07/18 Javascript
理解JavaScript的caller,callee,call,apply
2009/04/28 Javascript
JavaScript Event学习第十一章 按键的检测
2010/02/10 Javascript
Jquery+JSon 无刷新分页实现代码
2010/04/01 Javascript
两种简单实现菜单高亮显示的JS类代码
2010/06/27 Javascript
JS TextArea字符串长度限制代码集合
2012/10/31 Javascript
JS控制一个DIV层在指定时间内消失的方法
2014/02/17 Javascript
jQuery实现首页图片淡入淡出效果的方法
2015/06/10 Javascript
自己动手写的jquery分页控件(非常简单实用)
2015/10/28 Javascript
JS封装cookie操作函数实例(设置、读取、删除)
2015/11/17 Javascript
JS及PHP代码编写八大排序算法
2016/07/12 Javascript
轻松掌握JavaScript装饰者模式
2016/08/27 Javascript
VueJS如何引入css或者less文件的一些坑
2017/04/25 Javascript
react-navigation 如何判断用户是否登录跳转到登录页的方法
2017/12/01 Javascript
vue + vuex todolist的实现示例代码
2018/03/09 Javascript
node.js中Buffer缓冲器的原理与使用方法分析
2019/11/23 Javascript
[05:34]2014DOTA2国际邀请赛中国区预选赛精彩TOPPLAY第二弹
2014/06/25 DOTA
python实现向ppt文件里插入新幻灯片页面的方法
2015/04/28 Python
Python字符串特性及常用字符串方法的简单笔记
2016/01/04 Python
Python SMTP发送邮件遇到的一些问题及解决办法
2018/10/24 Python
利用selenium爬虫抓取数据的基础教程
2019/06/10 Python
Python中判断子串存在的性能比较及分析总结
2019/06/23 Python
浅谈tensorflow模型保存为pb的各种姿势
2020/05/25 Python
Python 创建守护进程的示例
2020/09/29 Python
matplotlib绘制正余弦曲线图的实现
2021/02/22 Python
html+css实现自定义图片上传按钮功能
2019/09/04 HTML / CSS
美国NBA官方商店:NBA Store
2019/04/12 全球购物
全球异乡人的跨境社交电商平台:Kouhigh口嗨网
2020/07/24 全球购物
摄影实习自我鉴定
2013/09/20 职场文书
班长岗位职责
2013/11/10 职场文书
金融专业大学生职业生涯规划范文
2014/01/16 职场文书
《燕子》教学反思
2014/02/18 职场文书
党员创先争优承诺书
2014/03/26 职场文书
Django实现翻页的示例代码
2021/05/24 Python
索尼ICF-36收音机评测
2022/04/30 无线电