<?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 		  = 2; // number of hosts
const int    m 		  = 1; // number of available IP addresses
			//Real value is 65024 but simulator can't handle that
const int    n		  = 2; // number of network automata

typedef scalar[k] HAType;
typedef scalar[n] NetworkType;
			       
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,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;

int [0,PROBE_NUM] counter;    //number of probes or gratuitous ARP that have been sent
int [0,MAX_CONFLICTS] ConflictNum;  //the number of times an address collision has occurred



</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="-96" y="-256"><name x="-144" y="-248">WAIT</name><label kind="invariant" x="-224" y="-232">x&lt;=PROBE_WAIT</label></location><location id="id2" x="160" y="-64"><name x="176" y="-64">COLLISION</name><label kind="invariant" x="176" y="-48">x&lt;=RATE_LIMIT_INTERVAL</label></location><location id="id3" x="64" y="-256"><name x="88" y="-248">PROBE</name><label kind="invariant" x="88" y="-232">x &lt;= PROBE_MAX</label></location><location id="id4" x="-96" y="32"><name x="-144" y="32">INIT</name></location><location id="id5" x="480" y="-256"><name x="488" y="-248">USE</name><label kind="invariant" x="488" y="-232">counter &lt; ANNOUNCE_NUM imply
x&lt;=ANNOUNCE_INTERVAL</label></location><init ref="id4"/><transition><source ref="id5"/><target ref="id4"/><label kind="synchronisation" x="488" y="-176">reset[j]?</label><label kind="assignment" x="488" y="-160">IP[j]:=0,
UseIP[j]:=false</label><nail x="480" y="32"/></transition><transition><source ref="id1"/><target ref="id2"/><label kind="synchronisation" x="-40" y="-176">reset[j]?</label><label kind="assignment" x="-40" y="-160">IP[j]:=0,
x:=0</label></transition><transition><source ref="id0"/><target ref="id2"/><label kind="synchronisation" x="224" y="-176">reset[j]?</label><label kind="assignment" x="224" y="-160">IP[j]:=0,
x:=0</label></transition><transition><source ref="id3"/><target ref="id0"/><label kind="guard" x="88" y="-304">counter==PROBE_NUM</label><label kind="synchronisation" x="88" y="-288">urg!</label><label kind="assignment" x="88" y="-272">x:=0</label></transition><transition><source ref="id1"/><target ref="id3"/><label kind="assignment" x="-72" y="-296">counter:=0,
x:=PROBE_MAX</label></transition><transition><source ref="id2"/><target ref="id4"/><label kind="guard" x="112" y="-16">ConflictNum &gt;= MAX_CONFLICTS &amp;&amp;
x==RATE_LIMIT_INTERVAL</label></transition><transition><source ref="id3"/><target ref="id2"/><label kind="synchronisation" x="128" y="-176">reset[j]?</label><label kind="assignment" x="128" y="-160">IP[j]:=0,
x:=0</label></transition><transition><source ref="id3"/><target ref="id3"/><label kind="guard" x="32" y="-504">counter&lt;PROBE_NUM &amp;&amp;
x&gt;=PROBE_MIN</label><label kind="synchronisation" x="32" y="-472">send_req!</label><label kind="assignment" x="32" y="-456">packet.senderHA:=j,
packet.senderIP:=0,
packet.targetIP:=IP[j],
packet.request:=true,
counter++,
x:=0</label><nail x="32" y="-336"/><nail x="64" y="-336"/></transition><transition><source ref="id4"/><target ref="id1"/><label kind="select" x="-216" y="-144">address:int[1,m]</label><label kind="assignment" x="-216" y="-128">IP[j]:=address,
x:=0</label></transition><transition><source ref="id5"/><target ref="id5"/><label kind="guard" x="480" y="-512">counter &lt; ANNOUNCE_NUM &amp;&amp;
x== ANNOUNCE_INTERVAL</label><label kind="synchronisation" x="480" y="-480">send_req!</label><label kind="assignment" x="480" y="-464">packet.senderHA:=j,
packet.senderIP:=IP[j],
packet.targetIP:=IP[j],
packet.request:=true,
counter++,
x:=0,
UseIP[j]:=true</label><nail x="480" y="-336"/><nail x="512" y="-336"/></transition><transition><source ref="id0"/><target ref="id5"/><label kind="guard" x="280" y="-336">x==ANNOUNCE_WAIT</label><label kind="assignment" x="280" y="-320">counter:=0,
ConflictNum:=0,
x:=ANNOUNCE_INTERVAL</label></transition><transition><source ref="id2"/><target ref="id4"/><label kind="guard" x="-80" y="-72">ConflictNum &lt; MAX_CONFLICTS</label><label kind="synchronisation" x="-80" y="-56">urg!</label><label kind="assignment" x="-80" y="-40">ConflictNum++</label><nail x="88" y="0"/></transition></template><template><name x="5" y="5">InputHandler</name><parameter>const HAType j</parameter><declaration>clock y;

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="id6" x="320" y="-96"><committed/></location><location id="id7" x="-96" y="-96"><committed/></location><location id="id8" x="480" y="-96"><committed/></location><location id="id9" x="192" y="96"><committed/></location><location id="id10" x="192" y="-224"><urgent/></location><location id="id11" x="192" y="-96"></location><init ref="id10"/><transition><source ref="id8"/><target ref="id6"/><label kind="guard" x="344" y="-136">response==false</label><label kind="synchronisation" x="344" y="-120">no_answer!</label></transition><transition><source ref="id9"/><target ref="id7"/><label kind="guard" x="48" y="64">conflict==false</label></transition><transition><source ref="id6"/><target ref="id11"/><label kind="synchronisation" x="232" y="-120">reset[j]!</label></transition><transition><source ref="id9"/><target ref="id8"/><label kind="guard" x="240" y="64">conflict==true</label></transition><transition><source ref="id8"/><target ref="id11"/><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,
y:=0</label><nail x="480" y="-160"/><nail x="256" y="-160"/></transition><transition><source ref="id11"/><target ref="id9"/><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="id7"/><target ref="id11"/><label kind="guard" x="-64" y="-136">response==false</label><label kind="synchronisation" x="-64" y="-120">no_answer!</label></transition><transition><source ref="id7"/><target ref="id11"/><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="id11"/><target ref="id9"/><label kind="guard" x="24" y="-64">y&gt;DEFEND_INTERVAL</label><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><transition><source ref="id10"/><target ref="id11"/><label kind="assignment" x="200" y="-200">y:=DEFEND_INTERVAL + 1</label></transition></template><template><name>Network</name><parameter>const NetworkType j</parameter><declaration>clock z;
bool sent[HAType],replied[HAType];
ARP_packet answer_buffer, send_buffer;


void init_vars(){
   for(i: HAType){
	sent[i]:=false;
	replied[i]:=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 (forall (i : HAType) replied[i])));
}</declaration><location id="id12" x="416" y="352"><committed/></location><location id="id13" x="640" y="160"><committed/></location><location id="id14" 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="id15" x="192" y="160"><name x="144" y="160">IDLE</name></location><init ref="id15"/><transition><source ref="id12"/><target ref="id14"/><label kind="synchronisation" x="296" y="248">no_answer?</label><nail x="384" y="288"/><nail x="384" y="224"/></transition><transition><source ref="id13"/><target ref="id14"/><label kind="synchronisation" x="480" y="104">no_answer?</label><nail x="608" y="128"/><nail x="448" y="128"/></transition><transition><source ref="id13"/><target ref="id14"/><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="id14"/><target ref="id12"/><label kind="select" x="424" y="248">host:HAType</label><label kind="guard" x="424" y="264">answer_buffer.senderIP!=0 &amp;&amp; replied[host]==false</label><label kind="synchronisation" x="424" y="280">receive_msg[host]!</label><label kind="assignment" x="424" y="296">replied[host]:=true,
packet:=answer_buffer</label></transition><transition><source ref="id14"/><target ref="id13"/><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="id14"/><target ref="id15"/><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="id15"/><target ref="id14"/><label kind="synchronisation" x="232" y="104">send_req?</label><label kind="assignment" x="232" y="120">send_buffer:=packet,
z:=0</label></transition></template><template><name>Regular</name><parameter>const HAType j</parameter><location id="id16" x="-384" y="-288"></location><init ref="id16"/><transition><source ref="id16"/><target ref="id16"/><label kind="select" x="-264" y="-304">address:int[1,m]</label><label kind="guard" x="-264" y="-288">UseIP[j]</label><label kind="synchronisation" x="-264" y="-272">send_req!</label><label kind="assignment" x="-264" y="-256">packet.senderHA:=j,
packet.senderIP:=IP[j],
packet.targetIP:=address,
packet.request:=true</label><nail x="-288" y="-288"/><nail x="-288" y="-224"/></transition></template><system>
system 
	Config, InputHandler,Regular,Network;
	
</system></nta>