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; }
/* * 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; } } }