AF_PACKET套接字解密 --- 02

AF_PACKET套接字解密 --- 02  2012-05-23 22:36:57

分类: LINUX

当AF_PACKET套接字注册了prot_hook后,怎样进行监听呢,先来看发送:

当协议栈准备将数据交给net_device发送时,它将调用dev_queue_xmit():


点击(此处)折叠或打开

  1. int dev_queue_xmit(struct sk_buff *skb)
  2. {
  3.     struct net_device *dev = skb->dev;
  4. ......
  5.                     rc = dev_hard_start_xmit(skb, dev, txq);
  6. ......
  7. }

点击(此处)折叠或打开

  1. int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
  2.             struct netdev_queue *txq)
  3. {
  4. ......
  5.         if (!list_empty(&ptype_all))
  6.             dev_queue_xmit_nit(skb, dev);
  7. ......
  8. }

由于AF_PACKET套接字注册了prot_hook,将导致dev_queue_xmit_nit()被调用:

点击(此处)折叠或打开

  1. static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
  2. {
  3.     struct packet_type *ptype;
  4.     struct sk_buff *skb2 = NULL;
  5.     struct packet_type *pt_prev = NULL;

  6.     rcu_read_lock();
  7.     list_for_each_entry_rcu(ptype, &ptype_all, list) {
  8.         /* Never send packets back to the socket
  9.          * they originated from - MvS (miquels@drinkel.ow.org)
  10.          */
  11.         if ((ptype->dev == dev || !ptype->dev) &&
  12.          (ptype->af_packet_priv == NULL ||
  13.          (struct sock *)ptype->af_packet_priv != skb->sk)) {
  14.             if (pt_prev) {
  15.                 deliver_skb(skb2, pt_prev, skb->dev);
  16.                 pt_prev = ptype;
  17.                 continue;
  18.             }

  19.             skb2 = skb_clone(skb, GFP_ATOMIC);
  20.             if (!skb2)
  21.                 break;
  22. ......
  23.         }
  24.     }
  25.     if (pt_prev)
  26.         pt_prev->func(skb2, skb->dev, pt_prev, skb->dev);
  27.     rcu_read_unlock();
  28. }
在遍历ptype_all链表时,这里有几点需要着重说明:

1:对于发送的包过滤条件有:
    1). net_device是否是prot_hook指定的dev(NULL代表全部匹配)。
    2). ptype->af_packet_priv在packet_creat()中被设定为自己,故自己发送的包不会被监听。

2:遍历ptype_all时,第一次会复制skb;只有ptype_all中不止1个entry时,将调用deliver_skb()。

3:当退出遍历时,将调用prot_hook的func成员,即packet_rcv()。

4: deliver_skb()仅仅是在调用prot_hook的func成员前增加skb的引用计算数。

点击(此处)折叠或打开

  1. static int packet_rcv(struct sk_buff *skb, struct net_device *dev,
  2.          struct packet_type *pt, struct net_device *orig_dev)
  3. {
  4. ......
  5.     __skb_queue_tail(&sk->sk_receive_queue, skb);
  6. ......
  7. }
经过packet_rcv(),发送的数据包被加入到了AF_PACKET套接字的接收队列,等待我们的读取。。。一切就是这么简单!
import cv2 import socket import numpy as np import struct import sqlite3 from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.primitives import padding from cryptography.hazmat.backends import default_backend key = b'0123456789abcdef0123456789abcdef' iv = b'0123456789abcdef' # 连接到数据库 conn = sqlite3.connect('video.db') cursor = conn.cursor() # 创建videos表 cursor.execute("CREATE TABLE IF NOT EXISTS videos (id INTEGER PRIMARY KEY, path TEXT)") path = 'M:/img/xinxixitong.avi' fourcc = cv2.VideoWriter_fourcc(*'XVID') out = cv2.VideoWriter(path, fourcc, 30, (640, 480)) # 解密函数 def dt_f(ciphertext, key, iv): # 创建 AES 解密器 dt = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend()).decryptor() # 解密图像 padded_data = dt.update(ciphertext) + dt.finalize() # 移除填充 unpadder = padding.PKCS7(128).unpadder() unpadded_data = unpadder.update(padded_data) + unpadder.finalize() return unpadded_data # 服务端IP和端口号 HOST = '0.0.0.0' # 任意IP地址 PORT = 6666 # 创建套接字对象 with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sk: sk.bind((HOST, PORT)) sk.listen(5) print('等待连接...') # 接受连接请求 client_conn, addr = sk.accept() with client_conn: print('与', addr,'相连接') data_buffer = b'' # 缓存数据 while True: data = client_conn.recv(6) #如果没有数据传输则停止 if not data: break size = struct.unpack('!I', data)[0] # 接收到的帧数据 data = b'' while len(data) < size: packet = client_conn.recv(size - len(data)) if not packet: break data += packet # 解密帧 dted_f = dt_f(data, key, iv) # data_buffer += dt_f # 添加到缓存中 # 将解密后的 bytes 数据转换为图像帧 dted_f = np.frombuffer(dted_f, dtype=np.uint8).reshape(480, 640, 3) # 显示解密后的帧 cv2.imshow("2021218000_dted_Server", dted_f) out.write(dted_f) if cv2.waitKey(1) in [ord('q'),27]: out.release() break cursor.execute('INSERT INTO videos (path) VALUES (?)', (path,)) conn.commit() conn.close() cv2.destroyAllWindows()
06-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值