Beispiel #1
0
/*
 * 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*)&ethaddr);

    /* 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);
}
Beispiel #2
0
/*
 * 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);
}
Beispiel #3
0
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);
	}