我正在开发一个需要修改网络数据包并附加额外标头的Linux内核模块。我已经实现了修改部分,重新计算了校验和,它工作得很好。但我不知道如何安全追加额外的标题。如果我的输入数据包是这样的:
package javaapplication1;
import javax.swing.*;
import javax.swing.JTextField;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class NewClass extends JFrame {
final int FRAME_WIDTH = 300;
final int FRAME_HEIGHT = 200;
public NewClass() {
super("ARTICULACION SOCIAL");
setSize(FRAME_WIDTH, FRAME_HEIGHT);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel heading = new JLabel("Identifiquese para entrar");
heading.setFont(new Font("Arial", Font.BOLD, 16));
JLabel namePrompt = new JLabel("Ingrese su nombre de usuario:");
JTextField nameField = new JTextField(12);
JLabel namePrompt2 = new JLabel("Ingrese su contraseña:");
JTextField nameField2 = new JTextField(12);
JButton button = new JButton("Ingresar");
setLayout(new FlowLayout());
add(heading);
add(namePrompt);
add(nameField);
add(namePrompt2);
add(nameField2);
add(button);
Escuchador escuchar = new Escuchador();
nameField.addActionListener(escuchar);
nameField2.addActionListener(escuchar);
button.addActionListener(escuchar);
}
private class Escuchador implements ActionListener{
public void actionPerformed (ActionEvent event){
String usuario="";
if (event.getSource()== nameField) {
usuario = event.getActionCommand();
}
}
}
}
我希望有一个输出数据包,如:
ip-header / tcp-header / data
对于我所读到的内容,我认为我需要类似下面的代码。我在代码上写了我的具体问题作为评论。我一般担心的是,我在这里编写的代码是否是内存安全的,或者我应该怎么做才能有一个内存安全的方法来附加新的头文件。此外,如果我做错了或有更好的方法,我也会感谢评论。我试图找到例子但到目前为止没有运气。这是代码:
ip-header / tcp-header / my-header / data
我假设变量static unsigned int my_iptables_target(struct sk_buff *skb, const struct xt_action_param *par) {
const struct xt_mytarget_info *info = par->targinfo;
/* Some code ... */
if (!skb_make_writable(skb, skb->len)) {
//Drop the packet
return NF_DROP;
}
struct newheader* myheader;
// Check if there is enough space and do something about it
if (skb_headroom(skb) < sizeof(struct newheader)) {
// So there is no enugh space.
/* I don't know well what to put here. I read that a function called pskb_expand_head might
* do the job. I do not understand very well how it works, or why it might fail (return value
* different from zero). Does this code work:
*/
if (pskb_expand_head(skb, sizeof(struct newheader) - skb_headroom(skb), 0, GPF_ATOMIC) != 0) {
// What does it mean if the code reaches this point?
return NF_DROP;
}
}
// At this point, there should be enough space
skb_push(skb, sizeof(struct newheader));
/* I also think that skb_push() creates space at the beggining, to open space between the header and
* the body I guess I must move the network/transport headers up. Perhaps something like this:
*/
memcpy(skb->data, skb->data + sizeof(struct newheader), size_of_all_headers - sizeof(struct newheader));
// Then set myheader address and fill data.
myheader = skb->data + size_of_all_headers;
//Then just set the new header, and recompute checksums.
return XT_CONTINUE;
}
包含网络和传输头的字节大小。我还认为size_of_all_headers
按递增顺序复制字节,因此调用不应成为问题。那么上面的代码是否有效?这一切都是内存安全的吗?有更好的方法吗?是否有这样的例子(或者你能提供一个)吗?
答案 0 :(得分:0)
我使用的代码类似于问题中的代码,到目前为止,它已经完成了我所做的所有测试。为了回答一些具体问题,我使用了类似的东西:
if (skb_headroom(skb) < sizeof(struct newheader)) {
printk("I got here!\n");
if (pskb_expand_head(skb, sizeof(struct newheader) - skb_headroom(skb), 0, GPF_ATOMIC) != 0) {
printk("And also here\n");
return NF_DROP;
}
}
但是没有一个打印语句被执行过。我想这是因为操作系统在内存中保留了足够的空间,因此在给定IP标头限制的情况下不会出现问题。但我认为最好留下if语句来在必要时增加数据包。
我测试和工作的代码的另一个不同之处在于,我没有移动所有其他标头来为我的标题创建空间,而是选择将数据包的主体向下移动。