<div dir="ltr">Hello everyone, <br><br><br>I am trying to send an ICMP message in a kernel module; typically I&#39;d build the skb, set up the net_device, the ethernet header and then use dev_queue_xmit.<div><br></div><div style>

But right now I want my packet to follow the IP routing rules set in the system, so I thought I&#39;ll use ip_local_out function and let it handle the routing and setting the rest of the parameters in the skb.</div><div style>

<br></div><div style>Yet, my code causes the kernel to panic due to a NULL pointer.</div><div style> <br>The code is as follows:<br><div>/* This function assumes source and dest are in NETWORK byte order */</div><div>int sendICMPEcho(char *msg, unsigned int length, __be32 source, __be32 dest)</div>

<div>{</div><div><span class="" style="white-space:pre">        </span>struct iphdr *iph;</div><div><span class="" style="white-space:pre">        </span>struct icmphdr *icmph;</div><div><span class="" style="white-space:pre">        </span>struct sk_buff *newPacket;</div>

<div><span class="" style="white-space:pre">        </span>unsigned char *data;</div><div><span class="" style="white-space:pre">        </span>unsigned int skbSize = length + sizeof(struct icmphdr) * 2</div><div><span class="" style="white-space:pre">                                </span>+ sizeof(struct iphdr) * 2</div>

<div><span class="" style="white-space:pre">                                </span>+ sizeof(struct ethhdr) * 2;</div><div><br></div><div><span class="" style="white-space:pre">        </span>/* Allocate the skb */</div><div><span class="" style="white-space:pre">        </span>newPacket = alloc_skb(skbSize, GFP_ATOMIC);</div>

<div><span class="" style="white-space:pre">        </span>if(newPacket == NULL)</div><div><span class="" style="white-space:pre">                </span>return SEND_FAIL_MEMORY;</div><div><br></div><div><span class="" style="white-space:pre">        </span>/* Reserve the headers area */</div>

<div><span class="" style="white-space:pre">        </span>skb_reserve(newPacket, sizeof(struct icmphdr)</div><div><span class="" style="white-space:pre">                                </span> + sizeof(struct iphdr) </div><div><span class="" style="white-space:pre">                                </span>+ sizeof(struct ethhdr));<span class="" style="white-space:pre">        </span></div>

<div><br></div><div><span class="" style="white-space:pre">        </span>/* Extend the data area from 0 to the message length */</div><div><span class="" style="white-space:pre">        </span>data = skb_put(newPacket, length);</div>
<div>
<span class="" style="white-space:pre">        </span>/* Copy the data from the message buffer to the newPacket */</div><div><span class="" style="white-space:pre">        </span>memcpy(data, msg, length);</div><div><br></div><div><span class="" style="white-space:pre">        </span>/************** ICMP HEADER***************/<span class="" style="white-space:pre">        </span></div>

<div><span class="" style="white-space:pre">        </span>/* skb_push - pushing the icmp header in the packet data */</div><div><span class="" style="white-space:pre">        </span>icmph = (struct icmphdr *) skb_push(newPacket,</div>

<div><span class="" style="white-space:pre">                                                </span>sizeof(struct icmphdr));</div><div><span class="" style="white-space:pre">        </span>/*set ICMP header here */</div><div><span class="" style="white-space:pre">        </span>icmph-&gt;type = ICMP_ECHO;</div>

<div><span class="" style="white-space:pre">        </span>icmph-&gt;code = 0;</div><div><span class="" style="white-space:pre">        </span>icmph-&gt;<a href="http://un.echo.id">un.echo.id</a> = 0;</div><div><span class="" style="white-space:pre">        </span>icmph-&gt;un.echo.sequence = htons(sendCounter);</div>

<div><span class="" style="white-space:pre">        </span>icmph-&gt;checksum= 0;</div><div><span class="" style="white-space:pre">        </span>icmph-&gt;checksum = in_cksum((unsigned short *)icmph, </div><div><span class="" style="white-space:pre">                                </span>sizeof(struct icmphdr) + length);</div>

<div><span class="" style="white-space:pre">        </span>/************** END ICMP HEADER**************/</div><div><span class="" style="white-space:pre">        </span></div><div><span class="" style="white-space:pre">        </span>/************** IP HEADER ***************/</div>

<div><span class="" style="white-space:pre">        </span>iph = (struct iphdr *) skb_push(newPacket,</div><div><span class="" style="white-space:pre">                                                </span>sizeof(struct iphdr));</div><div><span class="" style="white-space:pre">        </span>/* set IP header here */</div>

<div><span class="" style="white-space:pre">        </span>iph-&gt;ihl = 5;/* 5 * 32(bits) */</div><div><span class="" style="white-space:pre">        </span>iph-&gt;version = 4;</div><div><span class="" style="white-space:pre">        </span>iph-&gt;tos = 0; /* The recommended value by IANA for ICMP request */</div>

<div><span class="" style="white-space:pre">        </span>iph-&gt;tot_len = htons( sizeof(struct iphdr) </div><div><span class="" style="white-space:pre">                                </span>+ sizeof(struct icmphdr)</div><div><span class="" style="white-space:pre">                                </span>+ length);</div>

<div><span class="" style="white-space:pre">        </span>iph-&gt;id = 0;</div><div><span class="" style="white-space:pre">        </span>iph-&gt;frag_off = 0; /* No fragementation */</div><div><span class="" style="white-space:pre">        </span>iph-&gt;ttl = 65;</div>

<div><span class="" style="white-space:pre">        </span>iph-&gt;protocol =  IPPROTO_ICMP;</div><div><span class="" style="white-space:pre">        </span>iph-&gt;saddr = source;</div><div><span class="" style="white-space:pre">        </span>iph-&gt;daddr = dest;</div>

<div><span class="" style="white-space:pre">        </span>iph-&gt;check = 0;</div><div><span class="" style="white-space:pre">        </span>iph-&gt;check = in_cksum((unsigned short *)iph, sizeof(struct iphdr));</div><div><span class="" style="white-space:pre">        </span>/************** END IP HEADER ***************/</div>

<div><br></div><div><br></div><div>//<span class="" style="white-space:pre">        </span>if(ip_local_out(newPacket) &lt; 0) THIS CRASHES WITH A NULL POINTER</div><div>//<span class="" style="white-space:pre">                </span>return SEND_FAIL_SEND;</div>

<div><span class="" style="white-space:pre">        </span>++sendCounter;</div><div><span class="" style="white-space:pre">        </span>return SEND_SUCCESS;</div><div>}</div><div>/* end sendICMPEcho */</div><div><br></div><div><div>
In my attempts when trying to solve this, I&#39;ve tried to manually set the net_device in the skb and that didn&#39;t work either; I still had the same kernel panic.</div>
<div><br></div></div><div style>So I am sorry for the trouble, any hint where the error can be?<br><br><br>Regards,<br>Adel</div></div></div>