📄 ip_in.c
字号:
else if (route->flags & RT_BRDCST) { /*-----------------------------------------------------------------*/ /* If gateway, check for directed broadcast. */ /*-----------------------------------------------------------------*/ if (Net.IsGateway && (RxBuf->ni != route->ni)) { NetBuf *fbuf = tcpGetBuf(length); /*---------------------------------------------------------------*/ /* Forward directed broadcast to indicated network interface. */ /*---------------------------------------------------------------*/ if (fbuf) { /*-------------------------------------------------------------*/ /* Copy packet and initialize buffer. */ /*-------------------------------------------------------------*/ memcpy(fbuf->ip_pkt, RxBuf->ip_pkt, hlen); memcpy(fbuf->ip_pkt + hlen, RxBuf->ip_data, length - hlen); fbuf->next_hop = ip->dst_ip; fbuf->ni = route->ni; fbuf->type = RxBuf->type; fbuf->next_hop = 0; /*-------------------------------------------------------------*/ /* Change IP header to host byte order. */ /*-------------------------------------------------------------*/ ip = (Ip *)fbuf->ip_pkt; ip->length = htons(ip->length); ip->ip_id = htons(ip->ip_id); ip->frag_off = htons(ip->frag_off); /*-------------------------------------------------------------*/ /* Post to TCP/IP processing queue. */ /*-------------------------------------------------------------*/ if (NetPostMsg(IpOut, fbuf, ATTN_REQ)) { ++Stats.IpOutDiscards; tcpRetBuf(&fbuf); } } } /*-----------------------------------------------------------------*/ /* Pass to higher protocol layer. */ /*-----------------------------------------------------------------*/ IpLocalIn(); } /*-------------------------------------------------------------------*/ /* Else not to us. */ /*-------------------------------------------------------------------*/ else { /*-----------------------------------------------------------------*/ /* If inbound and outbound networks match, send redirect message. */ /*-----------------------------------------------------------------*/ if (RxBuf->ni == route->ni) { Route *tprt; int rdtype; /*---------------------------------------------------------------*/ /* Get route to sender and check that it is direct. */ /*---------------------------------------------------------------*/ tprt = RtSearch(ip->src_ip); if (tprt && !(tprt->flags & RT_GATEWAY)) { /*-------------------------------------------------------------*/ /* Network redirect if mask is subnetted, else host. */ /*-------------------------------------------------------------*/ if (route->mask == IpSubnetMask(route->addr)) rdtype = ICC_NETRD; else rdtype = ICC_HOSTRD; IcmpRedirect(rdtype, route->gw, ip->src_ip, ip->dst_ip); } } /*-----------------------------------------------------------------*/ /* Discard if we're not a gateway. */ /*-----------------------------------------------------------------*/ if (!Net.IsGateway) ++Stats.IpInAddrErrors; /*-----------------------------------------------------------------*/ /* Else forward if we are a gateway. */ /*-----------------------------------------------------------------*/ else { /*---------------------------------------------------------------*/ /* Decrement TTL and generate ICMP message if expired. */ /*---------------------------------------------------------------*/ if (--ip->ttl == 0) { ++Stats.IpInHdrErrors; IcmpTimeEx(ICC_TIMEX, RxBuf, ip->src_ip, ip->dst_ip); } /*---------------------------------------------------------------*/ /* Else forward to indicated network interface. */ /*---------------------------------------------------------------*/ else { /*-------------------------------------------------------------*/ /* Check if header alignment created new region. */ /*-------------------------------------------------------------*/ if (RxBuf->ip_data != RxBuf->ip_pkt + hlen) { RxBuf->app_data = RxBuf->ip_data; RxBuf->app_len = ip->length - hlen; RxBuf->order = 1; } /*-------------------------------------------------------------*/ /* Assign network interface and next hop IP address. */ /*-------------------------------------------------------------*/ if (route->flags & RT_GATEWAY) RxBuf->next_hop = route->gw; else RxBuf->next_hop = ip->dst_ip; RxBuf->ni = route->ni; /*-------------------------------------------------------------*/ /* Change IP header to host byte order. */ /*-------------------------------------------------------------*/ ip->length = htons(ip->length); ip->ip_id = htons(ip->ip_id); ip->frag_off = htons(ip->frag_off); /*-------------------------------------------------------------*/ /* Post to TCP/IP queue. Do not return buffer if successful. */ /*-------------------------------------------------------------*/ if (NetPostMsg(IpOut, RxBuf, ATTN_REQ)) ++Stats.IpOutDiscards; else RxBuf = NULL; ++Stats.IpForwDatagrams; } } }}/***********************************************************************//* IpSend: Complete IP header and send to specified address *//* *//* Inputs: route = pointer to route entry for outbound packet *//* buf = pointer to buffer containing packet *//* datalen = length of IP data *//* tos = type of service/priority flag *//* *//***********************************************************************/void IpSend(const Route *route, NetBuf *buf, int datalen, ui8 tos){ Ip *ip = (Ip *)buf->ip_pkt; /*-------------------------------------------------------------------*/ /* Write IP header info (other than src/dst address and protocol). */ /*-------------------------------------------------------------------*/ ip->ver_len = (IP_VERSION << 4) | (IPMHLEN >> 2); ip->ip_tos = tos; ip->length = datalen + IPMHLEN; ip->ip_id = Net.IpAckId++; ip->frag_off = 0; ip->ttl = IP_TTL_DEF; /*-------------------------------------------------------------------*/ /* Complete buffer header information. */ /*-------------------------------------------------------------------*/ buf->type = htons(IP_TYPE); buf->ni = route->ni; /*-------------------------------------------------------------------*/ /* If sending unicast, select the appropriate next hop address. */ /*-------------------------------------------------------------------*/ if ((route->flags & RT_BRDCST) == FALSE) { if (route->flags & RT_GATEWAY) buf->next_hop = route->gw; else buf->next_hop = ip->dst_ip; } /*-------------------------------------------------------------------*/ /* Else packet is being broadcast. */ /*-------------------------------------------------------------------*/ else { /*-----------------------------------------------------------------*/ /* If limited broadcast, route is directed to the local interface. */ /* Send copies to every other interface. */ /*-----------------------------------------------------------------*/ if (ip->dst_ip == INADDR_BROADCAST) limited_bcst(buf, ip); /*-----------------------------------------------------------------*/ /* Else directed broadcast. Route is directed to subnet interface. */ /*-----------------------------------------------------------------*/ else { NetBuf *lbuf = tcpGetBuf(NIMHLEN + ip->length); /*---------------------------------------------------------------*/ /* If buffer available, make copy for local interface. */ /*---------------------------------------------------------------*/ if (lbuf) { memcpy(lbuf->ip_pkt, buf->ip_pkt, ip->length); if (NetPostMsg(IpOut, lbuf, ATTN_REQ)) { ++Stats.IpOutDiscards; tcpRetBuf(&lbuf); } } /*---------------------------------------------------------------*/ /* Set broadcast flag for NiWrite(). */ /*---------------------------------------------------------------*/ buf->next_hop = 0; } } /*-------------------------------------------------------------------*/ /* Post to TCP/IP processing queue. */ /*-------------------------------------------------------------------*/ if (NetPostMsg(IpOut, buf, ATTN_REQ)) { ++Stats.IpOutDiscards; tcpRetBuf(&buf); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -