seemoo-lab/owl

AirPlay can't connect

Opened this issue · 17 comments

Now,owl project is successfully i use my mdns project connect with owl ,i want to establish a socket connection but faild

image

AirPlay is not supported over OWL, as it requires the service discovery mechanism, as well as certain modifications to the DataPathStateTLV.

Do you know how I can modify the DataPathStateTLV to support airplay?

This is the code in my library, which parses the flags.

bitfield! {
    #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
    pub struct DataPathFlags: u16 {
        pub infra_bssid_channel: bool => bit!(0),
        pub infra_address: bool => bit!(1),
        pub awdl_address: bool => bit!(2),
        pub is_umi: bool => bit!(4),
        pub dualband_support: bool => bit!(5),
        pub airplay_sink: bool => bit!(6),
        pub follow_channel_sequence: bool => bit!(7),
        pub country_code: bool => bit!(8),
        pub channel_map: bool => bit!(9),
        pub airplay_solo_mode: bool => bit!(10),
        pub umi_support: bool => bit!(11),
        pub unicast_options: bool => bit!(12),
        pub is_realtime: bool => bit!(13),
        pub rangeable: bool => bit!(14),
        pub extension_flags: bool => bit!(15)
    }
}

However, my current understanding is, that AirPlay requires more than the data path state tlv, namely unicast master indication frames. I'm afraid, that this would be a major change to OWL. I'm also uncertain, if the bandwidth currently provided by OWL is sufficient, since it's capped at 12 Mbit/s through the data rate set in the radiotap header.

I'm currently working on an alternative to OWL written in rust, since there isn't much activity on this repo anymore and there is still room for improvement. Until it's en par with OWL, it will probably take some time, since up until now I'm just working on parser infrastructure for reading the frames. My ultimate goal is to support SD and UMIs too.

I now try to send dns service information to the awdl0 network port. The Mac computer can find the Airplay service, but it fails when I click to connect. I used the netcat tool to test and found that a socket connection can be established through the awdl0 interface. So it feels strange.

Could you try monitoring the connection with wireshark?

I cannot capture the tcp sync during the connection through wireshark, but I can capture the udp packet of mdns.

What I meant, was capturing the packets send over the wireless interface, you set OWL to use. i.e. The monitoring interface.

awdl0 is the virtual node generated after starting owl

When you say the node where wireshark captures packets, you mean the node generated by owl, right?

This is the code in my library, which parses the flags.

bitfield! {
    #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
    pub struct DataPathFlags: u16 {
        pub infra_bssid_channel: bool => bit!(0),
        pub infra_address: bool => bit!(1),
        pub awdl_address: bool => bit!(2),
        pub is_umi: bool => bit!(4),
        pub dualband_support: bool => bit!(5),
        pub airplay_sink: bool => bit!(6),
        pub follow_channel_sequence: bool => bit!(7),
        pub country_code: bool => bit!(8),
        pub channel_map: bool => bit!(9),
        pub airplay_solo_mode: bool => bit!(10),
        pub umi_support: bool => bit!(11),
        pub unicast_options: bool => bit!(12),
        pub is_realtime: bool => bit!(13),
        pub rangeable: bool => bit!(14),
        pub extension_flags: bool => bit!(15)
    }
}

However, my current understanding is, that AirPlay requires more than the data path state tlv, namely unicast master indication frames. I'm afraid, that this would be a major change to OWL. I'm also uncertain, if the bandwidth currently provided by OWL is sufficient, since it's capped at 12 Mbit/s through the data rate set in the radiotap header.

Can you explain what the fields here mean? Especially airplay_sink

AirPlay sink indicates, that airplaying to this peer is supported.

Can you tell me if there are any other meanings?

owl turned out to be like this:
struct awdl_data_path_state_tlv {
uint8_t type;
uint16_t length;
uint16_t flags;
char country_code[3];
uint16_t social_channels;
struct ether_addr awdl_addr;
uint16_t ext_flags;
/* uint32_t logtrigger_id; if (ext_flags | 0x4) */
} attribute((packed));
Do you want to replace it with the DataPath format you sent?

owl turned out to be like this:
struct awdl_data_path_state_tlv {
uint8_t type;
uint16_t length;
uint16_t flags;
char country_code[3];
uint16_t social_channels;
struct ether_addr awdl_addr;
uint16_t ext_flags;
/* uint32_t logtrigger_id; if (ext_flags | 0x4) */
} attribute((packed));
Do you want to replace it with the DataPath format you sent?

Apply this patch two owl and it should work.

diff --git a/src/tx.c b/src/tx.c
index d72d7ff..a12b446 100644
--- a/src/tx.c
+++ b/src/tx.c
@@ -247,7 +247,7 @@ int awdl_init_data_path_state_tlv(uint8_t *buf, const struct awdl_state *state)
 	tlv->length = htole16(sizeof(struct awdl_data_path_state_tlv) - sizeof(struct tl));
 
 	/* TODO this is very ugly currently */
-	tlv->flags = htole16(0x8f24);
+	tlv->flags = htole16(0x8f64);
 
 	tlv->awdl_addr = state->self_address;
 

I don't have my hardware on me right now to test it, so let me know if it works.