بازنویسی لایه لینک پروتکل ارتباطی tcp در متلب
دوستانی که علاقمند به برنامه نویسی پایه پشته tcp/ip می توانند واقعیت پیاده سازی را با استفاده از این کد درک کنند، این کد بخشی از پروژه شبیه سازی شبکه های کامپیوتری که به شکل کد باز در اختیار علاقمندان و من جمله دانشجویان علاقمند قرار می دهم. در ضمن اسناد RFC و لینک هایی که برای کدنویسی از آنها استفاده کردم در بالای کد رفرنس شدند.
پیشنهادات و انتقادات شما باعث دلگرمی بنده خواهد بود.
%redesign of ip layer in tcp/ip stack % refence: %1-https://en.wikipedia.org/wiki/List_of_RFCs %2-https://en.wikipedia.org/wiki/List_of_RFCs %3-https://www.rfc-editor.org/search/rfc_search_detail.php?page=All&pubstatus[]=Any&pub_date_type=any&sortkey=Number&sorting=ASC %4-http://www.tcpipguide.com/free/t_ARPMessageFormat.htm %5- https://www.colasoft.com/help/7.1/appe_codes_ethernet.html %5-Packet Tracer help % Warning: all code we used here are decimals not hex! but all are Imitation from hex valus!! classdef link properties % internetLayerAgent= tcpIp.internet broadMac end methods function ap=link() global maxMac; ap.broadMac=maxMac; end function pdu=linkProt(linkLayer,pdu,netObj) if isfield(pdu,'ethernet') %means that pdu is incomming pdu inProcPortIndex=netObj.QueueinProcPortIndex(end); inProcPortName=netObj.ports(inProcPortIndex).name; switch netObj.typeDevice case 1 %PcObj if isfield(pdu,'arp') if strcmp(pdu.arp.SPA,pdu.arp.TPA) && strcmp(pdu.ethernet.destnation,'FF:FF:FF:FF:FF:FF') %update arp message srcIndex=find(strcmp(netObj.ARP_Table.hardWareAddress, pdu.arp.SHA ), 1); if ~isempty(srcIndex) netObj.ARP_Table{srcIndex,:}={pdu.arp.SPA ,pdu.ethernet.source,inProcPortName}; netObj.ioControlFlag(2)=1; else netObj.ioControlFlag(1)=1; end else if strcmp(pdu.arp.TPA,netObj.ports(inProcPortIndex).ip) && strcmp(pdu.ethernet.destnation,'FF:FF:FF:FF:FF:FF') packet=[]; packet.HRD=1;%packetDat.HRD;%defaultt=1, hardware type 1= Ethernet , 6=IEEE 802 Network, 7=ARCNET, 15=Frame Relay, 16= Asynchronous Transfer Mode(ATM, 17= HDLC ,18=Fibr Channel, 20=serialLine packet.PRO=800;%packetDat.PRO;%defaultt=8 as ip4;Protocol Type: This field is the complement of the Hardware Type field, specifying the type of layer three addresses used in the message. For IPv4 addresses, this value is 2048 (0800 hex), which corresponds to the EtherType code for the Internet Protocol. packet.HLN=6;%packetDat.HLN;%defaultt=6 ,Hardware Address Length: Specifies how long hardware addresses are in this message. For Ethernet or other networks using IEEE 802 MAC addresses, the value is 6. packet.PLN=4;%packetDat.PLN;%defaultt=4 ,Protocol Address Length: Again, the complement of the preceding field; specifies how long protocol (layer three) addresses are in this message. For IP(v4) addresses this value is of course 4. packet.OP=2;%defaultt=1 ,op code,1= arp request, 2= arp reply,3=RARP request, 4= RARP reply, 5=DRARP request, 6= DRARP reply,7= DRARP error,8= inARP request,9= inARP reply packet.SHA=netObj.ports(inProcPortIndex).mac;%Sender Hardware Address: The hardware (layer two) address of the device sending this message (which is the IP datagram source device on a request, and the IP datagram destination on a reply, as discussed in the topic on ARP operation). packet.SPA=netObj.ports(inProcPortIndex).ip ;%Sender Protocol Address: The IP address of the device sending this message. packet.THA=pdu.arp.SHA;%Target hardware Address: The hardware (layer two) address of the device this message is being sent to. This is the IP datagram destination device on a request, and the IP datagram source on a reply) packet.TPA=pdu.arp.SPA;%Target Protocol Address: The IP address of the device this message is being sent to. newpdu.arp=packet; packet=[]; packet.destnation=pdu.ethernet.source;%This is 6-Byte field which contains the MAC address of machine for which data is destined. packet.source=netObj.ports(inProcPortIndex).mac;%his is a 6-Byte field which contains the MAC address of source machine. As Source Address is always an individual address (Unicast), the least significant bit of first byte is always 0. packet.type=pdu.ethernet.type;% typ: arp =806 ,ipV4=800 for most code Go to the refrence 5 at the beginig newpdu.ethernet=packet; srcIndex=find(strcmp(netObj.ARP_Table.ipAddress, pdu.arp.SPA ), 1); if isempty(srcIndex) netObj.ARP_Table=[netObj.ARP_Table;{pdu.arp.SPA ,pdu.ethernet.source,inProcPortName}]; end pdu=newpdu; netObj.ioControlFlag(3)=1; elseif compareIp(pdu.arp.TPA, netObj.ports(inProcPortIndex).ip) srcIndex=find(strcmp(netObj.ARP_Table.ipAddress, pdu.arp.SPA ), 1); if isempty(srcIndex) netObj.ARP_Table=[netObj.ARP_Table;{pdu.arp.SPA ,pdu.ethernet.source,inProcPortName}]; end netObj.ioControlFlag(2)=1; else netObj.ioControlFlag(1)=1; end end else if strcmp(pdu.ethernet.destnation,netObj.ports(inProcPortIndex).mac) || strcmp(pdu.ethernet.destnation,'FF:FF:FF:FF:FF:FF') internetLayerAgent= tcpIp.internet; if (isfield(pdu,'rip') || isfield(pdu,'eigrp') || isfield(pdu,'ospf') ) % only for router netObj.ioControlFlag(1)=1; else newpdu=rmfield(pdu,'ethernet'); newpdu=internetLayerAgent.internetPort(newpdu,netObj); if strcmp(pdu.ethernet.destnation,macAddAloc('max')) % but not arp if isfield(pdu,'dhcp') && isfield(newpdu,'packetDat') if sum([2,5,10]==newpdu.packetDat.option.dhcp) % the current netobj is server, when dhcp code is even packet=[]; packet.destnation=macAddAloc('max') ;%This is 6-Byte field which contains the MAC address of machine for which data is destined. packet.source=netObj.ports(inProcPortIndex).mac;%his is a 6-Byte field which contains the MAC address of source machine. As Source Address is always an individual address (Unicast), the least significant bit of first byte is always 0. elseif sum([1,3,8,12]==newpdu.packetDat.option.dhcp) % the current netobj is cliend, when dhcp code is odd packet=[]; packet.destnation=macAddAloc('max') ;%This is 6-Byte field which contains the MAC address of machine for which data is destined. packet.source=netObj.ports(inProcPortIndex).mac;%his is a 6-Byte field which contains the MAC address of source machine. As Source Address is always an individual address (Unicast), the least significant bit of first byte is always 0. end else packet=[]; packet.destnation=pdu.ethernet.source;%This is 6-Byte field which contains the MAC address of machine for which data is destined. packet.source=netObj.ports(inProcPortIndex).mac;%his is a 6-Byte field which contains the MAC address of source machine. As Source Address is always an individual address (Unicast), the least significant bit of first byte is always 0. end else packet=[]; packet.destnation=pdu.ethernet.source ;%This is 6-Byte field which contains the MAC address of machine for which data is destined. packet.source=pdu.ethernet.destnation;%his is a 6-Byte field which contains the MAC address of source machine. As Source Address is always an individual address (Unicast), the least significant bit of first byte is always 0. end packet.type=pdu.ethernet.type;% typ: arp =806 ,ipV4=800 for most code Go to the refrence 5 at the beginig newpdu.ethernet=packet; pdu=newpdu; % this section behavior with recived frame will determined by application or upper layer protocols end else netObj.ioControlFlag(1)=1; end end case 2 %PcServerObj if isfield(pdu,'arp') if strcmp(pdu.arp.SPA,pdu.arp.TPA) && strcmp(pdu.ethernet.destnation,'FF:FF:FF:FF:FF:FF') %update arp message srcIndex=find(strcmp(netObj.ARP_Table.hardWareAddress, pdu.arp.SHA ), 1); if ~isempty(srcIndex) netObj.ARP_Table{srcIndex,:}={pdu.arp.SPA ,pdu.ethernet.source,inProcPortName}; netObj.ioControlFlag(2)=1; else netObj.ioControlFlag(1)=1; end else if strcmp(pdu.arp.TPA,netObj.ports(inProcPortIndex).ip) && strcmp(pdu.ethernet.destnation,'FF:FF:FF:FF:FF:FF') packet=[]; packet.HRD=1;%packetDat.HRD;%defaultt=1, hardware type 1= Ethernet , 6=IEEE 802 Network, 7=ARCNET, 15=Frame Relay, 16= Asynchronous Transfer Mode(ATM, 17= HDLC ,18=Fibr Channel, 20=serialLine packet.PRO=800;%packetDat.PRO;%defaultt=8 as ip4;Protocol Type: This field is the complement of the Hardware Type field, specifying the type of layer three addresses used in the message. For IPv4 addresses, this value is 2048 (0800 hex), which corresponds to the EtherType code for the Internet Protocol. packet.HLN=6;%packetDat.HLN;%defaultt=6 ,Hardware Address Length: Specifies how long hardware addresses are in this message. For Ethernet or other networks using IEEE 802 MAC addresses, the value is 6. packet.PLN=4;%packetDat.PLN;%defaultt=4 ,Protocol Address Length: Again, the complement of the preceding field; specifies how long protocol (layer three) addresses are in this message. For IP(v4) addresses this value is of course 4. packet.OP=2;%defaultt=1 ,op code,1= arp request, 2= arp reply,3=RARP request, 4= RARP reply, 5=DRARP request, 6= DRARP reply,7= DRARP error,8= inARP request,9= inARP reply packet.SHA=netObj.ports(inProcPortIndex).mac;%Sender Hardware Address: The hardware (layer two) address of the device sending this message (which is the IP datagram source device on a request, and the IP datagram destination on a reply, as discussed in the topic on ARP operation). packet.SPA=netObj.ports(inProcPortIndex).ip ;%Sender Protocol Address: The IP address of the device sending this message. packet.THA=pdu.arp.SHA;%Target hardware Address: The hardware (layer two) address of the device this message is being sent to. This is the IP datagram destination device on a request, and the IP datagram source on a reply) packet.TPA=pdu.arp.SPA;%Target Protocol Address: The IP address of the device this message is being sent to. newpdu.arp=packet; packet=[]; packet.destnation=pdu.ethernet.source;%This is 6-Byte field which contains the MAC address of machine for which data is destined. packet.source=netObj.ports(inProcPortIndex).mac;%his is a 6-Byte field which contains the MAC address of source machine. As Source Address is always an individual address (Unicast), the least significant bit of first byte is always 0. packet.type=pdu.ethernet.type;% typ: arp =806 ,ipV4=800 for most code Go to the refrence 5 at the beginig newpdu.ethernet=packet; srcIndex=find(strcmp(netObj.ARP_Table.ipAddress, pdu.arp.SPA ), 1); if isempty(srcIndex) netObj.ARP_Table=[netObj.ARP_Table;{pdu.arp.SPA ,pdu.ethernet.source,inProcPortName}]; end pdu=newpdu; netObj.ioControlFlag(3)=1; elseif compareIp(pdu.arp.TPA, netObj.ports(inProcPortIndex).ip) srcIndex=find(strcmp(netObj.ARP_Table.ipAddress, pdu.arp.SPA ), 1); if isempty(srcIndex) netObj.ARP_Table=[netObj.ARP_Table;{pdu.arp.SPA ,pdu.ethernet.source,inProcPortName}]; end netObj.ioControlFlag(2)=1; else netObj.ioControlFlag(1)=1; end end else if strcmp(pdu.ethernet.destnation,netObj.ports(inProcPortIndex).mac) || strcmp(pdu.ethernet.destnation,'FF:FF:FF:FF:FF:FF') internetLayerAgent= tcpIp.internet; if (isfield(pdu,'rip') || isfield(pdu,'eigrp') || isfield(pdu,'ospf') ) % only for router netObj.ioControlFlag(1)=1; else newpdu=rmfield(pdu,'ethernet'); newpdu=internetLayerAgent.internetPort(newpdu,netObj); if strcmp(pdu.ethernet.destnation,macAddAloc('max')) % but not arp if isfield(pdu,'dhcp') && isfield(newpdu,'packetDat') if sum([2,5,10]==newpdu.packetDat.option.dhcp) % the current netobj is server, when dhcp code is even packet=[]; packet.destnation=macAddAloc('max') ;%This is 6-Byte field which contains the MAC address of machine for which data is destined. packet.source=netObj.ports(inProcPortIndex).mac;%his is a 6-Byte field which contains the MAC address of source machine. As Source Address is always an individual address (Unicast), the least significant bit of first byte is always 0. elseif sum([1,3,8,12]==newpdu.packetDat.option.dhcp) % the current netobj is cliend, when dhcp code is odd packet=[]; packet.destnation=macAddAloc('max') ;%This is 6-Byte field which contains the MAC address of machine for which data is destined. packet.source=netObj.ports(inProcPortIndex).mac;%his is a 6-Byte field which contains the MAC address of source machine. As Source Address is always an individual address (Unicast), the least significant bit of first byte is always 0. end else packet=[]; packet.destnation=pdu.ethernet.source;%This is 6-Byte field which contains the MAC address of machine for which data is destined. packet.source=netObj.ports(inProcPortIndex).mac;%his is a 6-Byte field which contains the MAC address of source machine. As Source Address is always an individual address (Unicast), the least significant bit of first byte is always 0. end else packet=[]; packet.destnation=pdu.ethernet.source ;%This is 6-Byte field which contains the MAC address of machine for which data is destined. packet.source=pdu.ethernet.destnation;%his is a 6-Byte field which contains the MAC address of source machine. As Source Address is always an individual address (Unicast), the least significant bit of first byte is always 0. end packet.type=pdu.ethernet.type;% typ: arp =806 ,ipV4=800 for most code Go to the refrence 5 at the beginig newpdu.ethernet=packet; pdu=newpdu; % this section behavior with recived frame will determined by application or upper layer protocols end else netObj.ioControlFlag(1)=1; end end case 3 %smartphone if isfield(pdu,'arp') if strcmp(pdu.arp.SPA,pdu.arp.TPA) && strcmp(pdu.ethernet.destnation,'FF:FF:FF:FF:FF:FF') %update arp message srcIndex=find(strcmp(netObj.ARP_Table.hardWareAddress, pdu.arp.SHA ), 1); if ~isempty(srcIndex) netObj.ARP_Table{srcIndex,:}={pdu.arp.SPA ,pdu.ethernet.source,inProcPortName}; netObj.ioControlFlag(2)=1; else netObj.ioControlFlag(1)=1; end else if strcmp(pdu.arp.TPA,netObj.ports(inProcPortIndex).ip) && strcmp(pdu.ethernet.destnation,'FF:FF:FF:FF:FF:FF') packet=[]; packet.HRD=1;%packetDat.HRD;%defaultt=1, hardware type 1= Ethernet , 6=IEEE 802 Network, 7=ARCNET, 15=Frame Relay, 16= Asynchronous Transfer Mode(ATM, 17= HDLC ,18=Fibr Channel, 20=serialLine packet.PRO=800;%packetDat.PRO;%defaultt=8 as ip4;Protocol Type: This field is the complement of the Hardware Type field, specifying the type of layer three addresses used in the message. For IPv4 addresses, this value is 2048 (0800 hex), which corresponds to the EtherType code for the Internet Protocol. packet.HLN=6;%packetDat.HLN;%defaultt=6 ,Hardware Address Length: Specifies how long hardware addresses are in this message. For Ethernet or other networks using IEEE 802 MAC addresses, the value is 6. packet.PLN=4;%packetDat.PLN;%defaultt=4 ,Protocol Address Length: Again, the complement of the preceding field; specifies how long protocol (layer three) addresses are in this message. For IP(v4) addresses this value is of course 4. packet.OP=2;%defaultt=1 ,op code,1= arp request, 2= arp reply,3=RARP request, 4= RARP reply, 5=DRARP request, 6= DRARP reply,7= DRARP error,8= inARP request,9= inARP reply packet.SHA=netObj.ports(inProcPortIndex).mac;%Sender Hardware Address: The hardware (layer two) address of the device sending this message (which is the IP datagram source device on a request, and the IP datagram destination on a reply, as discussed in the topic on ARP operation). packet.SPA=netObj.ports(inProcPortIndex).ip ;%Sender Protocol Address: The IP address of the device sending this message. packet.THA=pdu.arp.SHA;%Target hardware Address: The hardware (layer two) address of the device this message is being sent to. This is the IP datagram destination device on a request, and the IP datagram source on a reply) packet.TPA=pdu.arp.SPA;%Target Protocol Address: The IP address of the device this message is being sent to. newpdu.arp=packet; packet=[]; packet.destnation=pdu.ethernet.source;%This is 6-Byte field which contains the MAC address of machine for which data is destined. packet.source=netObj.ports(inProcPortIndex).mac;%his is a 6-Byte field which contains the MAC address of source machine. As Source Address is always an individual address (Unicast), the least significant bit of first byte is always 0. packet.type=pdu.ethernet.type;% typ: arp =806 ,ipV4=800 for most code Go to the refrence 5 at the beginig newpdu.ethernet=packet; srcIndex=find(strcmp(netObj.ARP_Table.ipAddress, pdu.arp.SPA ), 1); if isempty(srcIndex) netObj.ARP_Table=[netObj.ARP_Table;{pdu.arp.SPA ,pdu.ethernet.source,inProcPortName}]; end pdu=newpdu; netObj.ioControlFlag(3)=1; elseif compareIp(pdu.arp.TPA, netObj.ports(inProcPortIndex).ip) srcIndex=find(strcmp(netObj.ARP_Table.ipAddress, pdu.arp.SPA ), 1); if isempty(srcIndex) netObj.ARP_Table=[netObj.ARP_Table;{pdu.arp.SPA ,pdu.ethernet.source,inProcPortName}]; end netObj.ioControlFlag(2)=1; else netObj.ioControlFlag(1)=1; end end else if strcmp(pdu.ethernet.destnation,netObj.ports(inProcPortIndex).mac) || strcmp(pdu.ethernet.destnation,'FF:FF:FF:FF:FF:FF') internetLayerAgent= tcpIp.internet; if (isfield(pdu,'rip') || isfield(pdu,'eigrp') || isfield(pdu,'ospf') ) % only for router netObj.ioControlFlag(1)=1; else newpdu=rmfield(pdu,'ethernet'); newpdu=internetLayerAgent.internetPort(newpdu,netObj); if strcmp(pdu.ethernet.destnation,macAddAloc('max')) % but not arp if isfield(pdu,'dhcp') && isfield(newpdu,'packetDat') if sum([2,5,10]==newpdu.packetDat.option.dhcp) % the current netobj is server, when dhcp code is even packet=[]; packet.destnation=macAddAloc('max') ;%This is 6-Byte field which contains the MAC address of machine for which data is destined. packet.source=netObj.ports(inProcPortIndex).mac;%his is a 6-Byte field which contains the MAC address of source machine. As Source Address is always an individual address (Unicast), the least significant bit of first byte is always 0. elseif sum([1,3,8,12]==newpdu.packetDat.option.dhcp) % the current netobj is cliend, when dhcp code is odd packet=[]; packet.destnation=macAddAloc('max') ;%This is 6-Byte field which contains the MAC address of machine for which data is destined. packet.source=netObj.ports(inProcPortIndex).mac;%his is a 6-Byte field which contains the MAC address of source machine. As Source Address is always an individual address (Unicast), the least significant bit of first byte is always 0. end else packet=[]; packet.destnation=pdu.ethernet.source;%This is 6-Byte field which contains the MAC address of machine for which data is destined. packet.source=netObj.ports(inProcPortIndex).mac;%his is a 6-Byte field which contains the MAC address of source machine. As Source Address is always an individual address (Unicast), the least significant bit of first byte is always 0. end else packet=[]; packet.destnation=pdu.ethernet.source ;%This is 6-Byte field which contains the MAC address of machine for which data is destined. packet.source=pdu.ethernet.destnation;%his is a 6-Byte field which contains the MAC address of source machine. As Source Address is always an individual address (Unicast), the least significant bit of first byte is always 0. end packet.type=pdu.ethernet.type;% typ: arp =806 ,ipV4=800 for most code Go to the refrence 5 at the beginig newpdu.ethernet=packet; pdu=newpdu; % this section behavior with recived frame will determined by application or upper layer protocols end else netObj.ioControlFlag(1)=1; end end case 4 %HubObj disp(''); case 5 %SwitchObj: we used switchs as layer 2 device and not set layer 3 configuration type inProcPortvlan=num2str(netObj.ports(inProcPortIndex).vlanValue); if isfield(pdu,'arp') %% arp proccess is within network only if strcmp(pdu.arp.SPA,pdu.arp.TPA) && strcmp(pdu.ethernet.destnation,'FF:FF:FF:FF:FF:FF')%% arp the first type %update arp message srcIndex=find(strcmp(netObj.MAC_Table.macAddress, pdu.arp.SHA ), 1); if ~isempty(srcIndex) netObj.MAC_Table=[netObj.MAC_Table;{inProcPortvlan,pdu.ethernet.source,inProcPortName}]; end netObj.ioControlFlag(5)=1; % % switch need in any condtion broadcast the message unless source and destnation is determined else %% arp the second typ srcIndex=find(strcmp(netObj.MAC_Table.macAddress, pdu.ethernet.source ), 1); dstIndex=find(strcmp(netObj.MAC_Table.macAddress, pdu.ethernet.destnation ), 1); switch strcmp(pdu.ethernet.destnation,'FF:FF:FF:FF:FF:FF') case 1 % it is broadcast arp if isempty(srcIndex) netObj.MAC_Table=[netObj.MAC_Table;{inProcPortvlan,pdu.ethernet.source,inProcPortName}]; end netObj.ioControlFlag(5)=1; case 0 % it is unicast arp if ~isempty(srcIndex) && ~isempty(dstIndex) netObj.ioControlFlag(4)=1;%relay else netObj.MAC_Table=[netObj.MAC_Table;{inProcPortvlan,pdu.ethernet.source,inProcPortName}]; netObj.ioControlFlag(4)=1;%relay end end end else % is not arp packet srcIndex=find(strcmp(netObj.MAC_Table.macAddress, pdu.ethernet.source ), 1); dstIndex=find(strcmp(netObj.MAC_Table.macAddress, pdu.ethernet.destnation ), 1); if ~isempty(srcIndex) && ~isempty(dstIndex) %% here this means that the destnation netObject is out of network netObj.ioControlFlag(4)=1; elseif isempty(srcIndex) && ~strcmp(pdu.ethernet.destnation, 'FF:FF:FF:FF:FF:FF' ) netObj.MAC_Table=[netObj.MAC_Table;{inProcPortvlan,pdu.ethernet.source,inProcPortName}]; netObj.ioControlFlag(4)=1; elseif strcmp(pdu.ethernet.destnation, 'FF:FF:FF:FF:FF:FF' ) netObj.ioControlFlag(5)=1; end end case 6 %RoutrrObj if isfield(pdu,'arp') if strcmp(pdu.arp.SPA,pdu.arp.TPA) && strcmp(pdu.ethernet.destnation,'FF:FF:FF:FF:FF:FF') %update arp message srcIndex=find(strcmp(netObj.ARP_Table.hardWareAddress, pdu.arp.SHA ), 1); if ~isempty(srcIndex) netObj.ARP_Table{srcIndex,:}={pdu.arp.SPA ,pdu.ethernet.source,inProcPortName}; netObj.ioControlFlag(2)=1; else netObj.ioControlFlag(1)=1; end else if strcmp(pdu.arp.TPA,netObj.ports(inProcPortIndex).ip) && strcmp(pdu.ethernet.destnation,'FF:FF:FF:FF:FF:FF') packet=[]; packet.HRD=1;%packetDat.HRD;%defaultt=1, hardware type 1= Ethernet , 6=IEEE 802 Network, 7=ARCNET, 15=Frame Relay, 16= Asynchronous Transfer Mode(ATM, 17= HDLC ,18=Fibr Channel, 20=serialLine packet.PRO=800;%packetDat.PRO;%defaultt=8 as ip4;Protocol Type: This field is the complement of the Hardware Type field, specifying the type of layer three addresses used in the message. For IPv4 addresses, this value is 2048 (0800 hex), which corresponds to the EtherType code for the Internet Protocol. packet.HLN=6;%packetDat.HLN;%defaultt=6 ,Hardware Address Length: Specifies how long hardware addresses are in this message. For Ethernet or other networks using IEEE 802 MAC addresses, the value is 6. packet.PLN=4;%packetDat.PLN;%defaultt=4 ,Protocol Address Length: Again, the complement of the preceding field; specifies how long protocol (layer three) addresses are in this message. For IP(v4) addresses this value is of course 4. packet.OP=2;%defaultt=1 ,op code,1= arp request, 2= arp reply,3=RARP request, 4= RARP reply, 5=DRARP request, 6= DRARP reply,7= DRARP error,8= inARP request,9= inARP reply packet.SHA=netObj.ports(inProcPortIndex).mac;%Sender Hardware Address: The hardware (layer two) address of the device sending this message (which is the IP datagram source device on a request, and the IP datagram destination on a reply, as discussed in the topic on ARP operation). packet.SPA=netObj.ports(inProcPortIndex).ip ;%Sender Protocol Address: The IP address of the device sending this message. packet.THA=pdu.arp.SHA;%Target hardware Address: The hardware (layer two) address of the device this message is being sent to. This is the IP datagram destination device on a request, and the IP datagram source on a reply) packet.TPA=pdu.arp.SPA;%Target Protocol Address: The IP address of the device this message is being sent to. newpdu.arp=packet; packet=[]; packet.destnation=pdu.ethernet.source;%This is 6-Byte field which contains the MAC address of machine for which data is destined. packet.source=netObj.ports(inProcPortIndex).mac;%his is a 6-Byte field which contains the MAC address of source machine. As Source Address is always an individual address (Unicast), the least significant bit of first byte is always 0. packet.type=pdu.ethernet.type;% typ: arp =806 ,ipV4=800 for most code Go to the refrence 5 at the beginig newpdu.ethernet=packet; srcIndex=find(strcmp(netObj.ARP_Table.ipAddress, pdu.arp.SPA ), 1); if isempty(srcIndex) netObj.ARP_Table=[netObj.ARP_Table;{pdu.arp.SPA ,pdu.ethernet.source,inProcPortName}]; end pdu=newpdu; netObj.ioControlFlag(3)=1; elseif compareIp(pdu.arp.TPA, netObj.ports(inProcPortIndex).ip) srcIndex=find(strcmp(netObj.ARP_Table.ipAddress, pdu.arp.SPA ), 1); if isempty(srcIndex) netObj.ARP_Table=[netObj.ARP_Table;{pdu.arp.SPA ,pdu.ethernet.source,inProcPortName}]; end netObj.ioControlFlag(2)=1; else netObj.ioControlFlag(1)=1; end end else if strcmp(pdu.ethernet.destnation,netObj.ports(inProcPortIndex).mac) || strcmp(pdu.ethernet.destnation,'FF:FF:FF:FF:FF:FF') internetLayerAgent= tcpIp.internet; newpdu=rmfield(pdu,'ethernet'); newpdu=internetLayerAgent.internetPort(newpdu,netObj); if strcmp(pdu.ethernet.destnation,macAddAloc('max')) % but not arp if isfield(pdu,'dhcp') && isfield(newpdu,'packetDat') if sum([2,5,10]==newpdu.packetDat.option.dhcp) % the current netobj is server, when dhcp code is even packet=[]; packet.destnation=macAddAloc('max') ;%This is 6-Byte field which contains the MAC address of machine for which data is destined. packet.source=netObj.ports(inProcPortIndex).mac;%his is a 6-Byte field which contains the MAC address of source machine. As Source Address is always an individual address (Unicast), the least significant bit of first byte is always 0. elseif sum([1,3,8,12]==newpdu.packetDat.option.dhcp) % the current netobj is cliend, when dhcp code is odd packet=[]; packet.destnation=macAddAloc('max') ;%This is 6-Byte field which contains the MAC address of machine for which data is destined. packet.source=netObj.ports(inProcPortIndex).mac;%his is a 6-Byte field which contains the MAC address of source machine. As Source Address is always an individual address (Unicast), the least significant bit of first byte is always 0. end else packet=[]; packet.destnation=pdu.ethernet.source;%This is 6-Byte field which contains the MAC address of machine for which data is destined. packet.source=netObj.ports(inProcPortIndex).mac;%his is a 6-Byte field which contains the MAC address of source machine. As Source Address is always an individual address (Unicast), the least significant bit of first byte is always 0. end else packet=[]; packet.destnation=pdu.ethernet.source ;%This is 6-Byte field which contains the MAC address of machine for which data is destined. packet.source=pdu.ethernet.destnation;%his is a 6-Byte field which contains the MAC address of source machine. As Source Address is always an individual address (Unicast), the least significant bit of first byte is always 0. end packet.type=pdu.ethernet.type;% typ: arp =806 ,ipV4=800 for most code Go to the refrence 5 at the beginig newpdu.ethernet=packet; pdu=newpdu; % this section behavior with recived frame will determined by application or upper layer protocols end end case 7 %SnifObj disp(''); case 8 % board case 9 % iot case 10 % cloud inProcPortvlan=num2str(netObj.ports(inProcPortIndex).vlanValue); if isfield(pdu,'arp') %% arp proccess is within network only if strcmp(pdu.arp.SPA,pdu.arp.TPA) && strcmp(pdu.ethernet.destnation,'FF:FF:FF:FF:FF:FF')%% arp the first type %update arp message srcIndex=find(strcmp(netObj.MAC_Table.macAddress, pdu.arp.SHA ), 1); if ~isempty(srcIndex) netObj.MAC_Table=[netObj.MAC_Table;{inProcPortvlan,pdu.ethernet.source,inProcPortName}]; end netObj.ioControlFlag(5)=1; % % switch need in any condtion broadcast the message unless source and destnation is determined else %% arp the second typ srcIndex=find(strcmp(netObj.MAC_Table.macAddress, pdu.ethernet.source ), 1); dstIndex=find(strcmp(netObj.MAC_Table.macAddress, pdu.ethernet.destnation ), 1); switch strcmp(pdu.ethernet.destnation,'FF:FF:FF:FF:FF:FF') case 1 % it is broadcast arp if isempty(srcIndex) netObj.MAC_Table=[netObj.MAC_Table;{inProcPortvlan,pdu.ethernet.source,inProcPortName}]; end netObj.ioControlFlag(5)=1; case 0 % it is unicast arp if ~isempty(srcIndex) && ~isempty(dstIndex) netObj.ioControlFlag(4)=1;%relay else netObj.MAC_Table=[netObj.MAC_Table;{inProcPortvlan,pdu.ethernet.source,inProcPortName}]; netObj.ioControlFlag(4)=1;%relay end end end else % is not arp packet srcIndex=find(strcmp(netObj.MAC_Table.macAddress, pdu.ethernet.source ), 1); dstIndex=find(strcmp(netObj.MAC_Table.macAddress, pdu.ethernet.destnation ), 1); if ~isempty(srcIndex) && ~isempty(dstIndex) %% here this means that the destnation netObject is out of network netObj.ioControlFlag(4)=1; elseif isempty(srcIndex) && ~strcmp(pdu.ethernet.destnation, 'FF:FF:FF:FF:FF:FF' ) netObj.MAC_Table=[netObj.MAC_Table;{inProcPortvlan,pdu.ethernet.source,inProcPortName}]; netObj.ioControlFlag(4)=1; elseif strcmp(pdu.ethernet.destnation, 'FF:FF:FF:FF:FF:FF' ) netObj.ioControlFlag(5)=1; end end end end end function pdu=linkOutProt(linkLayer,pdu,netObj) if isfield(pdu,'ip') && compareIp(pdu.packetDat.sourceIp,pdu.packetDat.destnationIp) % in the future we used this feature as netObj.ioControlFlag(1)=1; elseif isfield(pdu,'ip') && strcmp(pdu.packetDat.destnationIp,'255.255.255.255') pdu.packetDat.destnation=macAddAloc('max'); inUseIntIndex=find([netObj.ports.inUse]==1); ValidIpindex=find(ismember({netObj.ports(inUseIntIndex).ip}, pdu.packetDat.sourceIp )); if isempty(ValidIpindex)% for dhcp pdu.packetDat.source=netObj.ports(1).mac; else % for rip and other broadcast pdu.packetDat.source=netObj.ports(ValidIpindex).mac; end pdu.packetDat.type=800; if netObj.typeDevice==6 && (isfield(pdu,'rip') || isfield(pdu,'eigrp') || isfield(pdu,'ospf') ) % only for router netObj.ioControlFlag(4) = 1; else netObj.ioControlFlag(5) = 1; end pdu=linkLayer.ethernet( pdu,netObj); else inUseIntIndex=find([netObj.ports.inUse]==1); netObjIpS={netObj.ports(inUseIntIndex).ip}; validList=isvalidIp(netObjIpS); inUseIntIndex=inUseIntIndex(logical(validList)); netObjIpS={netObj.ports(inUseIntIndex).ip}; destIps=repmat({pdu.packetDat.destnationIp},1,length(netObjIpS)); subnetMaskS={netObj.ports(inUseIntIndex).subnetMask}; [~,netObjSubId,~]=getNet(netObjIpS,subnetMaskS); [~,destObjSubId,~]=getNet(destIps,subnetMaskS); destIntIndex=find(ismember(netObjSubId,destObjSubId)); if ~isempty(destIntIndex)% it is in sebnet, that connect to one of curent device ports srcIndex=find(strcmp(netObj.ARP_Table.ipAddress, ip2IpS_dec(pdu.packetDat.destnationIp,0) ), 1);% if ~isempty(srcIndex) % if it has a record in arp table destHwA=table2struct(netObj.ARP_Table(srcIndex,2)); destInFaName=table2struct(netObj.ARP_Table(srcIndex,3)); portNum=ismember({netObj.ports.name},destInFaName.interface); pdu.packetDat.destnation= destHwA.hardWareAddress; pdu.packetDat.source= netObj.ports(portNum).mac; netObj.ioControlFlag(4)=1; pdu=linkLayer.ethernet( pdu,netObj); else %arp parameters newPdu.packetDat.SHA=netObj.ports(destIntIndex).mac ; newPdu.packetDat.SPA=pdu.packetDat.sourceIp;%netObj.ports(pInd).mac; newPdu.packetDat.THA=macAddAloc('min');%Target Hardware Address: 00:00:00:00:00:00 as broadcast newPdu.packetDat.TPA=pdu.packetDat.destnationIp;%Target Protocol Address: The IP address of the device this message is being sent to. %ethernet parameters newPdu.packetDat.destnation=macAddAloc('max'); newPdu.packetDat.source= netObj.ports(destIntIndex).mac; %arp proccess netObj.ioControlFlag(5)=1; sentframe=linkLayer.arp(newPdu,netObj); reciveframe=netObj.recBuffer; srcIndex=find(strcmp(netObj.ARP_Table.ipAddress, ip2IpS_dec(pdu.packetDat.destnationIp,0) ), 1);% if ~isempty(srcIndex) % if it has a record in arp table destHwA=table2struct(netObj.ARP_Table(srcIndex,2)); destInFaName=table2struct(netObj.ARP_Table(srcIndex,3)); portNum=ismember({netObj.ports.name},destInFaName.interface); pdu.packetDat.destnation= destHwA.hardWareAddress; pdu.packetDat.source= netObj.ports(portNum).mac; netObj.ioControlFlag(4)=1; pdu=linkLayer.ethernet( pdu,netObj); else % end end elseif netObj.typeDevice~=6 && isfield(netObj.ports,'gatWay4') % if frame dont blong to current network and device is not router inUseIntIndex=find([netObj.ports.inUse]==1); netObjIpS={netObj.ports(inUseIntIndex).ip}; validList=isvalidIp(netObjIpS); inUseIntIndex=inUseIntIndex(logical(validList)); netObjIpS={netObj.ports(inUseIntIndex).ip}; destIps=repmat({netObj.ports(1).gatWay4},1,length(netObjIpS)); subnetMaskS={netObj.ports(inUseIntIndex).subnetMask}; [netObjNetId,netObjSubId,~]=getNet(netObjIpS,subnetMaskS); [destObjNetId,destObjSubId,~]=getNet(destIps,subnetMaskS); destIntIndex=find(ismember(netObjSubId,destObjSubId)); if ~isempty(destIntIndex)% it is in sebnet, that connect to one of curent device ports srcIndex=find(strcmp(netObj.ARP_Table.ipAddress, ip2IpS_dec(netObj.ports(1).gatWay4,0) ), 1);% if ~isempty(srcIndex) % if it has a record in arp table destHwA=table2struct(netObj.ARP_Table(srcIndex,2)); destInFaName=table2struct(netObj.ARP_Table(srcIndex,3)); portNum=ismember({netObj.ports.name},destInFaName.interface); pdu.packetDat.destnation= destHwA.hardWareAddress; pdu.packetDat.source= netObj.ports(portNum).mac; netObj.ioControlFlag(5) =1; pdu=linkLayer.ethernet( pdu,netObj); else %arp parameters newPdu.packetDat.SHA=netObj.ports(destIntIndex).mac ; newPdu.packetDat.SPA=pdu.packetDat.sourceIp;%netObj.ports(pInd).mac; newPdu.packetDat.THA=macAddAloc('min');%Target Hardware Address: 00:00:00:00:00:00 as broadcast newPdu.packetDat.TPA=netObj.ports(1).gatWay4;%Target Protocol Address: The IP address of the device this message is being sent to. %ethernet parameters newPdu.packetDat.destnation=macAddAloc('max'); newPdu.packetDat.source= netObj.ports(destIntIndex).mac; %arp proccess netObj.ioControlFlag(5) =1; sentframe=linkLayer.arp(newPdu,netObj); reciveframe=netObj.recBuffer; srcIndex=find(strcmp(netObj.ARP_Table.ipAddress, ip2IpS_dec(netObj.ports(1).gatWay4,0 ) ), 1);% compareIp(char(netObj.ARP_Table.ipAddress),netObj.ports(1).gatWay4) if ~isempty(srcIndex) % if it has a record in arp table destHwA=table2struct(netObj.ARP_Table(srcIndex,2)); destInFaName=table2struct(netObj.ARP_Table(srcIndex,3)); portNum=ismember({netObj.ports.name},destInFaName.interface); pdu.packetDat.destnation= destHwA.hardWareAddress; pdu.packetDat.source= netObj.ports(portNum).mac; netObj.ioControlFlag(5) =1; pdu=linkLayer.ethernet( pdu,netObj); else netObj.ioControlFlag(1)=1; end end end %the below section is used when we want to send an icmp or ... other app message! by router elseif netObj.typeDevice==6 && ~isfield(netObj.ports,'gatWay4') % if frame dont blong to current network and device is a router inUseIntIndex=find([netObj.ports.inUse]==1); netObjIpS={netObj.ports(inUseIntIndex).ip}; validList=isvalidIp(netObjIpS); inUseIntIndex=inUseIntIndex(logical(validList)); netObjIpS={netObj.ports(inUseIntIndex).ip}; portNum=inUseIntIndex(ismember(netObjIpS,pdu.packetDat.sourceIp)); destIps=repmat(pdu.packetDat.destnationIp,1,length(netObjIpS)); subnetMaskS={netObj.ports(inUseIntIndex).subnetMask}; [netObjNetId,netObjSubId,~]=getNet(netObjIpS,subnetMaskS); [destObjNetId,destObjSubId,~]=getNet(destIps,subnetMaskS); destIntIndex=find(ismember(netObjSubId,destObjSubId)); % it is in sebnet, that connect to one of curent device ports srcIndex=find(strcmp(netObj.ARP_Table.ipAddress, ip2IpS_dec(pdu.packetDat.destnationIp,0) ), 1);% if ~isempty(destIntIndex) && ~isempty(srcIndex) % if it has a record in arp table destHwA=table2struct(netObj.ARP_Table(srcIndex,2)); destInFaName=table2struct(netObj.ARP_Table(srcIndex,3)); portNum=ismember({netObj.ports.name},destInFaName.interface); pdu.packetDat.destnation= destHwA.hardWareAddress; pdu.packetDat.source= netObj.ports(portNum).mac; pdu=linkLayer.ethernet( pdu,netObj); else if isempty(srcIndex) %arp parameters newPdu.packetDat.SHA=netObj.ports(portNum).mac ; newPdu.packetDat.SPA=pdu.packetDat.sourceIp;%netObj.ports(pInd).mac; newPdu.packetDat.THA=macAddAloc('min');%Target Hardware Address: 00:00:00:00:00:00 as broadcast newPdu.packetDat.TPA=pdu.packetDat.destnationIp;%Target Protocol Address: The IP address of the device this message is being sent to. %ethernet parameters newPdu.packetDat.destnation=macAddAloc('max'); newPdu.packetDat.source= netObj.ports(portNum).mac;% destnation is a pc connetc to switch ,... %arp proccess netObj.ioControlFlag(5) =1; sentframe=linkLayer.arp(newPdu,netObj); reciveframe=netObj.recBuffer; end srcIndex=find(strcmp(netObj.ARP_Table.ipAddress, ip2IpS_dec(pdu.packetDat.destnationIp,0) ), 1);% if ~isempty(srcIndex) % if it has a record in arp table destHwA=table2struct(netObj.ARP_Table(srcIndex,2)); destInFaName=table2struct(netObj.ARP_Table(srcIndex,3)); portNum=ismember({netObj.ports.name},destInFaName.interface); pdu.packetDat.destnation= destHwA.hardWareAddress; pdu.packetDat.source= netObj.ports(portNum).mac; pdu=linkLayer.ethernet( pdu,netObj); else netObj.ioControlFlag(1)=1; end end else netObj.ioControlFlag(1)=1; end end end function pdu=arp(linkLayer,pdu,netObj) packet.HRD=1;%packetDat.HRD;%defaultt=1, hardware type 1= Ethernet , 6=IEEE 802 Network, 7=ARCNET, 15=Frame Relay, 16= Asynchronous Transfer Mode(ATM, 17= HDLC ,18=Fibr Channel, 20=serialLine packet.PRO=800;%packetDat.PRO;%defaultt=800 as ip4;Protocol Type: This field is the complement of the Hardware Type field, specifying the type of layer three addresses used in the message. For IPv4 addresses, this value is 2048 (0800 hex), which corresponds to the EtherType code for the Internet Protocol. packet.HLN=6;%packetDat.HLN;%defaultt=6 ,Hardware Address Length: Specifies how long hardware addresses are in this message. For Ethernet or other networks using IEEE 802 MAC addresses, the value is 6. packet.PLN=4;%packetDat.PLN;%defaultt=4 ,Protocol Address Length: Again, the complement of the preceding field; specifies how long protocol (layer three) addresses are in this message. For IP(v4) addresses this value is of course 4. packet.OP=1;%defaultt=1 ,op code,1= arp request, 2= arp reply,3=RARP request, 4= RARP reply, 5=DRARP request, 6= DRARP reply,7= DRARP error,8= inARP request,9= inARP reply packet.SHA=pdu.packetDat.SHA;%Sender Hardware Address: The hardware (layer two) address of the device sending this message (which is the IP datagram source device on a request, and the IP datagram destination on a reply, as discussed in the topic on ARP operation). packet.SPA=pdu.packetDat.SPA;%Sender Protocol Address: The IP address of the device sending this message. packet.THA=pdu.packetDat.THA;%Target Hardware Address: The hardware (layer two) address of the device this message is being sent to. This is the IP datagram destination device on a request, and the IP datagram source on a reply) packet.TPA=pdu.packetDat.TPA;%Target Protocol Address: The IP address of the device this message is being sent to. pdu.packetDat.type=806; % as arp pdu.arp=packet; pdu=linkLayer.ethernet(pdu,netObj); end function pdu=ethernet(linkLayer,pdu,netObj) packet.destnation=pdu.packetDat.destnation;%This is 6-Byte field which contains the MAC address of machine for which data is destined. packet.source=pdu.packetDat.source;%his is a 6-Byte field which contains the MAC address of source machine. As Source Address is always an individual address (Unicast), the least significant bit of first byte is always 0. packet.type=pdu.packetDat.type;% typ: arp =806 ,ipV4=800 for most code Go to the refrence 5 at the beginig pdu.ethernet=packet; if netObj.ioControlFlag(5) == 1 netObj.ioControlFlag(5)=0; pdu=rmfield(pdu,'packetDat'); netObj.onSentFram(pdu);% later i control this section for Possible error elseif netObj.ioControlFlag(4) == 1 netObj.ioControlFlag(4)=0; inUseIntIndex=find([netObj.ports.inUse]==1); netObjIpS={netObj.ports(inUseIntIndex).mac}; portNum=find(ismember(netObjIpS,pdu.ethernet.source)); aimPort=netObj.ports(portNum).outport; aimObj=netObj.ports(portNum).outObj; if aimObj.sendListener{aimPort}.Enabled==0 aimObj.sendListener{aimPort}.Enabled=1; end conLine.x={[netObj.pos.X,aimObj.pos.X]}; conLine.y={[netObj.pos.Y,aimObj.pos.Y]}; pdu=rmfield(pdu,'packetDat'); uniCast(netObj,aimObj,pdu,conLine,portNum) %unicast end end end methods % help Functions function [aimObj,aimPor,conLine]=netObjectFinder(linkLayer,netObj,dstIndex) portNum=find(strcmp({netObj.ports.name},netObj.MAC_Table(dstIndex,end).port)); connectLine=[netObj.connectLine{:}]; conObjects= [connectLine.conObjects] ; thisIndex=[]; thatIndex=[]; conPorts=cell2mat([connectLine.conPorts]); for conL=1:length(conObjects) if conObjects{conL}.typeDevice==netObj.typeDevice thisIndex=[thisIndex,conL]; else thatIndex=[thatIndex,conL]; end end thisport= conPorts(thisIndex); aimPortIndex= find(thisport==portNum); aimObj= conObjects{thatIndex(aimPortIndex)}; aimPor=conPorts(thatIndex(aimPortIndex)); aimLine=connectLine(aimPortIndex); conLine.x= aimLine.handles(1).XData ; conLine.y= aimLine.handles(1).YData ; if thatIndex(aimPortIndex)< thisIndex(aimPortIndex) conLine.x=flip(conLine.x); conLine.y=flip(conLine.y); end conLine.x={ conLine.x}; conLine.y={ conLine.y}; end end end