-
Notifications
You must be signed in to change notification settings - Fork 474
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Generation of Custom LLDP packet #230
Comments
Just create an instance of organizationally_specific. Then set the If I recall correctly, getting discovery to send additional TLVs should be as simple as appending them to the list with the other TLVs: https://github.com/MurphyMc/pox/blob/fangtooth/pox/openflow/discovery.py#L194 However, I think the current version pre-generates the LLDP messages and recycles them. If you want a fresh timestamp, you'll need to generate them on the fly instead. The current pre-generation is done in add_port(); it calls create_packet_out() to do the actual packet generation, wraps the resulting packet in a SendItem() and then adds it to the list of packets to send each cycle. I think the easiest fix is to have the SendItem() contain the tuple (dpid, port_num, port_addr) instead of the packet. Then when sending (in _timer_handler()), use those as parameters to create_packet_out() then. Then you'll want to modify the PacketIn handler: I think you'll want to iterate through the list of TLVs looking for ones of tlv_type==ORGANIZATIONALLY_SPECIFIC_TLV. When you find one, check if it's got your OUI and subtype. If so, parse its |
SHould it be done in the Discovery.py or the lldp.py |
Hello Murphy,
I am new to pox but know about SDN and currently carrying out research in
SDN could get me a simple code snippet to find a solution
…On Tue, Oct 22, 2019 at 10:29 AM Murphy ***@***.***> wrote:
Just create an instance of organizationally_specific. Then set the .oui
and possibly the .subtype to something that identifies you (e.g., your
organization's OUI) and your custom type. Then set the .payload to a
random UUID and timestamp however you want to do that. For example, you
could make it human-readable and just make payload a string containing
"{uuid...} timestamp". I think that's all there is to it.
If I recall correctly, getting discovery to send additional TLVs should be
as simple as appending them to the list with the other TLVs:
https://github.com/MurphyMc/pox/blob/fangtooth/pox/openflow/discovery.py#L194
However, I think the current version pre-generates the LLDP messages and
recycles them. If you want a *fresh* timestamp, you'll need to generate
them on the fly instead. The current pre-generation is done in add_port();
it calls create_packet_out() to do the actual packet generation, wraps the
resulting packet in a SendItem() and then adds it to the list of packets to
send each cycle. I think the easiest fix is to have the SendItem() contain
the tuple (dpid, port_num, port_addr) instead of the packet. Then when
sending (in _timer_handler()), use those as parameters to
create_packet_out() *then*.
Then you'll want to modify the PacketIn handler:
https://github.com/MurphyMc/pox/blob/fangtooth/pox/openflow/discovery.py#L342
I think you'll want to iterate through the list of TLVs looking for ones
of tlv_type==ORGANIZATIONALLY_SPECIFIC_TLV. When you find one, check if
it's got your OUI and subtype. If so, parse its .payload.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#230?email_source=notifications&email_token=ABYIRWTSY5OKCYDFS2PLTQ3QP2TW5A5CNFSM4JC4UFG2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEB4ZKIY#issuecomment-544838947>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABYIRWVXDQOR6QIUMSL4D7DQP2TW5ANCNFSM4JC4UFGQ>
.
--
*Joseph Katongole*
*UNIX Systems Engineer*
*+256392944768*
|
It's probably hard to alter discovery's behavior this way via subclassing, so certainly the easiest thing to do is to just hack up discovery.py. 'keilo' isn't a valid OUI. It is a 24 bit number (encoded as a string/bytes) which is acquired from IEEE. See the wikipedia article. In discovery.py around line 194 (https://github.com/MurphyMc/pox/blob/fangtooth/pox/openflow/discovery.py#L194), you'd do something like...
Then in _handle_openflow_PacketIn() probably right before the end (https://github.com/MurphyMc/pox/blob/fangtooth/pox/openflow/discovery.py#L467), you'd want to look for your custom TLV and do something with it...
I haven't tested any of that at all, but hopefully it will get you started. The timestamps will only be generated once, so if you want new ones with every packet, refer to my post above where I suggest a modification to have it generate new ones. (But I'd do that after you get the simple case working first.) |
This good atleast i can get the added tlv in the packet in message.
Because certain actions have to follow. before the link is created let me make some modifications i will let you know how it goes ` |
I did add the code to the discovery.py file just before a link is created the validation of the custom tlv should be done. so i decided to add this information right before the link event is called to detect a link.
` |
Hello @murphy its just not working as expected maybe we could go through the code together. My email is [email protected] would like to contact you so we can discuss more about it |
This piece of code finally worked and the packet information if first verified before the link is detected and created. Maybe now this should be dynamically created but it is working as expected
` |
only problem is ensuring the oui really matches checked through the lldp.py and the oui and subtype are transmitted as binary struct format together. `INFO:openflow.of_01:[00-00-00-00-00-02 3] connected ` the if statement is matching for any value of the oui |
Shouldn't that be an OR and not an AND? |
I think it should be an AND because both conditions must be satisfied for the data to be valid |
Exactly. But the line is using != instead of ==, so it's actually checking for the cases which are not valid. And it's not valid if either case is not valid, thus OR instead of AND. (One way to think of this is that it's an application of De Morgan's law.) |
@MurphyMc what are some of the characteristics that can be added to an LLDP packet to make it unique enough that we can assume it has been crafted i would like to build a model that i can adopt and use deep learning to be able to decided whether or not a link has been fabricated. |
The idea being that you want to be able to tell if an attacker is trying to convince the controller that the topology is different than it actually is? It's relatively easy to make sure that a packet is one that the controller itself generated. Put a nonce in it and have the controller verify it, or digitally sign it, for example. But there's nothing that stops an attacker with good positioning from taking an LLDP packet from one place and playing it back somewhere else except like... latency measurements, maybe. You need to actually secure your topology somehow for this. One way would be filtering such that hosts can't send/read LLDP, but that assumes you at least know where hosts attach. In my opinion, this is reasonable, but I don't really believe in ongoing automatic topology discovery for most scenarios to begin with. |
Exactly thats the idea that an attacker should not convince the controller that the topology is different. This is the idea. |
I'm pretty skeptical of any approach that uses automatic topology discovery. This probably makes me a bad person to ask, since my first answer is generally going to be "Don't do that." It really helps to have ground truth which discovery can't provide. For example, any host tracking service is susceptible to attack too. If you can fake not being a host, then you can fake being a link. My typical answer is that administrator configuration and physical security provides this, and that in the absence of administrator configuration and physical security, you can't really expect much. But my email address is in all of my commits. |
Here is my challenge trying to administratively manage the link detection
as we had earlier discussed but i realised i need to have some external
script to be able to add and delete links from the flow table. After the
packet-in message has been received at what point does the controller
decide to let traffic through that link detected link. Plus i need to
intercept the link creation so i can collect the links and be able to
choose which links to add and which links not to add.
Is this a good approach?
…On Mon, Nov 4, 2019 at 5:54 PM Murphy ***@***.***> wrote:
I'm pretty skeptical of any approach that uses automatic topology
discovery. This probably makes me a bad person to ask, since my first
answer is generally going to be "Don't do that." It really helps to have
ground truth which discovery can't provide. For example, any host tracking
service is susceptible to attack too. If you can fake not being a host,
then you can fake being a link. My typical answer is that administrator
configuration and physical security provides this, and that in the absence
of administrator configuration and physical security, you can't really
expect much.
But my email address is in all of my commits.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#230?email_source=notifications&email_token=ABYIRWWAK2ZOVWOEH47V7ODQSAZT5A5CNFSM4JC4UFG2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEC7QVAI#issuecomment-549390977>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABYIRWTQTRAK7JQOJTYXPXTQSAZT5ANCNFSM4JC4UFGQ>
.
--
*Joseph Katongole*
*UNIX Systems Engineer*
*+256392944768*
|
None of this sounds like it needs to be external. It sounds like you could write it as a POX component. If you did want to write it to be external, POX has various things that may help with this or at least could be starting points. For example, the messenger service, the OpenFlow webservice component, etc. As for what point after a packet-in message has been received does the controller let traffic through... this is really up to you. In l2_learning, for example, it happens immediately. For the proactive ones, it doesn't get a packet-in at all. |
@MurphyMc please break it down for me clearly. i am thinking as we had discussed of administratively managing these links. ie does that mean we are dealing away with LLDP packets ? |
Hello @MurphyMc what do you think about the previous post? |
does the manual/administrative procedure eliminate the need for LLDP packets |
It's up to you. If you actually know the topology ahead of time, there's no need. If you want to discover the topology then you still need LLDP (or the equivalent), and the difference is just that you have to approve a link before using it. |
oh i get it. lets take a scenario where i have to discover the topology. My question was at what point do i get to approve this link? how interactively would this approval be. ie i am talking about the discovery.py where the topology discovery happens. how would intercept to approve the links? thats i think that part i needed to look deeper. think mostly the part holding me back a bit |
looking at how to actually interact with an already running controller |
I think the cleanest thing would be to modify/build the forwarding application around the idea. For example, take topo_proactive. That part of the code is triggered by a discovery link event and updates topo_proactive's data structures and computes paths. You could just rewrite this so that instead of being triggered directly by a discovery event, it's triggered by an approval event, managed by some approval component (which itself probably consumes discovery events). |
okay sure does pox have some api i can work with to be able to interact with the controller? i am looking at how to externally send the approval event |
Many. First off, it's just Python. You could integrate whatever you wanted. Like RPyC, for example. POX also has its web module, based on Python's web stuff, so it's got built in support for writing web interfaces. POX has a JSON-RPC module built using the above which can easily be used to expose functionality by JSON-RPC. The OpenFlow webservice is an example. Then there's the messenger, which is a flexible system for building external interfaces to POX. Among other things, this has been used as the underlying technology behind POXDesk. The messenger can use multiple different "transports". One thing which should be a transport but hasn't been integrated yet is POX's relatively recent support for websockets. But one could use that "raw" instead of as part of messenger. |
Hello Murphy Process Flow New Links
New links with old links
What do you think about this process flow. What how would i store these already created links |
Hello @MurphyMc secondly in this case what events am i going to look out for in this case. here is the scenario as earlier discussed. at the beginning of discovery, first time the links are detected, intervention happens to accept the links. This is probably a link event secondly. earliler we had also talked about modification of the lldp packet, this is probably handling the packet out even. Please let me know what you think and how we can go about it |
The i am trying to create a custom LLPD packet by adding my own organisationally_specific TLV field.
`
class organizationally_specific (simple_tlv):
tlv_type = lldp.ORGANIZATIONALLY_SPECIFIC_TLV
def _init (self, kw):
self.oui = '\x00\x00\x00'
self.subtype = 0
self.payload = b''
def _parse_data (self, data):
(self.oui,self.subtype) = struct.unpack("3sB", data[0:4])
self.payload = data[4:]
def _pack_data (self):
return struct.pack('!3sB', self.oui, self.subtype) + self.payload
My field just has a random UUID and a TIMESTAMP. what code changes should be done to be able to add these custom tlvs plus the <discovery.py > such that the added tlvs can be sent out in the packet out message during the discovery process.
def create_packet_out (self, dpid, port_num, port_addr):
"""
Create an ofp_packet_out containing a discovery packet
"""
eth = self._create_discovery_packet(dpid, port_num, port_addr, self._ttl)
po = of.ofp_packet_out(action = of.ofp_action_output(port=port_num))
po.data = eth.pack()
return po.pack()
@staticmethod
def _create_discovery_packet (dpid, port_num, port_addr, ttl):
"""
Build discovery packet
"""
`
The text was updated successfully, but these errors were encountered: