add 203 codes
This commit is contained in:
parent
308085d03f
commit
aae17bb238
179
Blatt02/A203/arp_packet.c
Normal file
179
Blatt02/A203/arp_packet.c
Normal file
@ -0,0 +1,179 @@
|
||||
#include "arp_packet.h"
|
||||
|
||||
translation_table_entry translation_table[TB_L];
|
||||
int entry_length = 0;
|
||||
int entry_count = 0;
|
||||
|
||||
int search_entry(translation_table_entry * entry, uint32_t ip, int * table_id){
|
||||
for(size_t i = 0 ; i < entry_length; i++){
|
||||
if(ip == translation_table[i].ar_spa){
|
||||
entry->ar_pro = translation_table[i].ar_pro;
|
||||
entry->ar_spa = translation_table[i].ar_spa;
|
||||
for(size_t j = 0 ; j < MAC_A_S ; j++){
|
||||
entry->ar_sha[j] = translation_table[i].ar_sha[j];
|
||||
}
|
||||
*table_id = i;
|
||||
translation_table[i].count = entry_count;
|
||||
entry_count++;
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
int update_entry(int table_id, uint8_t * mac_ares){
|
||||
if(table_id >= TB_L) {
|
||||
perror("table_id wrong");
|
||||
return FAILED;
|
||||
}
|
||||
for(size_t j = 0 ; j < MAC_A_S ; j++){
|
||||
translation_table[table_id].ar_sha[j] = mac_ares[j];
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int insert_entry(translation_table_entry * entry){
|
||||
int final_id = entry_length;
|
||||
if(entry_length == TB_L){
|
||||
int minn = 1<<31;
|
||||
int id = -1;
|
||||
for(size_t i = 0 ; i < entry_length ; i++){
|
||||
if(translation_table[i].count < minn){
|
||||
minn = translation_table[i].count;
|
||||
id = i;
|
||||
}
|
||||
}
|
||||
final_id = id;
|
||||
}
|
||||
translation_table[final_id].ar_pro = entry->ar_pro;
|
||||
translation_table[final_id].ar_spa = entry->ar_spa;
|
||||
for(size_t j = 0 ; j < MAC_A_S ; j++){
|
||||
translation_table[final_id].ar_sha[j] = entry->ar_sha[j];
|
||||
}
|
||||
translation_table[final_id].count = entry_count;
|
||||
entry_count++;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int parse_arp_packet(mac_hdr * hdr, pkt_data * pkt, uint8_t * buf, size_t size){
|
||||
size_t offset = 0;
|
||||
for(size_t i=offset;i<offset+MAC_A_S;i++) hdr->dest_ares[i-offset]=buf[i]; offset += MAC_A_S;
|
||||
for(size_t i=offset;i<offset+MAC_A_S;i++) hdr->send_ares[i-offset]=buf[i]; offset += MAC_A_S;
|
||||
hdr->pro_T =combine_uint8(buf[offset], buf[offset+1]); offset += 2;
|
||||
pkt->ar_hrd=combine_uint8(buf[offset], buf[offset+1]); offset += 2;
|
||||
pkt->ar_pro=combine_uint8(buf[offset], buf[offset+1]); offset += 2;
|
||||
pkt->ar_hln=buf[offset]; offset += 1;
|
||||
pkt->ar_pln=buf[offset]; offset += 1;
|
||||
pkt->ar_op =combine_uint8(buf[offset], buf[offset+1]); offset += 2;
|
||||
for(size_t i=offset;i<offset+MAC_A_S;i++) pkt->ar_sha[i-offset]=buf[i]; offset += MAC_A_S;
|
||||
pkt->ar_spa = combine_uint8_32(buf+offset); offset+=IP_A_S;
|
||||
for(size_t i=offset;i<offset+MAC_A_S;i++) pkt->ar_tha[i-offset]=buf[i]; offset += MAC_A_S;
|
||||
pkt->ar_tpa = combine_uint8_32(buf+offset); offset+=IP_A_S;
|
||||
}
|
||||
|
||||
int receive_arp_packet(mac_hdr * hdr, pkt_data * pkt, uint8_t * buf, size_t size, uint8_t * local_ip, uint8_t * local_mac){
|
||||
uint32_t local_ip32 = combine_uint8_32(local_ip);
|
||||
|
||||
if(size < 42) {
|
||||
printf("The packet is too short! This is not an ARP packet!\n");
|
||||
return FAILED;
|
||||
}
|
||||
parse_arp_packet(hdr, pkt, buf, size);
|
||||
if(hdr->pro_T != ETHER_T_ARP) {
|
||||
printf("The packet is not ARP packet!\n");
|
||||
return FAILED;
|
||||
}
|
||||
if(pkt->ar_hrd != ARES_HRD_ETHERNET){
|
||||
printf("The hardware is not Ethernet!\n");
|
||||
return FAILED;
|
||||
}
|
||||
if(pkt->ar_pro!= ARES_PRO_IP){
|
||||
printf("The protocol is not IPv4!\n");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
int merge_flag = FALSE;
|
||||
int table_id = -1;
|
||||
|
||||
translation_table_entry entry;
|
||||
if(search_entry(&entry, pkt->ar_spa, &table_id) == SUCCESS){
|
||||
update_entry(table_id, pkt->ar_sha);
|
||||
merge_flag = TRUE;
|
||||
}
|
||||
if(merge_flag == FALSE){
|
||||
entry.ar_pro = pkt->ar_pro;
|
||||
entry.ar_spa = pkt->ar_spa;
|
||||
for(size_t j = 0 ; j < MAC_A_S ; j++){
|
||||
entry.ar_sha[j] = pkt->ar_sha[j];
|
||||
}
|
||||
}
|
||||
|
||||
if(pkt->ar_op==ARES_OP_REQ){
|
||||
printf("This is a request packet!\n");
|
||||
|
||||
uint32_t tmp_ip;
|
||||
uint8_t tmp_mac[MAC_A_S];
|
||||
tmp_ip = pkt->ar_spa; pkt->ar_spa = pkt->ar_tpa; pkt->ar_tpa = tmp_ip;
|
||||
memcpy(tmp_mac, pkt->ar_sha, MAC_A_S); memcpy(pkt->ar_sha, pkt->ar_tha, MAC_A_S); memcpy(pkt->ar_tha, tmp_mac, MAC_A_S);
|
||||
|
||||
memcpy(pkt->ar_sha, local_mac, MAC_A_S);
|
||||
pkt->ar_spa = local_ip32;
|
||||
|
||||
pkt->ar_op = ARES_OP_REP;
|
||||
memcpy(tmp_mac, hdr->dest_ares, MAC_A_S); memcpy(hdr->dest_ares, hdr->send_ares, MAC_A_S); memcpy(hdr->send_ares, tmp_mac, MAC_A_S);
|
||||
memcpy(hdr->send_ares, local_mac, MAC_A_S);
|
||||
return SUCCESS;
|
||||
}
|
||||
printf("This is a response packet!\n");
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int cv_uint16_to_uint8(uint8_t * tmp, uint16_t number){
|
||||
tmp[1] = number & 0x00FF;
|
||||
tmp[0] = (number >> 8 ) & 0x00FF;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int cv_arp_packet_to_uint8(uint8_t * resp_buffer, const pkt_data* pkt, const mac_hdr *hdr, size_t length){
|
||||
if( length < sizeof(pkt_data) + sizeof(mac_hdr) ) return FAILED;
|
||||
memcpy(resp_buffer, hdr->dest_ares, MAC_A_S); print_hex(resp_buffer, MAC_A_S); resp_buffer += MAC_A_S;
|
||||
memcpy(resp_buffer, hdr->send_ares, MAC_A_S); print_hex(resp_buffer, MAC_A_S); resp_buffer += MAC_A_S;
|
||||
uint8_t tmp[2];
|
||||
cv_uint16_to_uint8(tmp, hdr->pro_T);
|
||||
memcpy(resp_buffer, tmp, sizeof(uint16_t)); print_hex(resp_buffer, sizeof(uint16_t)); resp_buffer += sizeof(uint16_t);
|
||||
|
||||
cv_uint16_to_uint8(tmp, pkt->ar_hrd);
|
||||
memcpy(resp_buffer, tmp, sizeof(uint16_t)); print_hex(resp_buffer, sizeof(uint16_t)); resp_buffer += sizeof(uint16_t);
|
||||
cv_uint16_to_uint8(tmp, pkt->ar_pro);
|
||||
memcpy(resp_buffer, tmp, sizeof(uint16_t)); print_hex(resp_buffer, sizeof(uint16_t)); resp_buffer += sizeof(uint16_t);
|
||||
|
||||
uint16_t hln_pln = (pkt->ar_hln << 8) | (pkt->ar_pln);
|
||||
cv_uint16_to_uint8(tmp, hln_pln);
|
||||
memcpy(resp_buffer, tmp, sizeof(uint16_t)); print_hex(resp_buffer, sizeof(uint16_t)); resp_buffer += sizeof(uint16_t);
|
||||
|
||||
cv_uint16_to_uint8(tmp, pkt->ar_op);
|
||||
memcpy(resp_buffer, tmp, sizeof(uint16_t)); print_hex(resp_buffer, sizeof(uint16_t)); resp_buffer += sizeof(uint16_t);
|
||||
|
||||
memcpy(resp_buffer, pkt->ar_sha, MAC_A_S); print_hex(resp_buffer, MAC_A_S); resp_buffer += MAC_A_S;
|
||||
|
||||
uint8_t tmp_ip[4];
|
||||
for(size_t i = 0 ; i < 4 ; i++)
|
||||
tmp_ip[3-i] = ((pkt->ar_spa >> i * 8) & 0xFF);
|
||||
memcpy(resp_buffer, tmp_ip, IP_A_S); print_hex(resp_buffer, IP_A_S); resp_buffer += IP_A_S;
|
||||
|
||||
memcpy(resp_buffer, pkt->ar_tha, MAC_A_S); print_hex(resp_buffer, MAC_A_S); resp_buffer += MAC_A_S;
|
||||
|
||||
for(size_t i = 0 ; i < 4 ; i++)
|
||||
tmp_ip[3-i] = ((pkt->ar_tpa >> i * 8) & 0xFF);
|
||||
memcpy(resp_buffer, tmp_ip, IP_A_S); print_hex(resp_buffer, IP_A_S); resp_buffer += IP_A_S;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int send_arp_response(int tun_fd, uint8_t * resp_buffer, size_t length, const pkt_data * pkt, const mac_hdr * hdr){
|
||||
if(cv_arp_packet_to_uint8(resp_buffer, pkt, hdr, length) == FAILED) return FAILED;
|
||||
ssize_t nwrite = write(tun_fd, resp_buffer, length);
|
||||
if(nwrite < 0) return FAILED;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
43
Blatt02/A203/arp_packet.h
Normal file
43
Blatt02/A203/arp_packet.h
Normal file
@ -0,0 +1,43 @@
|
||||
#ifndef ARP_PACKET_H
|
||||
#define ARP_PACKET_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/if.h>
|
||||
#include <linux/if_tun.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include "arp_packet_st.h"
|
||||
#include "util.h"
|
||||
|
||||
#define IP_A_S 4
|
||||
#define OP_A_S 2
|
||||
|
||||
#define SUCCESS 0
|
||||
#define FAILED -1
|
||||
#define UNEQUAL 1
|
||||
|
||||
#define ARES_OP_REQ 0x0001
|
||||
#define ARES_OP_REP 0x0002
|
||||
#define ARES_HRD_ETHERNET 0x0001
|
||||
#define ETHER_T_ARP 0x0806
|
||||
#define ARES_PRO_IP 0x0800
|
||||
|
||||
#define TB_L 100
|
||||
|
||||
|
||||
int parse_arp_packet(mac_hdr * hdr, pkt_data * pkt, uint8_t * buf, size_t size);
|
||||
|
||||
int receive_arp_packet(mac_hdr * hdr, pkt_data * pkt, uint8_t * buf, size_t size, uint8_t * local_ip, uint8_t * local_mac);
|
||||
|
||||
int send_arp_response(int tun_fd, uint8_t * resp_buffer, size_t length, const pkt_data * pkt, const mac_hdr * hdr);
|
||||
|
||||
|
||||
#endif
|
36
Blatt02/A203/arp_packet_st.h
Normal file
36
Blatt02/A203/arp_packet_st.h
Normal file
@ -0,0 +1,36 @@
|
||||
#ifndef ARP_PACKET_ST_H
|
||||
#define ARP_PACKET_ST_H
|
||||
|
||||
#define MAC_A_S 6
|
||||
|
||||
#include<stdint.h>
|
||||
#include<stddef.h>
|
||||
|
||||
typedef struct{
|
||||
uint8_t dest_ares[MAC_A_S];
|
||||
uint8_t send_ares[MAC_A_S];
|
||||
uint16_t pro_T;
|
||||
}mac_hdr;
|
||||
|
||||
typedef struct{
|
||||
uint16_t ar_hrd;
|
||||
uint16_t ar_pro;
|
||||
uint8_t ar_hln;
|
||||
uint8_t ar_pln;
|
||||
uint16_t ar_op;
|
||||
uint8_t ar_sha[MAC_A_S];
|
||||
uint32_t ar_spa;
|
||||
uint8_t ar_tha[MAC_A_S];
|
||||
uint32_t ar_tpa;
|
||||
}pkt_data;
|
||||
|
||||
typedef struct{
|
||||
uint16_t ar_pro;
|
||||
uint32_t ar_spa;
|
||||
uint8_t ar_sha[MAC_A_S];
|
||||
int count;
|
||||
}translation_table_entry;
|
||||
|
||||
#endif
|
||||
|
||||
|
108
Blatt02/A203/tuntap.c
Normal file
108
Blatt02/A203/tuntap.c
Normal file
@ -0,0 +1,108 @@
|
||||
#include "arp_packet.h"
|
||||
|
||||
#define CLEAR(x) memset(&(x), 0x00, sizeof(x))
|
||||
|
||||
#define IFNAME "tap0"
|
||||
// #define IFNAME "tun0"
|
||||
|
||||
|
||||
#define BUFLEN 1600
|
||||
|
||||
static int tun_alloc(char *dev)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
int fd, err;
|
||||
|
||||
if( (fd = open("/dev/net/tun", O_RDWR)) < 0 ) {
|
||||
perror("Cannot open TUN/TAP dev\n"
|
||||
"Make sure one exists with "
|
||||
"'$ mknod /dev/net/tun c 10 200'");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
CLEAR(ifr);
|
||||
|
||||
/* Flags: IFF_TUN - TUN device (no Ethernet headers)
|
||||
* IFF_TAP - TAP device
|
||||
*
|
||||
* IFF_NO_PI - Do not provide packet information
|
||||
*/
|
||||
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
|
||||
if( *dev ) {
|
||||
strncpy(ifr.ifr_name, dev, IFNAMSIZ);
|
||||
}
|
||||
|
||||
if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ){
|
||||
perror("ERR: Could not ioctl tun");
|
||||
close(fd);
|
||||
return err;
|
||||
}
|
||||
|
||||
strcpy(dev, ifr.ifr_name);
|
||||
return fd;
|
||||
}
|
||||
|
||||
// int check_ip(uint8_t * ip, int length){
|
||||
// if(length != TARGET_IP_A_S) return UNEQUAL;
|
||||
// int8_t pc2[4]={10,5,1,2};
|
||||
// for(size_t i = 0 ; i < length ; i++)
|
||||
// printf("%X, %X \n", ip[i], pc2[i]);
|
||||
//
|
||||
// for(size_t i = 0 ; i < length ; i++)
|
||||
// if(ip[i]!=pc2[i]) return FAILED;
|
||||
// return SUCCESS;
|
||||
//}
|
||||
//
|
||||
int main (int argc, char *argv[]){
|
||||
|
||||
char dev[IFNAMSIZ];
|
||||
int tun_fd;
|
||||
|
||||
uint8_t local_ip[4] = {10, 5, 1, 10};
|
||||
uint8_t local_mac[6] = {0xD6,0x74,0x45,0xDC,0x5A,0xCD};
|
||||
|
||||
|
||||
if (argc > 1) {
|
||||
assert(strlen(argv[1]) < IFNAMSIZ);
|
||||
strcpy(dev, argv[1]);
|
||||
} else {
|
||||
strcpy(dev, IFNAME);
|
||||
}
|
||||
|
||||
printf("device name: %s\n", dev);
|
||||
|
||||
tun_fd = tun_alloc(dev);
|
||||
|
||||
int running = 1;
|
||||
|
||||
uint8_t buf[BUFLEN];
|
||||
while (running) {
|
||||
int nread;
|
||||
|
||||
if ((nread = read(tun_fd, buf, BUFLEN)) < 0) {
|
||||
perror("ERR: Read from tun_fd");
|
||||
break;
|
||||
}
|
||||
// buf[nread] = '\0';
|
||||
printf("buf :");
|
||||
print_hex(buf, nread);
|
||||
|
||||
mac_hdr hdr;
|
||||
pkt_data pkt;
|
||||
if(parse_arp_packet(&hdr, &pkt, buf, nread) == FAILED){
|
||||
perror("ERR: Cannot parse the packet");
|
||||
}
|
||||
if(receive_arp_packet(&hdr, &pkt, buf, nread, local_ip, local_mac) == FAILED){
|
||||
perror("ERR: Cannot process the packet");
|
||||
}
|
||||
if(send_arp_response(tun_fd, buf, nread, &pkt, &hdr) == FAILED){
|
||||
perror("ERR: Cannot send the response");
|
||||
}
|
||||
|
||||
printf("Read %d bytes from device %s\n\n", nread, dev);
|
||||
}
|
||||
|
||||
close(tun_fd);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
46
Blatt02/A203/util.c
Normal file
46
Blatt02/A203/util.c
Normal file
@ -0,0 +1,46 @@
|
||||
#include "util.h"
|
||||
void print_hex(uint8_t * array, size_t size){
|
||||
|
||||
for (size_t i = 0 ; i < size; i++){
|
||||
uint8_t high = (array[i] >> 4) & 0x0F;
|
||||
uint8_t low = array[i] & 0x0F;
|
||||
printf("%X", high);
|
||||
printf("%X ", low);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
void print_u16_hex(uint16_t number){
|
||||
uint8_t tmp_a[2];
|
||||
tmp_a[0] = (number >> 8) & 0x00FF;
|
||||
tmp_a[1] = number & 0x00FF;
|
||||
print_hex(tmp_a, 2);
|
||||
return;
|
||||
}
|
||||
void print_u8_hex(uint8_t number){
|
||||
printf("%X", (number >> 4) & 0x0F);
|
||||
printf("%X", number & 0x0F);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
// void print_packet_info(arp_packet_t * packet){
|
||||
// printf("destination: "); print_hex(packet->destination, DST_S);
|
||||
// printf("source: "); print_hex(packet->source, SRC_S);
|
||||
//
|
||||
// printf("hardware type: "); print_u16_hex(packet->hrd_t);
|
||||
// printf("protocal type: "); print_u16_hex(packet->pro_t);
|
||||
// printf("hardware size: "); print_u8_hex(packet->hrd_s);
|
||||
// printf("protocal size: "); print_u8_hex(packet->pro_s);
|
||||
// printf("op type: "); print_u16_hex(packet->op);
|
||||
//
|
||||
// printf("sender mac address: "); print_hex(packet->sender_mac_a, SENDER_MAC_A_S);
|
||||
// printf("sender ip address: "); print_hex(packet->sender_ip_a, SENDER_IP_A_S);
|
||||
// printf("target mac address: "); print_hex(packet->target_mac_a, TARGET_MAC_A_S);
|
||||
// printf("target ip address: "); print_hex(packet->target_ip_a, TARGET_IP_A_S);
|
||||
// }
|
||||
|
||||
uint16_t combine_uint8(uint8_t high, uint8_t low){
|
||||
return (high << 8 ) | low;
|
||||
}
|
||||
uint32_t combine_uint8_32(uint8_t * arr){
|
||||
return (arr[0] << 24 ) | (arr[1] << 16) | (arr[2] << 8) | (arr[3]);
|
||||
}
|
16
Blatt02/A203/util.h
Normal file
16
Blatt02/A203/util.h
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef UTIL_H
|
||||
#define UTIL_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include "arp_packet_st.h"
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
void print_hex(uint8_t * array, size_t size);
|
||||
void print_u16_hex(uint16_t number);
|
||||
void print_u8_hex(uint8_t number);
|
||||
uint16_t combine_uint8(uint8_t high, uint8_t low);
|
||||
uint32_t combine_uint8_32(uint8_t * arr);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user