📄 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"); }#endifassert (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 + -