/* * igmp_report - send a IGMP Report packet * * int igmp_report (DWORD ip) * Where: * ip is the IP address to report. * * Returns: * 0 if unable to send report * 1 report was sent successfully */ int igmp_report (DWORD ip) { struct IGMP_PKT *pkt; IGMP_packet *igmp; eth_address ethaddr; /* get the ethernet addr of the destination */ multi_to_eth ((DWORD)ALL_SYSTEMS, (BYTE*)ðaddr); /* format the packet with the request's hardware address */ pkt = (struct IGMP_PKT*) _eth_formatpacket (ethaddr, IP_TYPE); igmp = &pkt->igmp; ip = intel (ip); /* fill in the igmp packet */ igmp->type = IGMP_REPORT; igmp->version = IGMP_VERSION; igmp->mbz = 0; igmp->address = ip; igmp->checksum = 0; igmp->checksum = ~checksum (igmp,sizeof(*igmp)); return IP_OUTPUT (&pkt->in, 0, ip, IGMP_PROTO, 0, 0, 0, (int)sizeof(*igmp), NULL); }
/* * icmp_send - format and send a ICMP packet * - note that src and dest are network order. */ static int icmp_send (struct _pkt *pkt, DWORD src, DWORD dest, int length) { in_Header *ip = &pkt->in; ICMP_PKT *icmp = &pkt->icmp; icmp->unused.checksum = 0; icmp->unused.checksum = ~checksum (icmp, length); return IP_OUTPUT (ip, src, dest, ICMP_PROTO, 0, 0, 0, length, NULL); }
void tcp_respond (T_NET_BUF *output, T_TCP_CEP *cep, T_TCP_SEQ ack, T_TCP_SEQ seq, uint_t rbfree, uint8_t flags) { T_IP_HDR *iph; T_TCP_HDR *tcph; uint_t win = 0; if ((flags & TCP_FLG_RST) == 0) win = rbfree; /* * output が NULL でなければ、これは入力したセグメントの * net_buf で、そのまま再利用する。 */ if (output != NULL) { T_IN_ADDR ipaddr; uint16_t portno; /* * IPv4 では、IP ヘッダのオプションを削除する。 * IPv6 では、拡張ヘッダを削除する。 */ if (IP_REMOVE_OPTIONS(output) != E_OK) { syscall(rel_net_buf(output)); return; } iph = GET_IP_HDR(output); /* IP アドレスを交換する。*/ ipaddr = iph->src; iph->src = iph->dst; iph->dst = ipaddr; #if defined(SUPPORT_INET6) /* トラヒッククラスとフローラベルをクリアする。*/ iph->vcf = htonl(IP6_MAKE_VCF(IP6_VCF_V(ntohl(iph->vcf)), 0)); #endif /* of #if defined(SUPPORT_INET6) */ /* TCP SDU 長を 0 にする。*/ SET_IP_SDU_SIZE(iph, TCP_HDR_SIZE); tcph = GET_TCP_HDR(output, IF_IP_TCP_HDR_OFFSET); /* ポート番号を交換する。*/ portno = tcph->sport; tcph->sport = tcph->dport; tcph->dport = portno; /* TCP ヘッダに情報を設定する。*/ tcph->doff = TCP_MAKE_DATA_OFF(TCP_HDR_SIZE); } /* cep が NULL であれば、何もしないで終了する。*/ else if (cep == NULL) return; else { if (tcp_get_segment(&output, cep, 0, 0, (uint_t)(net_buf_max_siz() - IF_IP_TCP_HDR_SIZE), NBA_SEARCH_ASCENT, TMO_TCP_GET_NET_BUF) != E_OK) return; tcph = GET_TCP_HDR(output, IF_IP_TCP_HDR_OFFSET); flags |= TCP_FLG_ACK; } tcph->seq = htonl(seq); tcph->ack = htonl(ack); tcph->win = htons(win); tcph->flags = flags; tcph->urp = tcph->sum = 0; /* * チェックサムを設定する。 */ tcph->sum = IN_CKSUM(output, IPPROTO_TCP, IF_IP_TCP_HDR_OFFSET, (uint_t)GET_TCP_HDR_SIZE2(output, IF_IP_TCP_HDR_OFFSET)); /* ネットワークバッファ長を調整する。*/ output->len = (uint16_t)GET_IF_IP_TCP_HDR_SIZE2(output, IF_IP_TCP_HDR_OFFSET); #ifdef TCP_CFG_TRACE tcp_output_trace(output, cep); #endif /* of #ifdef TCP_CFG_TRACE */ /* ネットワーク層 (IP) の出力関数を呼び出す。*/ IP_OUTPUT(output, TMO_TCP_OUTPUT); }