📄 ip_read.c
字号:
{
#if DEBUG
{ where(); where(); printf("fragment not allright\n"); }
#endif
bf_afree(ip_acc);
bf_afree(eth_acc);
return;
}
for_this_port= ok_for_port(ip_port, ip_hdr->ih_dst,
&broadcast_allowed);
if (!broadcast_allowed && broadcast_pack)
{
printf("got eth-broadcast pack for ip-nonbroadcast addr, src=");
writeIpAddr(ip_hdr->ih_src);
printf(" dst=");
writeIpAddr(ip_hdr->ih_dst);
printf("\n");
bf_afree(ip_acc);
bf_afree(eth_acc);
return;
}
#if !IP_ROUTER
if (!for_this_port)
{
#if DEBUG
{ where(); printf("ip.c: got strange packet, src=");
writeIpAddr(ip_hdr->ih_src); printf(" dst="); writeIpAddr(ip_hdr->ih_dst);
printf(" src_eth= "); writeEtherAddr(ð_src); printf(" dst_eth= ");
writeEtherAddr(ð_dst); printf("\n"); }
#endif
bf_afree(ip_acc);
bf_afree(eth_acc);
return;
}
#else
if (!for_this_port)
{
bf_afree(eth_acc);
ip_route(ip_port, ip_acc);
return;
}
#endif /* !IP_ROUTER */
bf_afree(eth_acc);
if (ntohs(ip_hdr->ih_flags_fragoff) & (IH_FRAGOFF_MASK|IH_MORE_FRAGS))
{
#if DEBUG & 256
{ where(); printf("reassembling\n"); }
#endif
ip_acc= reassemble (ip_port, ip_acc, ip_hdr);
if (!ip_acc)
return;
assert (ip_acc->acc_length >= IP_MIN_HDR_SIZE);
ip_hdr= (ip_hdr_t *)ptr2acc_data(ip_acc);
assert (!(ntohs(ip_hdr->ih_flags_fragoff) & (IH_FRAGOFF_MASK|IH_MORE_FRAGS)));
}
ip_port_arrive (ip_port, ip_acc, ip_hdr);
}
PRIVATE int ok_for_port (ip_port, ipaddr, ref_broad_all)
ip_port_t *ip_port;
ipaddr_t ipaddr;
int *ref_broad_all;
{
ipaddr_t netmask;
#if DEBUG & 256
{ where(); printf("ok_for_port( .., "); writeIpAddr(ipaddr);
printf(", ..)\nip_port->ip_ipaddr= ");
writeIpAddr(ip_port->ip_ipaddr); printf("\n"); }
#endif
if (ipaddr == ip_port->ip_ipaddr)
*ref_broad_all= FALSE;
else if (ipaddr == (ipaddr_t)-1)
*ref_broad_all= TRUE;
else if (net_broad (ipaddr, ip_port->ip_ipaddr &
ip_port->ip_netmask, ip_port->ip_netmask))
*ref_broad_all= TRUE;
else
{
netmask= ip_get_netmask(ipaddr);
if (!net_broad (ipaddr, ip_port->ip_ipaddr & netmask,
netmask))
return FALSE;
*ref_broad_all= TRUE;
}
return TRUE;
}
PRIVATE int ip_frag_chk(pack)
acc_t *pack;
{
ip_hdr_t *ip_hdr;
int hdr_len;
if (pack->acc_length < sizeof(ip_hdr_t))
{
#if DEBUG
{ where(); printf("wrong length\n"); }
#endif
return FALSE;
}
ip_hdr= (ip_hdr_t *)ptr2acc_data(pack);
hdr_len= (ip_hdr->ih_vers_ihl & IH_IHL_MASK) * 4;
if (pack->acc_length < hdr_len)
{
#if DEBUG
{ where(); printf("wrong length\n"); }
#endif
return FALSE;
}
if (((ip_hdr->ih_vers_ihl >> 4) & IH_VERSION_MASK) !=
IP_VERSION)
{
#if DEBUG
{ where(); printf("wrong version (ih_vers_ihl=0x%x)\n",ip_hdr->ih_vers_ihl); }
#endif
return FALSE;
}
if (ntohs(ip_hdr->ih_length) != bf_bufsize(pack))
{
#if DEBUG
{ where(); printf("wrong size\n"); }
#endif
return FALSE;
}
if ((u16_t)~oneC_sum(0, (u16_t *)ip_hdr, hdr_len))
{
#if DEBUG
{ where(); printf("packet with wrong checksum (= %x)\n",
(u16_t)~oneC_sum(0, (u16_t *)ip_hdr, hdr_len)); }
#endif
return FALSE;
}
if (hdr_len>IP_MIN_HDR_SIZE && ip_chk_hdropt((u8_t *)
(ptr2acc_data(pack) + IP_MIN_HDR_SIZE),
hdr_len-IP_MIN_HDR_SIZE))
{
#if DEBUG
{ where(); printf("packet with wrong options\n"); }
#endif
return FALSE;
}
return TRUE;
}
PRIVATE int net_broad (hostaddr, netaddr, netmask)
ipaddr_t hostaddr, netaddr, netmask;
{
if ((hostaddr & netmask) != (netaddr & netmask))
return FALSE;
if ((hostaddr & ~netmask) == ~netmask)
return TRUE;
#if IP_SUN_BROADCAST
if ((hostaddr & ~netmask) == 0)
return TRUE;
#endif
return FALSE;
}
PUBLIC int ip_packet2user (ip_fd)
ip_fd_t *ip_fd;
{
acc_t *pack, *tmp_pack;
ip_hdr_t *hdr;
int result, hdr_len;
size_t size, transf_size;
pack= ip_fd->if_rd_buf;
ip_fd->if_rd_buf= 0;
size= bf_bufsize (pack);
if (ip_fd->if_ipopt.nwio_flags & NWIO_RWDATONLY)
{
pack= bf_packIffLess (pack, IP_MIN_HDR_SIZE);
assert (pack->acc_length >= IP_MIN_HDR_SIZE);
hdr= (ip_hdr_t *)ptr2acc_data(pack);
hdr_len= (hdr->ih_vers_ihl & IH_IHL_MASK) * 4;
assert (size>= hdr_len);
size -= hdr_len;
tmp_pack= bf_cut(pack, hdr_len, size);
bf_afree(pack);
pack= tmp_pack;
}
if (size>ip_fd->if_rd_count)
{
tmp_pack= bf_cut (pack, 0, ip_fd->if_rd_count);
bf_afree(pack);
pack= tmp_pack;
transf_size= ip_fd->if_rd_count;
}
else
transf_size= size;
result= (*ip_fd->if_put_userdata)(ip_fd->if_srfd,
(size_t)0, pack, FALSE);
if (result >= 0)
if (size > transf_size)
result= EPACKSIZE;
else
result= transf_size;
#if DEBUG & 256
{ where(); printf("packet2user cleared IFF_READ_IP\n"); }
#endif
ip_fd->if_flags &= ~IFF_READ_IP;
result= (*ip_fd->if_put_userdata)(ip_fd->if_srfd, result,
(acc_t *)0, FALSE);
assert (result >= 0);
return result;
}
PUBLIC int ip_ok_for_fd (ip_fd, pack)
ip_fd_t *ip_fd;
acc_t *pack;
{
ip_port_t *ip_port;
ip_hdr_t *hdr;
ipaddr_t dst;
unsigned long pack_kind, nwio_flags;
assert (pack->acc_length >= IP_MIN_HDR_SIZE);
ip_port= ip_fd->if_port;
hdr= (ip_hdr_t *)ptr2acc_data(pack);
dst= hdr->ih_dst;
if (dst == ip_port->ip_ipaddr)
pack_kind= NWIO_EN_LOC;
else
pack_kind= NWIO_DI_LOC;
nwio_flags= ip_fd->if_ipopt.nwio_flags;
if (!(pack_kind & nwio_flags))
return FALSE;
if ((nwio_flags & NWIO_PROTOSPEC) &&
(hdr->ih_proto != ip_fd->if_ipopt.nwio_proto))
return FALSE;
if ((nwio_flags & NWIO_REMSPEC) &&
(hdr->ih_src != ip_fd->if_ipopt.nwio_rem))
return FALSE;
return TRUE;
}
PUBLIC void ip_port_arrive (ip_port, pack, ip_hdr)
ip_port_t *ip_port;
acc_t *pack;
ip_hdr_t *ip_hdr;
{
ip_fd_t *ip_fd, *share_fd;
ip_hdr_t *hdr;
int port_nr;
unsigned long ip_pack_stat;
int i;
ipproto_t proto;
time_t exp_tim;
assert (pack->acc_linkC>0);
#if DEBUG & 256
{ where(); printf ("in ip_port_arrive()\n"); }
#endif
assert (pack->acc_length >= IP_MIN_HDR_SIZE);
exp_tim= get_time() + (ip_hdr->ih_ttl+1) * HZ;
if (ip_hdr->ih_dst == ip_port->ip_ipaddr)
ip_pack_stat= NWIO_EN_LOC;
else
ip_pack_stat= NWIO_EN_BROAD;
proto= ip_hdr->ih_proto;
#if DEBUG & 256
{ where(); printf("proto= %d\n", proto); }
#endif
share_fd= 0;
for (i=0, ip_fd=ip_fd_table; i<IP_FD_NR; i++, ip_fd++)
{
if (!(ip_fd->if_flags & IFF_INUSE))
{
continue;
}
#if DEBUG & 256
{ where(); printf("ip_fd_table[%d].if_flags= 0x%x\n",
ip_fd-ip_fd_table, ip_fd->if_flags); }
#endif
if (!(ip_fd->if_flags & IFF_OPTSET))
{
#if DEBUG & 256
{ where(); printf("%d options not set\n", i); }
#endif
continue;
}
if (ip_fd->if_port != ip_port)
{
#if DEBUG
{ where(); printf("%d wrong port\n", i); }
#endif
continue;
}
if (!(ip_fd->if_ipopt.nwio_flags & ip_pack_stat))
{
#if DEBUG & 256
{ where(); printf("%d wrong ip_pack_stat\n", i); }
#endif
continue;
}
if ((ip_fd->if_ipopt.nwio_flags & NWIO_PROTOSPEC) &&
proto != ip_fd->if_ipopt.nwio_proto)
{
#if DEBUG & 256
{ where(); printf("%d wrong proto\n", i); }
#endif
continue;
}
if ((ip_fd->if_ipopt.nwio_flags & NWIO_REMSPEC) &&
ip_hdr->ih_src != ip_fd->if_ipopt.nwio_rem)
{
#if DEBUG
{ where(); printf("%d wrong src addr (REMSPEC)\n", i); }
#endif
continue;
}
if (ip_fd->if_rd_buf)
{
if ((ip_fd->if_ipopt.nwio_flags &
NWIO_ACC_MASK) == NWIO_SHARED)
{
#if DEBUG
{ where(); printf("%d shared packet\n", i); }
#endif
share_fd= ip_fd;
continue;
}
#if DEBUG
{ where(); printf("throwing away packet\n"); }
#endif
bf_afree(ip_fd->if_rd_buf);
}
ip_fd->if_rd_buf= pack;
pack->acc_linkC++;
ip_fd->if_exp_tim= exp_tim;
if ((ip_fd->if_ipopt.nwio_flags & NWIO_ACC_MASK) ==
NWIO_SHARED || (ip_fd->if_ipopt.nwio_flags &
NWIO_ACC_MASK) == NWIO_EXCL)
{
#if DEBUG
{ where(); printf("exclusive packet\n"); }
#endif
bf_afree(pack);
pack= 0;
break;
}
if (ip_fd->if_flags & IFF_READ_IP)
{
#if DEBUG & 256
{ where(); printf("%d calling packet2user\n", i); }
#endif
ip_packet2user(ip_fd);
}
else
{
#if DEBUG
{ where(); printf("%d not READ_IP\n", i); }
#endif
}
}
if (share_fd && pack)
{
#if DEBUG
{ where(); printf("exclusive packet\n"); }
#endif
bf_afree(share_fd->if_rd_buf);
share_fd->if_rd_buf= pack;
share_fd->if_exp_tim= exp_tim;
}
else
{
#if DEBUG & 256
{ where(); printf("throwing away packet\n"); }
#endif
if (pack)
bf_afree(pack);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -