void net_handle(u8 *buf, u32 len) { ETH_HDR *p = (ETH_HDR *)buf; switch (HON(p->type)) { case PROTO_ARP: arp_process(buf,len); break; case PROTO_IP: ip_process(buf,len); break; default: break; } }
void serial_to_wpcap(FILE *inslip) { uint16_t buf_aligned[BUF_SIZE/2 + 42]; //extra for possible eth_hdr and ip_process expansion uint8_t *buf = (uint8_t *)buf_aligned; static int inbufptr = 0, issensiblestring=1; int ret; unsigned char c; unsigned char * inpktbuf; if(tun){ inpktbuf = buf + sizeof(struct uip_eth_hdr); } else { inpktbuf = buf; } read_more: if(inbufptr >= BUF_SIZE) { inbufptr = 0; } ret = fread(&c, 1, 1, inslip); if(ret == -1) { err(1, "serial_to_tun: read"); } if(ret == 0) { clearerr(inslip); return; if (timestamp) stamptime(); fprintf(stderr, "serial_to_tun: EOF\n"); exit(1); } /* fprintf(stderr, ".");*/ switch(c) { case SLIP_END: if(inbufptr > 0) { if(inpktbuf[0] == '!') { if (inpktbuf[1] == 'M' && inbufptr == 18) { /* Read gateway MAC address and autoconfigure tap0 interface */ char macs64[24], macs48[18]; int addr_bytes[8]; int i, pos; for(i = 0, pos = 0; i < 16; i++) { macs64[pos++] = inpktbuf[2 + i]; if ((i & 1) == 1 && i < 14) { macs64[pos++] = '-'; } } macs64[pos] = '\0'; if (timestamp) stamptime(); fprintf(stderr, "*** Gateway's MAC address: %s\n", macs64); mac_received = true; sscanf(macs64, "%2X-%2X-%2X-%2X-%2X-%2X-%2X-%2X", &addr_bytes[0], &addr_bytes[1], &addr_bytes[2], &addr_bytes[3], &addr_bytes[4], &addr_bytes[5], &addr_bytes[6], &addr_bytes[7]); /* Form a fictitious MAC address for the attached device from its EUI-64 (2 middle bytes elided) */ addr_bytes[0] |= 0x02; for(i=0;i<3;i++){ dev_eth_addr.addr[i] = addr_bytes[i]; } for(i=3;i<6;i++){ dev_eth_addr.addr[i] = addr_bytes[i+2]; } sprintf(macs48,"%02X-%02X-%02X-%02X-%02X-%02X", dev_eth_addr.addr[0], dev_eth_addr.addr[1], dev_eth_addr.addr[2], dev_eth_addr.addr[3], dev_eth_addr.addr[4], dev_eth_addr.addr[5]); if (timestamp) stamptime(); fprintf(stderr,"Fictitious MAC-48: %s\n", macs48); if(autoconf){ if(IPAddrFromPrefix(autoconf_addr, ipprefix, macs64)!=0){ if (timestamp) stamptime(); fprintf(stderr, "Invalid IPv6 address.\n"); exit(1); } local_ipaddr = autoconf_addr; addAddress(if_name,local_ipaddr); } if(br_prefix != NULL){ /* RPL Border Router mode. Add route towards LoWPAN. */ if(IPAddrFromPrefix(rem_ipaddr, br_prefix, macs64)!=0){ if (timestamp) stamptime(); fprintf(stderr, "Invalid IPv6 address.\n"); exit(1); } addLoWPANRoute(if_name, br_prefix, rem_ipaddr); addNeighbor(if_name, rem_ipaddr, macs48); } } #define DEBUG_LINE_MARKER '\r' } else if(inpktbuf[0] == '?') { if (inpktbuf[1] == 'M') { /* Send our MAC address. */ send_mac = true; set_sniffer_mode = true; set_channel = true; } else if (inpktbuf[1] == 'P') { /* Send LoWPAN network prefix to the border router. */ send_prefix = true; } } else if(inpktbuf[0] == DEBUG_LINE_MARKER) { /* Dont insert timestamp on wireshark packet dumps starting with 0000 */ if (timestamp) { if (inpktbuf[0]!='0' || inpktbuf[1]!=0 || inpktbuf[2]!=0 || inpktbuf[3]!=0) stamptime(); } fwrite(inpktbuf + 1, inbufptr - 1, 1, stderr); issensiblestring=1; } #if 0 else if(is_sensible_string(inpktbuf, inbufptr)) { /* Dont insert timestamp on wireshark packet dumps starting with 0000 */ if (timestamp) { if (inpktbuf[0]!='0' || inpktbuf[1]!=0 || inpktbuf[2]!=0 || inpktbuf[3]!=0) stamptime(); } fwrite(inpktbuf, inbufptr, 1, stderr); } #else else if(issensiblestring) { /* Dont insert timestamp on wireshark packet dumps starting with 0000 */ if (timestamp) { if (inpktbuf[0]!='0' || inpktbuf[1]!=0 || inpktbuf[2]!=0 || inpktbuf[3]!=0) stamptime(); } fwrite(inpktbuf, inbufptr, 1, stderr); } #endif else { PRINTF("Sending to wpcap\n"); if(tun){ //Ethernet header to be inserted before IP packet struct uip_eth_hdr * eth_hdr = (struct uip_eth_hdr *)buf; memcpy(ð_hdr->dest, &adapter_eth_addr, sizeof(struct uip_eth_addr)); memcpy(ð_hdr->src, &dev_eth_addr, sizeof(struct uip_eth_addr)); eth_hdr->type = htons(UIP_ETHTYPE_IPV6); inbufptr += sizeof(struct uip_eth_hdr); // Process incoming packets to transform link layer addresses inside ICMP packets. // Try to do processing if we did not succeed to add the neighbor. if(clean_neighb == false){ inbufptr = ip_process(buf, inbufptr); } } //print_packet(inpktbuf, inbufptr); wpcap_send(buf, inbufptr); /* printf("After sending to wpcap\n");*/ } inbufptr = 0; issensiblestring=1; } break; case SLIP_ESC: if(fread(&c, 1, 1, inslip) != 1) { clearerr(inslip); /* Put ESC back and give up! */ ungetc(SLIP_ESC, inslip); return; } switch(c) { case SLIP_ESC_END: c = SLIP_END; break; case SLIP_ESC_ESC: c = SLIP_ESC; break; } /* FALLTHROUGH */ default: inpktbuf[inbufptr++] = c; if (issensiblestring) { if(c == '\n') { /* Dont insert timestamp on wireshark packet dumps starting with 0000 */ if (timestamp) { if (inpktbuf[0]!='0' || inpktbuf[1]!=0 || inpktbuf[2]!=0 || inpktbuf[3]!=0) stamptime(); } /* This could be a proper debug string starting with CR just a print to stdout */ /* Trap the CR which would cause overwriting of the timestamp */ //{int i;for (i=0;i<inbufptr;i++) fprintf(stderr,"%2x ",inpktbuf[i]);} if(inpktbuf[0] == DEBUG_LINE_MARKER) { fwrite(inpktbuf + 1, inbufptr - 1, 1, stderr); } else { fwrite(inpktbuf, inbufptr, 1, stderr); } inbufptr=0; } else if (c == 0 || c == '\t' || c == '\r') { } else if(c < ' ' || '~' < c) { issensiblestring=0; } } break; } goto read_more; }
/*! \brief: process an incoming ip packet Send a TCP ack for recd data and if there is app data, send it \arg: 1 [INOUT] pkt \arg: 2 [IN] rx len \note this function also gets the yh_socket and tx data len is len of data in sock \todo: should this live in eth */ RESULT process_ip_pkt( BYTE** pktp, SHORT len ) { RESULT _res_ = ERR_STATE; ip_header_p ip_hdr = NULL; /* todo: add hash alg to make sure we get the same sock */ yh_socket* sock = tcp_get_sock( NULL ); if( sock == NULL ) { printf( "Failed to get socket \r\n" ); _res_ = TCP_CONN_FAILED_TO_SET_SOCKET; goto done; } sock->pktp = pktp; sock->rxlen = len; sock->txlen = 0; sock_set_offsets( sock, len ); _res_ = ip_process( sock->iph, sock->ipl ); printf( "Processing IP result [%X]\r\n", _res_ ); if( _res_ != OK ) { if( _res_ == IP_HEADER_AND_ACTUAL_LEN_MISMATCH ) { /* Ignore for now since there might be an eth trailer */ _res_ = OK; } else { goto done; } } printf( "Processing tcp \r\n" ); /* process tcp <-> tcp */ _res_ = tcp_process( sock ); /* something went wrong or if it was only an ack */ if( _res_ != OK ) { /* * And god gave us re-transmissions */ _res_ = tcp_err_cleanup( sock, _res_ ); goto done; } if( sock->txlen <= 0 ) { goto done; } /* We have data to send i.e. sock->txlen > 0. Well, first send an ack */ _res_ = send_packet( sock, ETH_TYPE_TCPIP ); if( _res_ != OK ) { goto done; } if( sock->pkt_len <= MIN_PKT_LEN ) { goto done; } /* Process the app here */ _res_ = tcp_app_process( sock ); if( _res_ != OK ) { /* debug */ printf("Application error [%X]", _res_ ); /* end debug */ tcp_app_cleanup(sock); goto done; } if( sock->txlen > 0 ) { _res_ = send_packet( sock, ETH_TYPE_APP_DATA ); } done: //yh_free( *sock->pktp, sock->pkt_len ); tx_reset( sock ); return _res_; }
/* ARGSUSED */ void ip_fanout_sctp(mblk_t *mp, ill_t *recv_ill, ipha_t *ipha, uint32_t ports, uint_t flags, boolean_t mctl_present, boolean_t ip_policy, uint_t ipif_seqid, zoneid_t zoneid) { sctp_t *sctp; boolean_t isv4; conn_t *connp; mblk_t *first_mp; ip6_t *ip6h; in6_addr_t map_src, map_dst; in6_addr_t *src, *dst; first_mp = mp; if (mctl_present) { mp = first_mp->b_cont; ASSERT(mp != NULL); } /* Assume IP provides aligned packets - otherwise toss */ if (!OK_32PTR(mp->b_rptr)) { BUMP_MIB(&ip_mib, ipInDiscards); freemsg(first_mp); return; } if (IPH_HDR_VERSION(ipha) == IPV6_VERSION) { ip6h = (ip6_t *)ipha; src = &ip6h->ip6_src; dst = &ip6h->ip6_dst; isv4 = B_FALSE; } else { ip6h = NULL; IN6_IPADDR_TO_V4MAPPED(ipha->ipha_src, &map_src); IN6_IPADDR_TO_V4MAPPED(ipha->ipha_dst, &map_dst); src = &map_src; dst = &map_dst; isv4 = B_TRUE; } if ((connp = sctp_fanout(src, dst, ports, ipif_seqid, zoneid, mp)) == NULL) { ip_fanout_sctp_raw(first_mp, recv_ill, ipha, isv4, ports, mctl_present, flags, ip_policy, ipif_seqid, zoneid); return; } sctp = CONN2SCTP(connp); /* Found a client; up it goes */ BUMP_MIB(&ip_mib, ipInDelivers); /* * We check some fields in conn_t without holding a lock. * This should be fine. */ if (CONN_INBOUND_POLICY_PRESENT(connp) || mctl_present) { first_mp = ipsec_check_inbound_policy(first_mp, connp, ipha, NULL, mctl_present); if (first_mp == NULL) { SCTP_REFRELE(sctp); return; } } /* Initiate IPPF processing for fastpath */ if (IPP_ENABLED(IPP_LOCAL_IN)) { ip_process(IPP_LOCAL_IN, &mp, recv_ill->ill_phyint->phyint_ifindex); if (mp == NULL) { SCTP_REFRELE(sctp); if (mctl_present) freeb(first_mp); return; } else if (mctl_present) { /* * ip_process might return a new mp. */ ASSERT(first_mp != mp); first_mp->b_cont = mp; } else { first_mp = mp; } } if (connp->conn_recvif || connp->conn_recvslla || connp->conn_ipv6_recvpktinfo) { int in_flags = 0; if (connp->conn_recvif || connp->conn_ipv6_recvpktinfo) { in_flags = IPF_RECVIF; } if (connp->conn_recvslla) { in_flags |= IPF_RECVSLLA; } if (isv4) { mp = ip_add_info(mp, recv_ill, in_flags); } else { mp = ip_add_info_v6(mp, recv_ill, &ip6h->ip6_dst); } if (mp == NULL) { SCTP_REFRELE(sctp); if (mctl_present) freeb(first_mp); return; } else if (mctl_present) { /* * ip_add_info might return a new mp. */ ASSERT(first_mp != mp); first_mp->b_cont = mp; } else { first_mp = mp; } } mutex_enter(&sctp->sctp_lock); if (sctp->sctp_running) { if (mctl_present) mp->b_prev = first_mp; if (!sctp_add_recvq(sctp, mp, B_FALSE)) { BUMP_MIB(&ip_mib, ipInDiscards); freemsg(first_mp); } mutex_exit(&sctp->sctp_lock); } else { sctp->sctp_running = B_TRUE; mutex_exit(&sctp->sctp_lock); mutex_enter(&sctp->sctp_recvq_lock); if (sctp->sctp_recvq != NULL) { if (mctl_present) mp->b_prev = first_mp; if (!sctp_add_recvq(sctp, mp, B_TRUE)) { BUMP_MIB(&ip_mib, ipInDiscards); freemsg(first_mp); } mutex_exit(&sctp->sctp_recvq_lock); WAKE_SCTP(sctp); } else { mutex_exit(&sctp->sctp_recvq_lock); sctp_input_data(sctp, mp, (mctl_present ? first_mp : NULL)); WAKE_SCTP(sctp); sctp_process_sendq(sctp); } } SCTP_REFRELE(sctp); }