예제 #1
0
파일: tcp.c 프로젝트: ax-jones/umip
uint8_t tcp_handle_msg(IpHost *iph)
{
  TcpFrame *tcprf = tcp_get_header(&iph->mdev->recvFrame);
  TcpHeader *tcprh = &tcprf->tcpHead;

  if(tcprh->tcpFlags & TCP_SYN) {
    dout("new connection from %hhx %08x %i to %i.\n", tcprh->tcpFlags, HTONL(tcprf->ipHead.srcAddr), HTONS(tcprh->srcPort), HTONS(tcprh->destPort));
    TcpSession *tcps = tcp_create_session(iph, tcprf->ipHead.srcAddr, tcprh->srcPort, tcprh->destPort);

    if(!arp_has_addr(&iph->arph, tcprf->ipHead.srcAddr))
      arp_add_entry(&iph->arph, tcprf->ipHead.mac.srcAddr, tcprf->ipHead.srcAddr);
    tcps->remoteSeqNumber = HTONL(tcprh->seqNumber) + 1;

    TcpFrame *tcpsf = tcp_init_head(iph, tcps);
    TcpHeader *tcpsh = &tcpsf->tcpHead;
    tcpsh->tcpFlags = TCP_SYN | TCP_ACK;
    tcp_finish_frame(&iph->mdev->sendFrame, tcpsf, 0);

    return 1;
  }
  if(tcprh->tcpFlags & TCP_PSH) {
    TcpSession *tcps = tcp_get_session(iph, tcprf->ipHead.srcAddr, tcprf->tcpHead.srcPort, tcprf->tcpHead.destPort);

    TcpFrame *tcpsf = tcp_init_head(iph, tcps);
    TcpHeader *tcpsh = &tcpsf->tcpHead;
    uint8_t *dptr = tcp_get_payload(tcpsf);
    tcpsh->tcpFlags = TCP_PSH | TCP_ACK;

    uint16_t l = _strlen(htstr) + 1;
    _memcpy(dptr, htstr, l);
    tcp_finish_frame(&iph->mdev->sendFrame, tcpsf, l);

    return 1;
  }

  dout("tcp-wtf? %x %x %i %i\n", tcprh->tcpFlags, HTONL(tcprf->ipHead.srcAddr), HTONS(tcprh->srcPort), HTONS(tcprh->destPort));
#if 1
  uint8_t *prbuf = iph->mdev->recvFrame.packet;
  int len = iph->mdev->recvFrame.writePtr, i;
    for(i = 0; i < len; i++) {
      dout("%02hhx ", *(prbuf++));
    }
#endif
  return 0;
}
예제 #2
0
/*
 * Process the packet, received by adapter.
 * Process ARP requests. For IP packets, strip off the ethernet header.
 */
buf_t *
arp_input (netif_t *netif, buf_t *p)
{
	struct ethip_hdr *h;
	struct arp_hdr *ah;
	unsigned char *ipaddr;

	/*debug_printf ("arp_input: %d bytes\n", p->tot_len);*/
	h = (struct ethip_hdr*) p->payload;
	switch (h->eth.proto) {
	default:
		/* Unknown protocol. */
		/* debug_printf ("arp_input: unknown protocol 0x%x\n", h->eth.proto); */
		buf_free (p);
		return 0;

	case PROTO_IP:
		/*debug_printf ("arp: ip packet from %d.%d.%d.%d %02x-%02x-%02x-%02x-%02x-%02x\n",
			h->ip_src[0], h->ip_src[1], h->ip_src[2], h->ip_src[3],
			h->eth.src[0], h->eth.src[1], h->eth.src[2],
			h->eth.src[3], h->eth.src[4], h->eth.src[5]);*/

		/* For unicasts, update an ARP entry, independent of
		 * the source IP address. */
		if (h->eth.dest[0] != 255) {
			/* debug_printf ("arp: add entry %d.%d.%d.%d %02x-%02x-%02x-%02x-%02x-%02x\n",
				h->ip_src[0], h->ip_src[1], h->ip_src[2], h->ip_src[3],
				h->eth.src[0], h->eth.src[1], h->eth.src[2],
				h->eth.src[3], h->eth.src[4], h->eth.src[5]); */
			arp_add_entry (netif, h->ip_src, h->eth.src);
		}

		/* Strip off the Ethernet header. */
		buf_add_header (p, -14);
		return p;

	case PROTO_ARP:
		if (p->tot_len < sizeof (struct arp_hdr)) {
			/* debug_printf ("arp_input: too short packet\n"); */
			buf_free (p);
			return 0;
		}
		buf_truncate (p, sizeof (struct arp_hdr));
		p = buf_make_continuous (p);

		ah = (struct arp_hdr*) p->payload;
		switch (ah->opcode) {
		default:
			/* Unknown ARP operation code. */
			/* debug_printf ("arp_input: unknown opcode 0x%x\n", ah->opcode); */
			buf_free (p);
			return 0;

		case ARP_REQUEST:
#ifdef ARP_TRACE
			debug_printf ("arp: got request for %d.%d.%d.%d\n",
				ah->dst_ipaddr[0], ah->dst_ipaddr[1], ah->dst_ipaddr[2], ah->dst_ipaddr[3]);
			debug_printf ("     from %d.%d.%d.%d %02x-%02x-%02x-%02x-%02x-%02x\n",
				ah->src_ipaddr[0], ah->src_ipaddr[1], ah->src_ipaddr[2], ah->src_ipaddr[3],
				ah->src_hwaddr[0], ah->src_hwaddr[1], ah->src_hwaddr[2],
				ah->src_hwaddr[3], ah->src_hwaddr[4], ah->src_hwaddr[5]);
#endif
			/* ARP request. If it asked for our address,
			 * we send out a reply. */
			ipaddr = route_lookup_ipaddr (netif->arp->ip,
				ah->src_ipaddr, netif);
			if (! ipaddr || memcmp (ipaddr, ah->dst_ipaddr, 4) != 0) {
				buf_free (p);
				return 0;
			}

			ah->opcode = ARP_REPLY;

			memcpy (ah->dst_ipaddr, ah->src_ipaddr, 4);
			memcpy (ah->src_ipaddr, ipaddr, 4);

			memcpy (ah->dst_hwaddr, ah->src_hwaddr, 6);
			memcpy (ah->src_hwaddr, netif->ethaddr, 6);
			memcpy (ah->eth.dest, ah->dst_hwaddr, 6);
			memcpy (ah->eth.src, netif->ethaddr, 6);

			ah->eth.proto = PROTO_ARP;
#ifdef ARP_TRACE
			debug_printf ("arp: send reply %d.%d.%d.%d %02x-%02x-%02x-%02x-%02x-%02x\n",
				ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3],
				netif->ethaddr[0], netif->ethaddr[1], netif->ethaddr[2],
				netif->ethaddr[3], netif->ethaddr[4], netif->ethaddr[5]);
			debug_printf ("     to %d.%d.%d.%d %02x-%02x-%02x-%02x-%02x-%02x\n",
				ah->dst_ipaddr[0], ah->dst_ipaddr[1], ah->dst_ipaddr[2], ah->dst_ipaddr[3],
				ah->dst_hwaddr[0], ah->dst_hwaddr[1], ah->dst_hwaddr[2],
				ah->dst_hwaddr[3], ah->dst_hwaddr[4], ah->dst_hwaddr[5]);
#endif
			netif->interface->output (netif, p, 0);
			return 0;

		case ARP_REPLY:
			/* ARP reply. We insert or update the ARP table.
			 * No need to check the destination IP address. */
			/* debug_printf ("arp: got reply from %d.%d.%d.%d %02x-%02x-%02x-%02x-%02x-%02x\n",
				ah->src_ipaddr[0], ah->src_ipaddr[1], ah->src_ipaddr[2], ah->src_ipaddr[3],
				ah->src_hwaddr[0], ah->src_hwaddr[1], ah->src_hwaddr[2],
				ah->src_hwaddr[3], ah->src_hwaddr[4], ah->src_hwaddr[5]); */
			arp_add_entry (netif, ah->src_ipaddr, ah->src_hwaddr);
			buf_free (p);
			return 0;
		}
	}
}