icmp port unreachable
阅读原文时间:2023年07月09日阅读:1

端口不可达:

client------>server 结果server回复端口不可达,

由于是icmp报文; 到达client内核协议栈后进入icmp_rcv处理:

/*
* Deal with incoming ICMP packets.
*/
int icmp_rcv(struct sk_buff *skb)
{
struct icmphdr *icmph;
struct rtable *rt = skb_rtable(skb);
struct net *net = dev_net(rt->dst.dev);
bool success;

success = icmp\_pointers\[icmph->type\].handler(skb);

if (success)  {  
    consume\_skb(skb);  
    return 0;  
}  

}
--->/*
* Handle ICMP_DEST_UNREACH, ICMP_TIME_EXCEED, ICMP_QUENCH, and
* ICMP_PARAMETERPROB.
*/

static bool icmp_unreach(struct sk_buff *skb)
{
const struct iphdr *iph;
struct icmphdr *icmph;
struct net *net;
u32 info = 0;

net = dev\_net(skb\_dst(skb)->dev);

/\*  
 \*    Incomplete header ?  
 \*     Only checks for the IP header, there should be an  
 \*    additional check for longer headers in upper levels.  
 \*/

if (!pskb\_may\_pull(skb, sizeof(struct iphdr)))  
    goto out\_err;

icmp\_socket\_deliver(skb, info);

out:
return true;
out_err:
__ICMP_INC_STATS(net, ICMP_MIB_INERRORS);
return false;
}

static void icmp_socket_deliver(struct sk_buff *skb, u32 info)
{
const struct iphdr *iph = (const struct iphdr *) skb->data;
const struct net_protocol *ipprot;
int protocol = iph->protocol;

/\* Checkin full IP header plus 8 bytes of protocol to  
 \* avoid additional coding at protocol handlers.  
 \*/  
if (!pskb\_may\_pull(skb, iph->ihl \* 4 + 8)) {  
    \_\_ICMP\_INC\_STATS(dev\_net(skb->dev), ICMP\_MIB\_INERRORS);  
    return;  
}

raw\_icmp\_error(skb, protocol, info);

ipprot = rcu\_dereference(inet\_protos\[protocol\]);  
if (ipprot && ipprot->err\_handler)  
    ipprot->err\_handler(skb, info);//----udp\_err(struct sk\_buff \* skb, u32 info)  

}

:最后根据 icmp里面的  控制信息找到对应协议处理;udp_err  tcp_v4_err等

然后唤醒进程 wake_up