<?xml version='1.0' encoding='utf-8'?><!DOCTYPE nta PUBLIC '-//Uppaal Team//DTD Flat System 1.0//EN' 'http://www.docs.uu.se/docs/rtmv/uppaal/xml/flat-1_0.dtd'><nta><declaration>
//
// CONSTANTS FROM RFC 3927 www.ietf.org/rfc/rfc3927.txt
//
// The following 10 constant declarations are copied almost verbatim from Section 9 
//   "The following timing constants are used in this protocol; they are
//   not intended to be user configurable."

const int    PROBE_WAIT          = 1; // second   (initial random  delay)
const int    PROBE_NUM           = 3; //          (number of probe packets)
const int    PROBE_MIN           = 1; // second   (minimum delay till repeated probe)
const int    PROBE_MAX           = 2; // seconds  (maximum delay till repeated probe)
const int    ANNOUNCE_WAIT       = 2; // seconds  (delay before announcing)
const int    ANNOUNCE_NUM        = 2; //          (number of announcement packets)
const int    ANNOUNCE_INTERVAL   = 2; // seconds  (time between announcement packets)
const int    MAX_CONFLICTS       = 10; //         (max conflicts before rate limiting)
const int    RATE_LIMIT_INTERVAL = 60; // second  (delay between successive attempts)
const int    DEFEND_INTERVAL     = 10; // seconds (minimum interval between defensive ARPs).

//The following constants have been defined by us
const int    k 		  = 3; // number of hosts
const int    m 		  = 1; // number of available IP addresses
			//Real value is 65024 but simulator can't handle that


typedef scalar[k] HAType;

			       
int[0,m] IP[HAType]; // array recording (guessed) IP address for each host, 0 means no address guessed
bool UseIP[HAType];  // array recording whether host is using an IP address

// channels to send messages to network, receive messages from network, and to reset host
chan send_req[HAType],receive_msg[HAType],answer,no_answer,reset[HAType];

// trick to make certain transitions urgent
urgent broadcast chan urg;

typedef int[0,m] IPType;

typedef struct{
	HAType senderHA;  // sender hardware address
	IPType senderIP;  // sender IP address
	IPType targetIP;  // target IP address
	bool request;     // is the packet a Request or a Reply
}ARP_packet;

//auxiliary control variables needed for handling  messages
bool response;
bool conflict;

//make following variable meta once this is implemented
ARP_packet packet;
</declaration><template><name x="-232" y="-768">Config</name><parameter>const HAType j</parameter><declaration>//Insert local declarations of clocks, variables and constants.

clock x;



</declaration><location id="id0" x="256" y="-256"><name x="264" y="-248">PRE_CLAIM</name><label kind="invariant" x="264" y="-232">x&lt;=ANNOUNCE_WAIT</label></location><location id="id1" x="264" y="24"><name x="216" y="24">INIT</name></location><location id="id2" x="480" y="-256"><name x="488" y="-248">USE</name></location><init ref="id1"/><transition><source ref="id2"/><target ref="id1"/><label kind="synchronisation" x="488" y="-176">reset[j]?</label><label kind="assignment" x="488" y="-160">IP[j]:=0,
UseIP[j]:=false,
x:=0</label></transition><transition><source ref="id0"/><target ref="id1"/><label kind="synchronisation" x="264" y="-192">reset[j]?</label><label kind="assignment" x="264" y="-176">IP[j]:=0,
x:=0</label></transition><transition><source ref="id1"/><target ref="id0"/><label kind="select" x="40" y="-128">address:int[1,m]</label><label kind="synchronisation" x="40" y="-112">send_req[j]!</label><label kind="assignment" x="40" y="-88">IP[j]:=address,
packet.senderHA:=j,
packet.senderIP:=0,
packet.targetIP:=IP[j],
packet.request:=true,
x:=0</label><nail x="168" y="-104"/></transition><transition><source ref="id0"/><target ref="id2"/><label kind="guard" x="288" y="-296">x==ANNOUNCE_WAIT</label><label kind="assignment" x="288" y="-280">UseIP[j]:=true</label></transition></template><template><name x="5" y="5">InputHandler</name><parameter>const HAType j</parameter><declaration>

void ihandler(bool defend)
{
  if (IP[j]==0) // Scenario A: I have not selected an IP address
 	{response:=false; conflict:=false;}
  else if (packet.senderHA==j) // Scenario B: I have sent the packet myself
	{response:=false; conflict:=false;}
  else if (packet.senderIP==IP[j]) //There is a conflict: somebody else is using my IP address!
	{
	conflict:=true;
	if (not UseIP[j]) // Scenario C: select a new address
		response:=false; 
	else if (defend) // Scenario D: I am going to defend my address
		response:=true;
	else  // Scenario E: I will not defend my address
		response:=false;
		}
  else if (not UseIP[j])	
	{
	response:=false;
	if (packet.targetIP==IP[j] &amp;&amp; packet.request &amp;&amp; packet.senderIP==0) // Scenario F: conflicting probe
		conflict:=true;
	else  //Scenario G: Packet is not conflicting with IP address that I want to use
		conflict:=false;
	}
  else // Incoming packet is not conflicting with IP address that I am using
	{
	conflict:=false;
	if (packet.targetIP==IP[j] &amp;&amp; packet.request) // Scenario H: answer regular ARP request 
		response:=true;
	else // Scenario I: no reply message required
		response:=false; 
	}		
}
</declaration><location id="id3" x="320" y="-96"><committed/></location><location id="id4" x="-96" y="-96"><committed/></location><location id="id5" x="480" y="-96"><committed/></location><location id="id6" x="192" y="96"><committed/></location><location id="id7" x="192" y="-96"></location><init ref="id7"/><transition><source ref="id5"/><target ref="id3"/><label kind="guard" x="344" y="-136">response==false</label><label kind="synchronisation" x="344" y="-120">no_answer!</label></transition><transition><source ref="id6"/><target ref="id4"/><label kind="guard" x="48" y="64">conflict==false</label></transition><transition><source ref="id3"/><target ref="id7"/><label kind="synchronisation" x="232" y="-120">reset[j]!</label></transition><transition><source ref="id6"/><target ref="id5"/><label kind="guard" x="240" y="64">conflict==true</label></transition><transition><source ref="id5"/><target ref="id7"/><label kind="guard" x="392" y="-264">response==true</label><label kind="synchronisation" x="392" y="-248">answer!</label><label kind="assignment" x="392" y="-232">packet.senderHA:=j,
packet.senderIP:=IP[j],
packet.targetIP:=IP[j],
packet.request:=true</label><nail x="480" y="-160"/><nail x="256" y="-160"/></transition><transition><source ref="id7"/><target ref="id6"/><label kind="synchronisation" x="216" y="-48">receive_msg[j]?</label><label kind="assignment" x="216" y="-32">ihandler(false)</label><nail x="208" y="-64"/><nail x="208" y="32"/></transition><transition><source ref="id4"/><target ref="id7"/><label kind="guard" x="-64" y="-136">response==false</label><label kind="synchronisation" x="-64" y="-120">no_answer!</label></transition><transition><source ref="id4"/><target ref="id7"/><label kind="guard" x="-64" y="-264">response==true</label><label kind="synchronisation" x="-64" y="-248">answer!</label><label kind="assignment" x="-64" y="-232">packet.targetIP:=packet.senderIP,
packet.senderHA:=j,
packet.senderIP:=IP[j],
packet.request:=false</label><nail x="-96" y="-160"/><nail x="128" y="-160"/></transition><transition><source ref="id7"/><target ref="id6"/><label kind="synchronisation" x="64" y="-48">receive_msg[j]?</label><label kind="assignment" x="72" y="-32">ihandler(true)</label><nail x="176" y="-64"/><nail x="176" y="32"/></transition></template><template><name>Network</name><parameter>const HAType j</parameter><declaration>clock z;
bool sent[HAType],replied;
ARP_packet answer_buffer, send_buffer;


void init_vars(){
   for(i: HAType){
	sent[i]:=false;
   };
   replied:=false;
   answer_buffer.senderIP:=0;
   answer_buffer.targetIP:=0;
   answer_buffer.request:=false;
}

bool all_sent(){
// the request packet has been sent to all 
// and if there is an answer it has been sent to all
return ((forall (i : HAType) sent[i]) and ((answer_buffer.senderIP!=0) imply replied));
}</declaration><location id="id8" x="416" y="352"><committed/></location><location id="id9" x="640" y="160"><committed/></location><location id="id10" x="416" y="160"><name x="440" y="168">DELIVER</name><label kind="invariant" x="440" y="184">z&lt;=1</label></location><location id="id11" x="192" y="160"><name x="144" y="160">IDLE</name></location><init ref="id11"/><transition><source ref="id8"/><target ref="id10"/><label kind="synchronisation" x="296" y="248">no_answer?</label><nail x="384" y="288"/><nail x="384" y="224"/></transition><transition><source ref="id9"/><target ref="id10"/><label kind="synchronisation" x="480" y="104">no_answer?</label><nail x="608" y="128"/><nail x="448" y="128"/></transition><transition><source ref="id9"/><target ref="id10"/><label kind="synchronisation" x="480" y="24">answer?</label><label kind="assignment" x="480" y="40">answer_buffer:=packet</label><nail x="608" y="64"/><nail x="448" y="64"/></transition><transition><source ref="id10"/><target ref="id8"/><label kind="select" x="424" y="248">host:HAType</label><label kind="guard" x="424" y="264">answer_buffer.senderIP!=0 &amp;&amp; replied==false &amp;&amp; host==send_buffer.senderHA</label><label kind="synchronisation" x="424" y="280">receive_msg[host]!</label><label kind="assignment" x="424" y="296">replied:=true,
packet:=answer_buffer</label></transition><transition><source ref="id10"/><target ref="id9"/><label kind="select" x="520" y="168">host:HAType</label><label kind="guard" x="520" y="184">sent[host]==false</label><label kind="synchronisation" x="520" y="200">receive_msg[host]!</label><label kind="assignment" x="520" y="216">sent[host]:=true,
packet:=send_buffer</label></transition><transition><source ref="id10"/><target ref="id11"/><label kind="guard" x="232" y="208">all_sent()</label><label kind="synchronisation" x="232" y="192">urg!</label><label kind="assignment" x="232" y="224">init_vars()</label><nail x="384" y="192"/><nail x="224" y="192"/></transition><transition><source ref="id11"/><target ref="id10"/><label kind="synchronisation" x="232" y="104">send_req[j]?</label><label kind="assignment" x="232" y="120">send_buffer:=packet,
z:=0</label></transition></template><system>
system 
	Config, InputHandler,Network;
	
</system></nta>