void send_arp_request(struct sr_instance* sr, uint32_t tip /* Net byte order */, const char* interface) { assert(sr); assert(interface); iface_entry *inter = get_interface(sr, interface); uint8_t *request_packet = 0; eth_hdr *eth_request = 0; arp_hdr *arp_request = 0; uint32_t len = 0; uint8_t default_addr[ETH_ADDR_LEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; /* construct the ARP request */ len = sizeof(eth_hdr) + sizeof(arp_hdr); request_packet = calloc(len, sizeof(uint8_t)); eth_request = (eth_hdr *)request_packet; arp_request = (arp_hdr *)(request_packet + sizeof(eth_hdr)); populate_eth_hdr(eth_request, default_addr, inter->addr, ETH_TYPE_ARP); populate_arp_hdr(arp_request, NULL, tip, inter->addr, inter->ip, ARP_OP_REQUEST); /* send the ARP reply */ if (send_packet(sr, request_packet, len, interface) != 0) { printf("Failure sending arp request\n"); } /* recover allocated memory */ free(request_packet); }
/* * Send an arp reply out of the given interface, as a reply to the given packet */ void send_arp_reply(struct sr_instance *sr, const uint8_t *packet, unsigned int len, iface_entry* iface) { eth_hdr* eth = (eth_hdr*)packet; arp_hdr* arp_req = get_arp_hdr(packet, len); uint8_t* new_packet = (uint8_t*)malloc(sizeof(eth_hdr) + sizeof(arp_hdr)); /* Setup the ETHERNET header */ eth_hdr* new_eth = (eth_hdr*)new_packet; populate_eth_hdr(new_eth, eth->eth_shost, iface->addr, ETH_TYPE_ARP); /* Setup the ARP header */ arp_hdr* new_arp = get_arp_hdr(new_packet, sizeof(eth_hdr) + sizeof(arp_hdr)); populate_arp_hdr(new_arp, arp_req->arp_sha, arp_req->arp_sip.s_addr, iface->addr, iface->ip, ARP_OP_REPLY); /* Send the reply */ if (send_packet(sr, new_packet, sizeof(eth_hdr) + sizeof(arp_hdr), iface->name) != 0) { printf("Error sending ARP reply\n"); } free(new_packet); }
int main (void) { int raw_socket = -1; int udp_socket = -1; struct sockaddr_in udp_sockaddr; struct sockaddr_ll sockaddr; uint8_t *packet = 0; uint8_t *packet_ptr; int packet_len; uint8_t *payload = 0; eth_hdr_t eth_hdr; int n_bytes_sent = 0; int ret; int j; uint8_t packet_buffer[ETH_FRAME_LEN]; int addrlen = -1; int bytes_received = 0; //Set up the netlink socket int chan = 3; nl_set_channel(chan,5); // Open the raw socket ret = open_socket(if_name, &raw_socket, &sockaddr); if (ret < 0){ printf("Error opening socket: %i\n", raw_socket); return -1; } // Open the udp socket udp_socket = socket(AF_INET, SOCK_DGRAM, 0); if (udp_socket < 0){ printf("Error opening udp socket: %i\n", udp_socket); return -1; } //fcntl(udp_socket, F_SETFL, O_NONBLOCK); // set to non-blocking // Bind the socket to port 5580 memset((char *)&udp_sockaddr, 0, sizeof(udp_sockaddr)); udp_sockaddr.sin_family = AF_INET; udp_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY); udp_sockaddr.sin_port = htons(5550); ret = bind(udp_socket, (struct sockaddr *)&udp_sockaddr, sizeof(struct sockaddr_in)); if (ret < 0) { printf("Unable to bind to udp socket: %s\n", strerror(errno)); return -1; } // Create the packet //packet_len = PAYLOAD_LEN + sizeof(eth_hdr_t); packet_len = ETH_FRAME_LEN; packet = malloc(packet_len); if ( packet == 0 ) { printf("Unable to allocate packet memory\n"); } packet_ptr = packet; // Add the ethernet header populate_eth_hdr(ð_hdr, sockaddr.sll_addr, ETH_TYPE_3DR); memcpy(packet_ptr, ð_hdr, sizeof(eth_hdr_t)); packet_ptr += sizeof(eth_hdr_t); // Populate the payload payload = malloc(PAYLOAD_LEN); if (payload == 0) { printf("Unable to allocate payload\n"); return -1; } memset(payload, 0, PAYLOAD_LEN); memcpy(packet_ptr, payload, PAYLOAD_LEN); while (1) { //Clear the packet buffer memset(packet_buffer, 0, ETH_FRAME_LEN); //Read from the incoming port. addrlen=sizeof(udp_sockaddr); bytes_received = recvfrom(udp_socket, packet_buffer, sizeof(packet_buffer), 0, (struct sockaddr*)&udp_sockaddr, (socklen_t*) &addrlen); if ( bytes_received < 0 ) { printf("error: %s\n", strerror(errno)); continue; } //Copy the rest of the recieved packet into the sending packet memcpy(packet + sizeof(eth_hdr_t), packet_buffer, bytes_received); packet_len = sizeof(eth_hdr_t) + bytes_received; printf("Sending %i bytes on channel %i\n", packet_len, chan); //Send the same packet NUM_RETRANSMITS times for(j=0; j<NUM_RETRANSMITS; ++j){ n_bytes_sent = sendto(raw_socket, packet, packet_len, 0, (const struct sockaddr *)&sockaddr, sizeof(struct sockaddr_ll)); if (n_bytes_sent <= 0) { printf("Unable to send data: %s\n", strerror(errno)); return -1; } } } return 0; }
/* * Simple example sending packets with a sequence number in them */ int main (void) { int raw_socket = -1; struct sockaddr_ll sockaddr; uint8_t *packet = 0; uint8_t *packet_ptr; int packet_len; uint8_t *payload = 0; eth_hdr_t eth_hdr; int n_bytes_sent = 0; int ret; int i; //Set up the netlink socket nl_set_channel(CHANNEL,5); // Open the raw socket ret = open_socket(if_name, &raw_socket, &sockaddr); if (ret < 0){ printf("Error opening socket: %i\n", raw_socket); return -1; } // Create the packet packet_len = PAYLOAD_LEN + sizeof(eth_hdr_t); packet = malloc(packet_len); if ( packet == 0 ) { printf("Unable to allocate packet memory\n"); } packet_ptr = packet; // Add the ethernet header populate_eth_hdr(ð_hdr, sockaddr.sll_addr, ETH_TYPE_3DR); memcpy(packet_ptr, ð_hdr, sizeof(eth_hdr_t)); packet_ptr += sizeof(eth_hdr_t); // Populate the payload payload = malloc(PAYLOAD_LEN); if (payload == 0) { printf("Unable to allocate payload\n"); return -1; } memset(payload, 0, PAYLOAD_LEN); memcpy(packet_ptr, payload, PAYLOAD_LEN); i=0; while (2) { //Set the sequence number in the packet memcpy(packet + sizeof(eth_hdr_t),&i,4); ++i; printf("Sending on channel %i", CHANNEL); printf("seq: %i\n",i); n_bytes_sent = sendto(raw_socket, packet, packet_len, 0, (const struct sockaddr *)&sockaddr, sizeof(struct sockaddr_ll)); if (n_bytes_sent <= 0) { printf("Unable to send data: %s\n", strerror(errno)); return -1; } } return 0; }