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编写的微博应用
Oct 17 Python
Python3实现Web网页图片下载
Jan 28 Python
Python实现选择排序
Jun 04 Python
Python数据结构之双向链表的定义与使用方法示例
Jan 16 Python
python实现狄克斯特拉算法
Jan 17 Python
Python3模拟curl发送post请求操作示例
May 03 Python
python,Django实现的淘宝客登录功能示例
Jun 12 Python
详解pandas删除缺失数据(pd.dropna()方法)
Jun 25 Python
Pycharm使用之设置代码字体大小和颜色主题的教程
Jul 12 Python
Python全局锁中如何合理运用多线程(多进程)
Nov 06 Python
Python谱减法语音降噪实例
Dec 18 Python
python 密码学示例——理解哈希(Hash)算法
Sep 21 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 minixml详解
2008/07/19 PHP
php入门学习知识点四 PHP正则表达式基本应用
2011/07/14 PHP
解析PHP SPL标准库的用法(遍历目录,查找固定条件的文件)
2013/06/18 PHP
destoon二次开发入门示例
2014/06/20 PHP
PHP中遇到的时区问题解决方法
2015/07/23 PHP
PHP实现活动人选抽奖功能
2017/04/19 PHP
PHP长连接实现与使用方法详解
2018/02/11 PHP
ThinkPHP5.0 图片上传生成缩略图实例代码说明
2018/06/20 PHP
PDO::errorCode讲解
2019/01/28 PHP
js操作Xml(向服务器发送Xml,处理服务器返回的Xml)(IE下有效)
2009/01/30 Javascript
使用jQuery向asp.net Mvc传递复杂json数据-ModelBinder篇
2010/05/07 Javascript
html a标签-超链接中confirm方法使用介绍
2013/01/04 Javascript
jquery图片不完全按比例自动缩小的简单代码
2013/07/29 Javascript
jquery中animate的stop()方法作用实例分析
2015/01/30 Javascript
jquery实现的蓝色二级导航条效果代码
2015/08/24 Javascript
js实现的鼠标滚轮滚动切换页面效果(类似360默认页面滚动切换效果)
2016/01/27 Javascript
JS及PHP代码编写八大排序算法
2016/07/12 Javascript
深入理解JavaScript中Ajax
2016/08/02 Javascript
JS实现禁止鼠标右键的功能
2016/10/15 Javascript
微信小程序自定义模态对话框实例详解
2017/08/16 Javascript
详解ionic本地相册、拍照、裁剪、上传(单图完全版)
2017/10/10 Javascript
Nuxt.js之自动路由原理的实现方法
2018/11/21 Javascript
从理论角度讨论JavaScript闭包
2019/04/03 Javascript
vue history 模式打包部署在域名的二级目录的配置指南
2019/07/02 Javascript
磁盘垃圾文件清理器python代码实现
2020/08/24 Python
Linux下远程连接Jupyter+pyspark部署教程
2019/06/21 Python
在windows下使用python进行串口通讯的方法
2019/07/02 Python
python程序如何进行保存
2020/07/03 Python
html5+css3气泡组件的实现
2014/11/21 HTML / CSS
什么是makefile? 如何编写makefile?
2012/08/08 面试题
证婚人搞笑证婚词
2014/01/10 职场文书
城建学院毕业生自荐信
2014/01/31 职场文书
周年庆促销方案
2014/03/15 职场文书
2014党员民主评议个人思想剖析发言
2014/09/19 职场文书
JavaScript offset实现鼠标坐标获取和窗口内模块拖动
2021/05/30 Javascript
MySQL 数据恢复的多种方法汇总
2021/06/21 MySQL