struct packet *dns4(pcs *pc, int sw, char *data, int dlen) { u_int gip; struct in_addr in; sesscb cb; u_char mac[ETH_ALEN]; struct packet *m; if (pc->ip4.dns[sw] == 0) return 0; if (sameNet(cb.dip, pc->ip4.ip, pc->ip4.cidr)) gip = cb.dip; else { if (pc->ip4.gw == 0) return NULL; gip = pc->ip4.gw; } if (!arpResolve(pc, gip, mac)) { in.s_addr = gip; return NULL; } /* save old control block */ memcpy(&cb, &pc->mscb, sizeof(sesscb)); pc->mscb.data = data; pc->mscb.dsize = dlen; pc->mscb.proto = IPPROTO_UDP; pc->mscb.mtu = pc->mtu; pc->mscb.ipid = time(0) & 0xffff; pc->mscb.ttl = TTL; pc->mscb.sip = pc->ip4.ip; pc->mscb.dip = pc->ip4.dns[sw]; pc->mscb.sport = (random() % (65000 - 1024)) + 1024; pc->mscb.dport = 53; memcpy(pc->mscb.smac, pc->ip4.mac, ETH_ALEN); memcpy(pc->mscb.dmac, mac, ETH_ALEN); m = packet(pc); /* restore control block */ memcpy(&pc->mscb, &cb, sizeof(sesscb)); return m; }
/** * Shell command arp that can be used to display the current table, to * request a new mapping, or to eliminate an existing mapping. */ command arp(int type, uchar *ip) { int i, j, size, oldest, ret = OK; wait(arpSem); size = arpTab.size; if (type == ARP_DISPLAY) { //Display current arp table printf("IP ADDRESS\tMAC ADDRESS\n"); for (i = 0; i < arpTab.size; i++) { printf("%u.%u.%u.%u\t%02x:%02x:%02x:%02x:%02x:%02x\n", arpTab.arr[i].arpIp[0], arpTab.arr[i].arpIp[1], arpTab.arr[i].arpIp[2], arpTab.arr[i].arpIp[3], arpTab.arr[i].arpMac[0], arpTab.arr[i].arpMac[1], arpTab.arr[i].arpMac[2], arpTab.arr[i].arpMac[3], arpTab.arr[i].arpMac[4], arpTab.arr[i].arpMac[5]); } }else if (type == ARP_ADD) { //Request new arp mapping // Check to see if the ip address is already mapped kprintf("adding\r\n"); for (i = 0; i < arpTab.size; i++) { if (memcmp(arpTab.arr[i].arpIp, ip, sizeof(ip)) == 0) { printf("Resulting MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n", arpTab.arr[i].arpMac[0], arpTab.arr[i].arpMac[1], arpTab.arr[i].arpMac[2], arpTab.arr[i].arpMac[3], arpTab.arr[i].arpMac[4], arpTab.arr[i].arpMac[5]); signal(arpSem); return OK; } } oldest = 0; if (arpTab.size >= MAX_ARP_TABLE) // Full ARP table, replace oldest { for (i = 1; i < arpTab.size; i++) { if (arpTab.arr[i].timeStamp < arpTab.arr[oldest].timeStamp) oldest = i; } size = oldest; } // Attempt to ARP for it arpTab.arr[size].arpMac = malloc(sizeof(uchar)*6); arpTab.arr[size].arpIp = malloc(sizeof(uchar)*4); if (SYSERR == arpResolve(ip, arpTab.arr[size].arpMac)) { printf("ERROR: Could not resolve the IP address\n"); free(arpTab.arr[size].arpMac); free(arpTab.arr[size].arpIp); ret = SYSERR; } else{ printf("Resulting MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n", arpTab.arr[size].arpMac[0], arpTab.arr[size].arpMac[1], arpTab.arr[size].arpMac[2], arpTab.arr[size].arpMac[3], arpTab.arr[size].arpMac[4], arpTab.arr[size].arpMac[5]); arpTab.arr[size].arpIp = ip; arpTab.arr[size].timeStamp = clocktime; if (arpTab.size < MAX_ARP_TABLE) arpTab.size++; } }else if (type == ARP_DELETE) { //Eliminate an existing mapping for (i = 0; i < arpTab.size; i++) { if (memcmp(arpTab.arr[i].arpIp, ip, sizeof(ip)) == 0) { for (j = i; j < arpTab.size-1; j++) arpTab.arr[j] = arpTab.arr[j+1]; free(arpTab.arr[size].arpMac); free(arpTab.arr[size].arpIp); arpTab.size--; break; } } }else { //Incorrect input printf("ERROR: Invalid input\n"); ret = SYSERR; } signal(arpSem); return ret; // COMEBACK }
void UWMllModule::sendDown(Packet *p) { hdr_cmn *ch = HDR_CMN(p); hdr_uwip *ih = HDR_UWIP(p); nsaddr_t dst = ih->daddr(); hdr_ll *llh = HDR_LL(p); hdr_mac *mh = HDR_MAC(p); llh->seqno_ = ++seqno_; llh->lltype() = LL_DATA; mh->macSA() = getDownAddr(); mh->hdr_type() = ETHERTYPE_IP; int tx = 0; switch (ch->addr_type()) { case NS_AF_ILINK: /* Uhh!? nsaddr_t to int!? */ mh->macDA() = ch->next_hop(); // cout << "ILINK mode " << endl; break; case NS_AF_INET: if (ch->next_hop() == UWIP_BROADCAST) dst = ch->next_hop(); else if (ch->next_hop() <= 0) dst = ih->daddr(); else dst = ch->next_hop(); // cout << "INET mode " << endl; case NS_AF_NONE: if (UWIP_BROADCAST == (u_int32_t) dst) { mh->macDA() = MAC_BROADCAST; break; } /* Resolv ARP */ tx = arpResolve(dst, p); break; default: mh->macDA() = MAC_BROADCAST; break; } if (tx == 0) { Module::sendDown(p); } else { if (enable_addr_copy == 0) { std::cerr << NOW << "Node(" << mh->macSA() << ")::UwMLL_Module -> WARNING: Entry not found for IP " "address " << dst << " Packet dropped" << endl; drop(p, 1, UWMLL_DROP_REASON_NOT_IN_ARP_LIST); } else { mh->macDA() = dst; Module::sendDown(p); } } }
error_t ipv4SendPacket(NetInterface *interface, Ipv4PseudoHeader *pseudoHeader, uint16_t fragId, uint16_t fragOffset, ChunkedBuffer *buffer, size_t offset, uint8_t timeToLive) { error_t error; size_t length; Ipv4Addr destIpAddr = 0; MacAddr destMacAddr; Ipv4Header *packet; //Is there enough space for the IPv4 header? if(offset < sizeof(Ipv4Header)) return ERROR_INVALID_PARAMETER; //Make room for the header offset -= sizeof(Ipv4Header); //Calculate the size of the entire packet, including header and data length = chunkedBufferGetLength(buffer) - offset; //Point to the IPv4 header packet = chunkedBufferAt(buffer, offset); //Format IPv4 header packet->version = IPV4_VERSION; packet->headerLength = 5; packet->typeOfService = 0; packet->totalLength = htons(length); packet->identification = htons(fragId); packet->fragmentOffset = htons(fragOffset); packet->timeToLive = timeToLive; packet->protocol = pseudoHeader->protocol; packet->headerChecksum = 0; packet->srcAddr = pseudoHeader->srcAddr; packet->destAddr = pseudoHeader->destAddr; //Calculate IP header checksum packet->headerChecksum = ipCalcChecksumEx(buffer, offset, packet->headerLength * 4); //Ensure the source address is valid error = ipv4CheckSourceAddr(interface, pseudoHeader->srcAddr); //Invalid source address? if(error) return error; //Destination address is the unspecified address? if(pseudoHeader->destAddr == IPV4_UNSPECIFIED_ADDR) { //Destination address is not acceptable error = ERROR_INVALID_ADDRESS; } //Destination address is the loopback address? else if(pseudoHeader->destAddr == IPV4_LOOPBACK_ADDR) { //Not yet implemented... error = ERROR_NOT_IMPLEMENTED; } //Destination address is a broadcast address? else if(ipv4IsBroadcastAddr(interface, pseudoHeader->destAddr)) { //Destination IPv4 address destIpAddr = pseudoHeader->destAddr; //Make use of the broadcast MAC address destMacAddr = MAC_BROADCAST_ADDR; //No error to report error = NO_ERROR; } //Destination address is a multicast address? else if(ipv4IsMulticastAddr(pseudoHeader->destAddr)) { //Destination IPv4 address destIpAddr = pseudoHeader->destAddr; //Map IPv4 multicast address to MAC-layer multicast address error = ipv4MapMulticastAddrToMac(pseudoHeader->destAddr, &destMacAddr); } //Destination host is in the local subnet? else if(ipv4IsInLocalSubnet(interface, pseudoHeader->destAddr)) { //Destination IPv4 address destIpAddr = pseudoHeader->destAddr; //Resolve host address before sending the packet error = arpResolve(interface, pseudoHeader->destAddr, &destMacAddr); } //Destination host is outside the local subnet? else { //Make sure the default gateway is properly set if(interface->ipv4Config.defaultGateway != IPV4_UNSPECIFIED_ADDR) { //Use the default gateway to forward the packet destIpAddr = interface->ipv4Config.defaultGateway; //Perform address resolution error = arpResolve(interface, interface->ipv4Config.defaultGateway, &destMacAddr); } else { //There is no route to the outside world... error = ERROR_NO_ROUTE; } } //Successful address resolution? if(!error) { //Debug message TRACE_INFO("Sending IPv4 packet (%u bytes)...\r\n", length); //Dump IP header contents for debugging purpose ipv4DumpHeader(packet); //Send Ethernet frame error = ethSendFrame(interface, &destMacAddr, buffer, offset, ETH_TYPE_IPV4); } //Address resolution is in progress? else if(error == ERROR_IN_PROGRESS) { //Debug message TRACE_INFO("Enqueuing IPv4 packet (%u bytes)...\r\n", length); //Dump IP header contents for debugging purpose ipv4DumpHeader(packet); //Enqueue packets waiting for address resolution error = arpEnqueuePacket(interface, destIpAddr, buffer, offset); } //Address resolution failed? else { //Debug message TRACE_WARNING("Cannot map IPv4 address to Ethernet address!\r\n"); } //Return status code return error; }