Čeština / English
Login

SVN Repository / Prohlížení

Aktuální adresář: FITkit / trunk / mcu / libs / enc28j60 /

enc28j60_arp.c

   1  /*******************************************************************************
   2     enc28j60_arp.c: ARP modul
   3     Copyright (C) 2010 Brno University of Technology,
   4                        Faculty of Information Technology
   5     Author(s): Martin Musil <xmusil34 AT fit.vutbr.cz>
   6  
   7     LICENSE TERMS
   8  
   9     Redistribution and use in source and binary forms, with or without
  10     modification, are permitted provided that the following conditions
  11     are met:
  12     1. Redistributions of source code must retain the above copyright
  13        notice, this list of conditions and the following disclaimer.
  14     2. Redistributions in binary form must reproduce the above copyright
  15        notice, this list of conditions and the following disclaimer in
  16        the documentation and/or other materials provided with the
  17        distribution.
  18     3. All advertising materials mentioning features or use of this software
  19        or firmware must display the following acknowledgement:
  20  
  21          This product includes software developed by the University of
  22          Technology, Faculty of Information Technology, Brno and its
  23          contributors.
  24  
  25     4. Neither the name of the Company nor the names of its contributors
  26        may be used to endorse or promote products derived from this
  27        software without specific prior written permission.
  28  
  29     This software or firmware is provided ``as is'', and any express or implied
  30     warranties, including, but not limited to, the implied warranties of
  31     merchantability and fitness for a particular purpose are disclaimed.
  32     In no event shall the company or contributors be liable for any
  33     direct, indirect, incidental, special, exemplary, or consequential
  34     damages (including, but not limited to, procurement of substitute
  35     goods or services; loss of use, data, or profits; or business
  36     interruption) however caused and on any theory of liability, whether
  37     in contract, strict liability, or tort (including negligence or
  38     otherwise) arising in any way out of the use of this software, even
  39     if advised of the possibility of such damage.
  40  
  41     $Id$
  42  
  43  *******************************************************************************/
  44  #include "enc28j60_spi.h"
  45  #include "enc28j60_eth.h"
  46  #include "enc28j60_arp.h"
  47  #include "enc28j60_ip.h"
  48  
  49  #include "enc28j60_string.h"
  50  
  51  extern unsigned long local_ip;
  52  extern unsigned long ip_netmask;
  53  extern unsigned long default_gateway;
  54  extern unsigned char broadcast_mac[MAC_LEN];
  55  
  56  struct arp_record arp_table[ARP_TABLE_SIZE];	// ARP tabulka
  57  unsigned char arp_last;
  58  
  59  extern unsigned char local_mac[MAC_LEN];
  60  unsigned char arp_next_free = 0;				//ukazatel na volne misto v tabulce / na nejstarsi zaznam
  61  
  62  /**
  63  
  64   **/
  65  void arp_recv(){
  66  
  67  	struct arp_h arp_header;
  68  
  69  	rx_read(&arp_header,ARP_HEADER_LEN);
  70  
  71  	// podpora pouze protokolu ethernet
  72  	if(arp_header.hw_type != HTONS(ETH_HW_TYPE))
  73  		return;
  74  
  75  	// podpora pouze IP protokolu
  76  	if(arp_header.proto_type != NTOHS(ETH_PROTO_IP))
  77  		return;
  78  
  79  	//kontrola delky MAC adresy
  80  	if(arp_header.hw_addr_len != MAC_LEN)
  81  		return;
  82  
  83  	//kontrola delky IP adresy
  84  	if(arp_header.proto_addr_len != IP_LEN)
  85  		return;
  86  
  87  	//kontrola IP adresy
  88  	if(arp_header.target_ip != HTONL(local_ip))
  89  		return;
  90  
  91  	//ARP REPLY
  92  	if(arp_header.operation == HTONS(ARP_REPLY)){					//jedna se o odpoved
  93  		//ulozeni ARP zaznamu
  94  		arp_table_add(NTOHL(arp_header.sender_ip), arp_header.sender_mac);	//ulozeni zaznamu do arp tabulky
  95  	}
  96  	//ARP REQUEST
  97  	else if(arp_header.operation == HTONS(ARP_REQUEST)){					//jedna se o arp zadost
  98  
  99  		//ulozeni ARP zaznamu
 100  		arp_table_add(NTOHL(arp_header.sender_ip), arp_header.sender_mac);
 101  
 102  		//doplneni hlavicky pro odpoved
 103  		arp_header.operation = HTONS(ARP_REPLY);
 104  		enc_memcpy(&arp_header.target_mac,&arp_header.sender_mac, MAC_LEN);	//prohozeni udaju sender a target
 105  		arp_header.target_ip = arp_header.sender_ip;
 106  		enc_memcpy(&arp_header.sender_mac,&local_mac, MAC_LEN);
 107  		arp_header.sender_ip = HTONL(local_ip);
 108  
 109  
 110  		tx_init(ARP_PROTO);				//prepnuti na druhou cast odesilaciho bufferu
 111  		tx_write(&arp_header, sizeof(struct arp_h));
 112  
 113  		tx_close();
 114  
 115  		eth_send(arp_header.target_mac,ETH_PROTO_ARP);
 116  	}
 117  
 118  return;
 119  }
 120  
 121  /**
 122  
 123   **/
 124  char arp_send(unsigned long dest_ip){
 125  
 126  	struct arp_h arp_header;
 127  	enc_memset(&arp_header, 0, ARP_HEADER_LEN);
 128  
 129  	/*sestaveni hlavicky*/
 130  	//protokol ethernet
 131  	arp_header.hw_type = HTONS(ETH_HW_TYPE);
 132  	// IP protokol
 133  	arp_header.proto_type = HTONS(ETH_PROTO_IP);
 134  	//typ operace, chceme REQUEST
 135  	arp_header.operation = HTONS(ARP_REQUEST);
 136  	//delka MAC adresy
 137  	arp_header.hw_addr_len = MAC_LEN;
 138  	//delka IP adresy
 139  	arp_header.proto_addr_len = IP_LEN;
 140  	//IP adresa odesilatele
 141  	arp_header.sender_ip = HTONL(local_ip);
 142  	//MAC adresa odesilatele
 143  	enc_memcpy(&arp_header.sender_mac,&local_mac,MAC_LEN);
 144  	//IP adresa prijemce
 145  	arp_header.target_ip = HTONL(dest_ip);
 146  
 147  	tx_init(ARP_PROTO);
 148  	tx_write(&arp_header,ARP_HEADER_LEN);
 149  	tx_close();
 150  
 151  return eth_send(broadcast_mac,ETH_PROTO_ARP);
 152  }
 153  
 154  /**
 155  
 156   **/
 157  void arp_table_clear(){
 158  	enc_memset(&arp_table, 0, sizeof(struct arp_record) * ARP_TABLE_SIZE);
 159  	arp_last = 0;
 160  }
 161  
 162  /**
 163  
 164   **/
 165  void arp_table_add(int ip,unsigned char* mac){
 166  
 167  
 168  	char* ptr = arp_table_find(ip);
 169  
 170  	if(ptr != NULL){		//zaznam jiz existuje
 171  		enc_memcpy(ptr,mac,MAC_LEN);		//aktualizace mac_adresy
 172  		return;
 173  	}
 174  
 175  	//zaznam neexistuje, prepiseme posledni zaznam
 176  	arp_table[arp_next_free].ip = ip;
 177  	enc_memcpy( &(arp_table[arp_next_free].mac), mac, MAC_LEN);
 178  
 179  	//posun arp_next_free pointeru (kruhove, pouze hodnoty <0;ARP_TABLE_SIZE> )
 180  	if(++arp_next_free >= ARP_TABLE_SIZE)
 181  		arp_next_free = 0;
 182  
 183  
 184  return;
 185  }
 186  
 187  /**
 188  
 189   **/
 190  unsigned char* arp_table_find(int ip){
 191  
 192  	int i;
 193  	for (i=0; i < ARP_TABLE_SIZE; i++){
 194  		if(arp_table[i].ip == ip)
 195  			return arp_table[i].mac;
 196  	}
 197  
 198  return NULL;
 199  }
 200  
Zobrazeno: 683829x Naposledy: 5.7.2022 04:33:16