/* devuelve lo mismo que eth_send (bytes enviados) o -1 si ha habido error*/ int ipv4_send( ipv4_address_t dst, uint8_t type, unsigned char * payload, int payload_len ) { int bytes_sent = 0; int arp_flag = 0; mac_addr_t mac_addr; //mac destino arp_flag = arp_resolve (iface, dst , mac_addr_t ); //resolvemos ip if( arp_flag == -1 ) { //si error salimos printf("Cannot resolve ip addr into mac addr"); return arp_flag; //-1 } bytes_sent eth_send ( eth_iface_aux, dst, IPV4_OVER_ETH_TYPE, payload, payload_len ); return bytes_sent; }
void ethernet_send(char *data, unsigned int length, char *dst, char *type) { ethernet_header *header; char arpdst[6]; if ( type[0] == 0x08 && type[1] == 0x00 ) // IP { if ( dst == NULL ) { // If the IP stack didn't give us a destination, resolve it with ARP // If the destination isn't in the cache, arp_resolve will send a // request and queue the IP packet for sending later if ( arp_resolve(data, length, arpdst) ) dst = arpdst; else return; } } header = (ethernet_header*)data; memcpy(header->dest_addr, dst, 6); memcpy(header->src_addr, ethernet_opt_address, 6); header->ether_type[0] = type[0]; header->ether_type[1] = type[1]; //hexdump(data, length); if ( DEREF_INT(ADDR_ETH_BASE+ADDR_ETH_TSR) & 1<<4 ) { DEREF_INT(ADDR_ETH_BASE+ADDR_ETH_TAR) = (unsigned int) data; DEREF_INT(ADDR_ETH_BASE+ADDR_ETH_TCR) = length; while(DEREF_INT(ADDR_ETH_BASE+ADDR_ETH_TCR) > 0); } else printf("EMAC: Not ready to transmit next frame\n"); }
/*------------------------------------------------------------------------ * udp_send - send a UDP packet *------------------------------------------------------------------------ */ status udp_send ( uint32 remip, /* remote IP address or IP_BCAST*/ /* for a local broadcast */ uint16 remport, /* remote UDP protocol port */ uint32 locip, /* local IP address */ uint16 locport, /* local UDP protocol port */ char *buff, /* buffer of UDP data */ int32 len /* length of data in buffer */ ) { struct eth_packet pkt; /* ptr to packet being read */ struct ipv4_packet *ippkt = (struct ipv4_packet *)(pkt.net_ethdata); struct udp_packet *udppkt = (struct udp_packet *)(ippkt->net_ipdata); int32 pktlen; /* total packet length */ static uint16 ident = 1; /* datagram IDENT field */ char *udataptr; /* pointer to UDP data */ byte ethbcast[] = {0xff,0xff,0xff,0xff,0xff,0xff}; /* Compute packet length as UDP data size + fixed header size */ pktlen = ((char *)(udppkt->net_udpdata) - (char *)&pkt) + len; /* Create UDP packet in pkt */ memcpy(pkt.net_ethsrc, NetData.ethaddr, ETH_ADDR_LEN); pkt.net_ethtype = 0x0800; /* Type is IP */ ippkt->net_ipvh = 0x45; /* IP version and hdr length */ ippkt->net_iptos = 0x00; /* Type of service */ ippkt->net_iplen= pktlen - ETH_HDR_LEN;/* total IP datagram length */ ippkt->net_ipid = ident++; /* datagram gets next IDENT */ ippkt->net_ipfrag = 0x0000; /* IP flags & fragment offset */ ippkt->net_ipttl = 0xff; /* IP time-to-live */ ippkt->net_ipproto = IP_UDP; /* datagram carries UDP */ ippkt->net_ipcksum = 0x0000; /* initial checksum */ ippkt->net_ipsrc = locip; /* IP source address */ ippkt->net_ipdst = remip; /* IP destination address */ udppkt->net_udpsport = locport; /* local UDP protocol port */ udppkt->net_udpdport = remport; /* remote UDP protocol port */ udppkt->net_udplen = (uint16)(UDP_HDR_LEN+len); /* UDP length */ udppkt->net_udpcksum = 0x0000; /* ignore UDP checksum */ udataptr = (char *) udppkt->net_udpdata; for (; len>0; len--) { *udataptr++ = *buff++; } /* Set MAC address in packet, using ARP if needed */ //kprintf("Udp_send called with ip : %x\r\n", remip); if (remip == IP_BCAST) { /* set mac address to b-cast */ memcpy(pkt.net_ethdst, ethbcast, ETH_ADDR_LEN); /* If destination isn't on the same subnet, send to router */ } else if ((locip & NetData.addrmask) != (remip & NetData.addrmask)) { //kprintf("localip [%08x] NetData.addrmask [%08x] remote ip [%08x] 12 [%08x] 23 [%08x]\r\n", //locip, NetData.addrmask, remip, locip&NetData.addrmask, remip & NetData.addrmask); if (arp_resolve(NetData.routeraddr, pkt.net_ethdst)!=OK) { kprintf("udp_send: cannot resolve router %08x\n\r", NetData.routeraddr); return SYSERR; } } else { /* Destination is on local subnet - get MAC address */ //kprintf("UDP_Send trying to resolve address : %x\r\n", remip); if (arp_resolve(remip, pkt.net_ethdst) != OK) { kprintf("udp_send: cannot resolve %08x\n\r",remip); return SYSERR; } } /* Convert IP and UDP header fields from net to host byte order */ udp_hton(udppkt); ip_hton(ippkt); eth_hton(&pkt); //kprintf("Cleared conversion of header fields\r\n"); /* Compute IP header checksum */ ippkt->net_ipcksum = 0xffff & ipcksum(ippkt); //kprintf("Writing to ethernet device\r\n"); write(ETHER0, (char *)&pkt, pktlen); return OK; }
status rpl_send_with_ip(char * node_phy_addr, char *src_node, byte msg_type, char *msg, uint32 msg_len, uint32 remip){ struct eth_packet pkt; struct rpl_sim_packet *rpl_sim_pkt = NULL; byte ethbcast[] = {0xff,0xff,0xff,0xff,0xff,0xff}; #ifdef DEBUG kprintf("Simulator is : %04x dest : %04x source : %04x my addr : %04x\r\n", remip, *((uint32*)node_phy_addr), *((uint32*)src_node), NetData.ipaddr); #endif if ( ! NetData.ipvalid){ getlocalip(); } if(msg_len > 1500-ETH_HDR_LEN-RPL_SIM_HDR_LEN){ kprintf("WARN : Simulator : Message too big \r\n"); return SYSERR; } memcpy(pkt.net_ethsrc, NetData.ethaddr, ETH_ADDR_LEN); /* FIXME : Needs to be changed to something that is valid */ pkt.net_ethtype = 0x1000; if (remip == IP_BCAST) { /* set mac address to b-cast */ memcpy(pkt.net_ethdst, ethbcast, ETH_ADDR_LEN); /* If destination isn't on the same subnet, send to router */ } else if ((NetData.ipaddr & NetData.addrmask) != (remip & NetData.addrmask)) { if (arp_resolve(NetData.routeraddr, pkt.net_ethdst)!=OK) { kprintf("rpl_send: cannot resolve router %08x\n\r", NetData.routeraddr); return SYSERR; } } else { /* Destination is on local subnet - get MAC address */ if (arp_resolve(remip, pkt.net_ethdst) != OK) { kprintf("rpl_send: cannot resolve %08x\n\r",remip); return SYSERR; } } rpl_sim_pkt = (struct rpl_sim_packet *)pkt.net_ethdata; memcpy((char *)rpl_sim_pkt->dest_node, (char *)node_phy_addr, RPL_NODE_PHY_ADDR_LEN); /* * FIXME Change this to my_phsical_address which is 64 bits */ memcpy((char *)rpl_sim_pkt->src_node, (char *)(src_node), RPL_NODE_PHY_ADDR_LEN); rpl_sim_pkt->msg_type = msg_type; rpl_sim_pkt->msg_len = msg_len; memcpy(rpl_sim_pkt->data, msg, msg_len); /* * FIXME : Perform host to network order translations */ #ifdef DEBUG kprintf("The packet is destined for : %06x with length : %d\r\n", *(pkt.net_ethdst+4), msg_len); #endif eth_hton(&pkt); write(ETHER0, (char *)&pkt, ETH_HDR_LEN + RPL_SIM_HDR_LEN + msg_len); return OK; }