├── DashSharp
├── FodyWeavers.xml
├── Models
│ ├── DashListenerResponse.cs
│ └── DashResponse.cs
├── packages.config
├── Exceptions
│ └── PcapMissingException.cs
├── Properties
│ └── AssemblyInfo.cs
├── Network
│ └── DashNetwork.cs
└── DashSharp.csproj
├── DashExample
├── App.config
├── Properties
│ └── AssemblyInfo.cs
├── Program.cs
└── DashExample.csproj
├── DashSharp.sln
├── README.md
└── .gitignore
/DashSharp/FodyWeavers.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/DashExample/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/DashSharp/Models/DashListenerResponse.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace DashSharp.Models
8 | {
9 | public class DashListenerResponse : EventArgs
10 | {
11 | public bool Started { get; set; }
12 | public string Message { get; set; }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/DashSharp/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/DashSharp/Models/DashResponse.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Net.NetworkInformation;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace DashSharp.Models
9 | {
10 | public class DashResponse : EventArgs
11 | {
12 | public string DashMac { get; set; }
13 | public int DashId { get; set; }
14 | public string Device { get; set; }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/DashSharp/Exceptions/PcapMissingException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace DashSharp.Exceptions
4 | {
5 | public class PcapMissingException : Exception
6 | {
7 | public PcapMissingException()
8 | {
9 | }
10 |
11 | public PcapMissingException(string message)
12 | : base(message)
13 | {
14 | }
15 |
16 | public PcapMissingException(string format, params object[] args)
17 | : base(string.Format(format, args))
18 | {
19 | }
20 |
21 | public PcapMissingException(string message, Exception innerException)
22 | : base(message, innerException)
23 | {
24 | }
25 |
26 | public PcapMissingException(string format, Exception innerException, params object[] args)
27 | : base(string.Format(format, args), innerException)
28 | {
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/DashSharp.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.24720.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DashSharp", "DashSharp\DashSharp.csproj", "{0F2C32A0-ABB8-4734-9C34-3C059C42835F}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DashExample", "DashExample\DashExample.csproj", "{A6F544CB-B685-4897-A067-F23246D059BF}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Any CPU = Debug|Any CPU
13 | Release|Any CPU = Release|Any CPU
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {0F2C32A0-ABB8-4734-9C34-3C059C42835F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17 | {0F2C32A0-ABB8-4734-9C34-3C059C42835F}.Debug|Any CPU.Build.0 = Debug|Any CPU
18 | {0F2C32A0-ABB8-4734-9C34-3C059C42835F}.Release|Any CPU.ActiveCfg = Release|Any CPU
19 | {0F2C32A0-ABB8-4734-9C34-3C059C42835F}.Release|Any CPU.Build.0 = Release|Any CPU
20 | {A6F544CB-B685-4897-A067-F23246D059BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {A6F544CB-B685-4897-A067-F23246D059BF}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {A6F544CB-B685-4897-A067-F23246D059BF}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | {A6F544CB-B685-4897-A067-F23246D059BF}.Release|Any CPU.Build.0 = Release|Any CPU
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | EndGlobal
29 |
--------------------------------------------------------------------------------
/DashSharp/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("DashSharp")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("DashSharp")]
13 | [assembly: AssemblyCopyright("Copyright © 2016")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("0f2c32a0-abb8-4734-9c34-3c059c42835f")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/DashExample/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("DashExample")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("DashExample")]
13 | [assembly: AssemblyCopyright("Copyright © 2016")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("a6f544cb-b685-4897-a067-f23246d059bf")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/DashExample/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using DashSharp;
7 | using DashSharp.Exceptions;
8 | using DashSharp.Models;
9 |
10 | namespace DashExample
11 | {
12 | class Program
13 | {
14 |
15 | private static void Main(string[] args)
16 | {
17 | Console.Title = "DashSharp - Amazon Dash Button";
18 | Console.WriteLine("Dash Buttons have two MAC addresses, their wakeup and their pair. The last one you receive is the pair address. ");
19 | var network = new DashNetwork();
20 | network.ListenerStarted += network_ListenerStarted;
21 | network.DashButtonProbed += network_DashProbed;
22 | try
23 | {
24 | network.StartListening();
25 | }
26 | catch (PcapMissingException)
27 | {
28 | Console.WriteLine("No Pcap is missing, please install it.");
29 | }
30 | Console.Read();
31 | }
32 |
33 | private static void network_DashProbed(object sender, EventArgs e)
34 | {
35 | var probe = (DashResponse)e;
36 | Console.WriteLine("Amazon Dash Connected: " + probe.DashMac + " seen on " + probe.Device);
37 |
38 | }
39 |
40 | private static void network_ListenerStarted(object sender, EventArgs e)
41 | {
42 | Console.WriteLine(((DashListenerResponse)e).Message);
43 | }
44 | }
45 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # DashSharp
2 | A C# Library to handle your amazon dash probing to execute custom actions.
3 |
4 | ### How does it work?
5 |
6 | When an Amazon Dash Button wakes up after being pushed, it introduces itself to the network via a small probe. By simply capturing this probe and raising some events, we can turn our dash button into our own internet of things device.
7 |
8 | ### How to set it up.
9 |
10 | Follow the setup steps provided by Amazon, once you reach step 3 (selecting an item you want the dash to purchase), exit the app and uninstall it (it will bomb you with notifications otherwise)
11 |
12 | Once the Dash Button has been connected to your wifi, any computer on your network can see it when it wakes up. By using this library you can write an application to handle it.
13 |
14 |
15 | ### Hello World
16 |
17 | Using the library is easy
18 |
19 | ```csharp
20 | private static void Main(string[] args)
21 | {
22 | Console.Title = "DashSharp - Amazon Dash Button";
23 | var network = new DashNetwork();
24 | network.ListenerStarted += network_ListenerStarted;
25 | network.DashButtonProbed += network_DashProbed;
26 | try
27 | {
28 | network.StartListening();
29 | }
30 | catch (PcapMissingException)
31 | {
32 | Console.WriteLine("Pcap is missing, please install it.");
33 | }
34 | Console.Read();
35 | }
36 | ```
37 |
38 | ### Multiple physical addresses
39 |
40 | Dash Buttons have two physical addresses, one for when they are waking up/pressed and the other for their sync attempt/shutting down. This library monitors for them, you have to handle the logic.
41 |
42 | ### Requirements
43 |
44 | You'll neeed [WinPcap](https://www.winpcap.org/) on Windows and Pcap on Linux or OSX.
45 |
46 | ### Running code on your dash
47 |
48 | An interesting write up can be found [here](http://www.networkworld.com/article/2994131/internet-of-things/inside-the-amazon-dash-button-hack-and-how-to-make-it-useful.html)
49 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Build Folders (you can keep bin if you'd like, to store dlls and pdbs)
2 | [Bb]in/
3 | [Oo]bj/
4 |
5 | # mstest test results
6 | TestResults
7 |
8 | ## Ignore Visual Studio temporary files, build results, and
9 | ## files generated by popular Visual Studio add-ons.
10 |
11 | # User-specific files
12 | *.suo
13 | *.user
14 | *.sln.docstates
15 | *.userprefs
16 |
17 | # Build results
18 | [Dd]ebug/
19 | [Rr]elease/
20 | x64/
21 | *_i.c
22 | *_p.c
23 | *.ilk
24 | *.meta
25 | *.obj
26 | *.pch
27 | *.pdb
28 | *.pgc
29 | *.pgd
30 | *.rsp
31 | *.sbr
32 | *.tlb
33 | *.tli
34 | *.tlh
35 | *.tmp
36 | *.log
37 | *.vspscc
38 | *.vssscc
39 | .builds
40 |
41 | # Visual C++ cache files
42 | ipch/
43 | *.aps
44 | *.ncb
45 | *.opensdf
46 | *.sdf
47 |
48 | # Visual Studio profiler
49 | *.psess
50 | *.vsp
51 | *.vspx
52 |
53 | # Guidance Automation Toolkit
54 | *.gpState
55 |
56 | # ReSharper is a .NET coding add-in
57 | _ReSharper*
58 |
59 | # NCrunch
60 | *.ncrunch*
61 | .*crunch*.local.xml
62 |
63 | # Installshield output folder
64 | [Ee]xpress
65 |
66 | # DocProject is a documentation generator add-in
67 | DocProject/buildhelp/
68 | DocProject/Help/*.HxT
69 | DocProject/Help/*.HxC
70 | DocProject/Help/*.hhc
71 | DocProject/Help/*.hhk
72 | DocProject/Help/*.hhp
73 | DocProject/Help/Html2
74 | DocProject/Help/html
75 |
76 | # Click-Once directory
77 | publish
78 |
79 | # Publish Web Output
80 | *.Publish.xml
81 |
82 | # NuGet Packages Directory
83 | packages
84 |
85 | # Windows Azure Build Output
86 | csx
87 | *.build.csdef
88 |
89 | # Windows Store app package directory
90 | AppPackages/
91 |
92 | # Others
93 | [Bb]in
94 | [Oo]bj
95 | sql
96 | TestResults
97 | [Tt]est[Rr]esult*
98 | *.Cache
99 | ClientBin
100 | [Ss]tyle[Cc]op.*
101 | ~$*
102 | *.dbmdl
103 | Generated_Code #added for RIA/Silverlight projects
104 |
105 | # Backup & report files from converting an old project file to a newer
106 | # Visual Studio version. Backup files are not needed, because we have git ;-)
107 | _UpgradeReport_Files/
108 | Backup*/
109 | UpgradeLog*.XML
110 |
111 | Installer/*setup.exe
112 |
--------------------------------------------------------------------------------
/DashSharp/Network/DashNetwork.cs:
--------------------------------------------------------------------------------
1 | #region
2 |
3 | using System;
4 | using DashSharp.Exceptions;
5 | using DashSharp.Models;
6 | using PacketDotNet;
7 | using SharpPcap;
8 |
9 | #endregion
10 |
11 | namespace DashSharp
12 | {
13 | public class DashNetwork
14 | {
15 | private const int ReadTimeoutMilliseconds = 1000;
16 | public event EventHandler ListenerStarted;
17 | public event EventHandler DashButtonProbed;
18 |
19 |
20 | public void StartListening()
21 | {
22 | // Retrieve the device list
23 | try
24 | {
25 | var devices = CaptureDeviceList.Instance;
26 | if (devices.Count < 1)
27 | {
28 | throw new PcapMissingException("No interfaces found! Make sure WinPcap is installed.");
29 | }
30 | foreach (var device in devices)
31 | {
32 | if (device == null) continue;
33 | device.OnPacketArrival += delegate(object sender, CaptureEventArgs e)
34 | {
35 | var packet = Packet.ParsePacket(e.Packet.LinkLayerType, e.Packet.Data);
36 | var eth = (EthernetPacket) packet;
37 | var dashMac = eth.SourceHwAddress.ToString();
38 | if (dashMac.Equals(device.MacAddress.ToString()))
39 | {
40 | //ignore packets from our own device
41 | return;
42 | }
43 | var dashId = dashMac.GetHashCode();
44 |
45 | DashButtonProbed?.Invoke(this,
46 | new DashResponse
47 | {
48 | DashMac = dashMac,
49 | DashId = dashId,
50 | Device = device.MacAddress.ToString()
51 | });
52 | };
53 | device.Open(DeviceMode.Promiscuous, ReadTimeoutMilliseconds);
54 | // tcpdump filter to capture only ARP Packets
55 | device.Filter = "arp";
56 | Action action = device.Capture;
57 | action.BeginInvoke(ar => action.EndInvoke(ar), null);
58 | ListenerStarted?.Invoke(this,
59 | new DashListenerResponse
60 | {
61 | Started = true,
62 | Message = $"Started listenr on {device.MacAddress}"
63 | });
64 | }
65 | }
66 | catch (Exception)
67 | {
68 | throw new PcapMissingException("No interfaces found! Make sure WinPcap is installed.");
69 | }
70 | }
71 | }
72 | }
--------------------------------------------------------------------------------
/DashExample/DashExample.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {A6F544CB-B685-4897-A067-F23246D059BF}
8 | Exe
9 | Properties
10 | DashExample
11 | DashExample
12 | v4.5.2
13 | 512
14 | true
15 |
16 |
17 | AnyCPU
18 | true
19 | full
20 | false
21 | bin\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 |
26 |
27 | AnyCPU
28 | pdbonly
29 | true
30 | bin\Release\
31 | TRACE
32 | prompt
33 | 4
34 |
35 |
36 |
37 | ..\DashSharp\bin\Debug\DashSharp.dll
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
63 |
--------------------------------------------------------------------------------
/DashSharp/DashSharp.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {0F2C32A0-ABB8-4734-9C34-3C059C42835F}
8 | Library
9 | Properties
10 | DashSharp
11 | DashSharp
12 | v4.5.2
13 | 512
14 |
15 |
16 |
17 |
18 | true
19 | full
20 | false
21 | bin\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 | AnyCPU
26 |
27 |
28 | pdbonly
29 | true
30 | bin\Release\
31 | TRACE
32 | prompt
33 | 4
34 | AnyCPU
35 |
36 |
37 |
38 | ..\packages\PacketDotNet.0.13.0\lib\net\PacketDotNet.dll
39 | True
40 |
41 |
42 | ..\packages\SharpPcap.4.2.0\lib\net\SharpPcap.dll
43 | True
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 | ();
86 | var attribute = config.Attribute("ExcludeAssemblies");
87 | if (attribute != null)
88 | foreach (var item in attribute.Value.Split('|').Select(x => x.Trim()).Where(x => x != string.Empty))
89 | excludedAssemblies.Add(item);
90 | var element = config.Element("ExcludeAssemblies");
91 | if (element != null)
92 | foreach (var item in element.Value.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()).Where(x => x != string.Empty))
93 | excludedAssemblies.Add(item);
94 |
95 | var filesToCleanup = Files.Select(f => f.ItemSpec).Where(f => !excludedAssemblies.Contains(Path.GetFileNameWithoutExtension(f), StringComparer.InvariantCultureIgnoreCase));
96 |
97 | foreach (var item in filesToCleanup)
98 | File.Delete(item);
99 | ]]>
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
109 |
110 |
111 |
112 |
119 |
--------------------------------------------------------------------------------