FITkit
Fakulta informačních technologií

enc28j60_arp.c

Zobrazit dokumentaci tohoto souboru.
00001 /*******************************************************************************
00002    enc28j60_arp.c: ARP modul
00003    Copyright (C) 2010 Brno University of Technology,
00004                       Faculty of Information Technology
00005    Author(s): Martin Musil <xmusil34 AT fit.vutbr.cz>
00006 
00007    LICENSE TERMS
00008 
00009    Redistribution and use in source and binary forms, with or without
00010    modification, are permitted provided that the following conditions
00011    are met:
00012    1. Redistributions of source code must retain the above copyright
00013       notice, this list of conditions and the following disclaimer.
00014    2. Redistributions in binary form must reproduce the above copyright
00015       notice, this list of conditions and the following disclaimer in
00016       the documentation and/or other materials provided with the
00017       distribution.
00018    3. All advertising materials mentioning features or use of this software
00019       or firmware must display the following acknowledgement:
00020 
00021         This product includes software developed by the University of
00022         Technology, Faculty of Information Technology, Brno and its
00023         contributors.
00024 
00025    4. Neither the name of the Company nor the names of its contributors
00026       may be used to endorse or promote products derived from this
00027       software without specific prior written permission.
00028 
00029    This software or firmware is provided ``as is'', and any express or implied
00030    warranties, including, but not limited to, the implied warranties of
00031    merchantability and fitness for a particular purpose are disclaimed.
00032    In no event shall the company or contributors be liable for any
00033    direct, indirect, incidental, special, exemplary, or consequential
00034    damages (including, but not limited to, procurement of substitute
00035    goods or services; loss of use, data, or profits; or business
00036    interruption) however caused and on any theory of liability, whether
00037    in contract, strict liability, or tort (including negligence or
00038    otherwise) arising in any way out of the use of this software, even
00039    if advised of the possibility of such damage.
00040 
00041    $Id$
00042 
00043 *******************************************************************************/ 
00044 #include "enc28j60_spi.h"
00045 #include "enc28j60_eth.h"
00046 #include "enc28j60_arp.h"
00047 #include "enc28j60_ip.h"
00048 
00049 #include "enc28j60_string.h"
00050 
00051 extern unsigned long local_ip;
00052 extern unsigned long ip_netmask;
00053 extern unsigned long default_gateway;
00054 extern unsigned char broadcast_mac[MAC_LEN];
00055 
00056 struct arp_record arp_table[ARP_TABLE_SIZE];    // ARP tabulka
00057 unsigned char arp_last;
00058 
00059 extern unsigned char local_mac[MAC_LEN];
00060 unsigned char arp_next_free = 0;                                //ukazatel na volne misto v tabulce / na nejstarsi zaznam
00061 
00065 void arp_recv(){
00066         
00067         struct arp_h arp_header;
00068         
00069         rx_read(&arp_header,ARP_HEADER_LEN);
00070         
00071         // podpora pouze protokolu ethernet
00072         if(arp_header.hw_type != HTONS(ETH_HW_TYPE))
00073                 return;
00074 
00075         // podpora pouze IP protokolu
00076         if(arp_header.proto_type != NTOHS(ETH_PROTO_IP))
00077                 return;
00078 
00079         //kontrola delky MAC adresy
00080         if(arp_header.hw_addr_len != MAC_LEN)
00081                 return;
00082 
00083         //kontrola delky IP adresy
00084         if(arp_header.proto_addr_len != IP_LEN)
00085                 return;
00086 
00087         //kontrola IP adresy
00088         if(arp_header.target_ip != HTONL(local_ip))
00089                 return;
00090 
00091         //ARP REPLY
00092         if(arp_header.operation == HTONS(ARP_REPLY)){                                   //jedna se o odpoved
00093                 //ulozeni ARP zaznamu
00094                 arp_table_add(NTOHL(arp_header.sender_ip), arp_header.sender_mac);      //ulozeni zaznamu do arp tabulky
00095         }
00096         //ARP REQUEST
00097         else if(arp_header.operation == HTONS(ARP_REQUEST)){                                    //jedna se o arp zadost
00098         
00099                 //ulozeni ARP zaznamu
00100                 arp_table_add(NTOHL(arp_header.sender_ip), arp_header.sender_mac);
00101 
00102                 //doplneni hlavicky pro odpoved
00103                 arp_header.operation = HTONS(ARP_REPLY);
00104                 enc_memcpy(&arp_header.target_mac,&arp_header.sender_mac, MAC_LEN);     //prohozeni udaju sender a target
00105                 arp_header.target_ip = arp_header.sender_ip;
00106                 enc_memcpy(&arp_header.sender_mac,&local_mac, MAC_LEN);
00107                 arp_header.sender_ip = HTONL(local_ip);
00108 
00109 
00110                 tx_init(ARP_PROTO);                             //prepnuti na druhou cast odesilaciho bufferu           
00111                 tx_write(&arp_header, sizeof(struct arp_h));
00112 
00113                 tx_close();
00114                 
00115                 eth_send(arp_header.target_mac,ETH_PROTO_ARP);
00116         }
00117         
00118 return;
00119 }
00120 
00124 char arp_send(unsigned long dest_ip){
00125         
00126         struct arp_h arp_header;
00127         enc_memset(&arp_header, 0, ARP_HEADER_LEN);
00128 
00129         /*sestaveni hlavicky*/
00130         //protokol ethernet
00131         arp_header.hw_type = HTONS(ETH_HW_TYPE);
00132         // IP protokol
00133         arp_header.proto_type = HTONS(ETH_PROTO_IP);
00134         //typ operace, chceme REQUEST
00135         arp_header.operation = HTONS(ARP_REQUEST);
00136         //delka MAC adresy
00137         arp_header.hw_addr_len = MAC_LEN;
00138         //delka IP adresy
00139         arp_header.proto_addr_len = IP_LEN;
00140         //IP adresa odesilatele
00141         arp_header.sender_ip = HTONL(local_ip);
00142         //MAC adresa odesilatele
00143         enc_memcpy(&arp_header.sender_mac,&local_mac,MAC_LEN);
00144         //IP adresa prijemce
00145         arp_header.target_ip = HTONL(dest_ip);
00146         
00147         tx_init(ARP_PROTO);
00148         tx_write(&arp_header,ARP_HEADER_LEN);
00149         tx_close();
00150 
00151 return eth_send(broadcast_mac,ETH_PROTO_ARP);
00152 }       
00153         
00157 void arp_table_clear(){
00158         enc_memset(&arp_table, 0, sizeof(struct arp_record) * ARP_TABLE_SIZE);
00159         arp_last = 0;
00160 }
00161 
00165 void arp_table_add(int ip,unsigned char* mac){
00166 
00167         
00168         char* ptr = arp_table_find(ip);
00169                 
00170         if(ptr != NULL){                //zaznam jiz existuje
00171                 enc_memcpy(ptr,mac,MAC_LEN);            //aktualizace mac_adresy        
00172                 return;
00173         }
00174 
00175         //zaznam neexistuje, prepiseme posledni zaznam
00176         arp_table[arp_next_free].ip = ip;
00177         enc_memcpy( &(arp_table[arp_next_free].mac), mac, MAC_LEN);
00178         
00179         //posun arp_next_free pointeru (kruhove, pouze hodnoty <0;ARP_TABLE_SIZE> )
00180         if(++arp_next_free >= ARP_TABLE_SIZE)
00181                 arp_next_free = 0;
00182 
00183 
00184 return;
00185 }
00186 
00190 unsigned char* arp_table_find(int ip){
00191         
00192         int i;
00193         for (i=0; i < ARP_TABLE_SIZE; i++){
00194                 if(arp_table[i].ip == ip)
00195                         return arp_table[i].mac;
00196         }
00197 
00198 return NULL;
00199 }