TCPDump (Linux) to WireShark (Windows)

Share your advanced PureBasic knowledge/code with the community.
infratec
Always Here
Always Here
Posts: 7620
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

TCPDump (Linux) to WireShark (Windows)

Post by infratec »

Hi,

since I'm a 'networker' I sometimes need to sniff in some packets :mrgreen:

But most of our linux servers have no X and we don't want that additional stuff.
tcpdump is not really friendly to read what's inside the packets, so I wrote a small tool which:

1. Start tcpdump on a linux PC
2. redirect the output to WireShark on a windows PC

What you need:

Linux: tcpdump and sshd
Windows: PuTTY (PLink) and WireShark

If you have a non common ssh port (like on ipcop) you can use a syntax like this:
192.168.0.254:8022

Save it as TCPDump2WireShark.pb (only as example).

Code: Select all

EnableExplicit

#Version$ = "0.01"


Enumeration
  #Main_Window
  #Config_Window
EndEnumeration

Enumeration
  #MenuConfig
  #MenuExit
EndEnumeration

Enumeration
  #Main_RemoteText
  #Main_RemoteString
  #Main_UserText
  #Main_UserString
  #Main_PasswordText
  #Main_PasswordString
  #Main_FilterText
  #Main_FilterString
  #Main_InterfaceText
  #Main_InterfaceString
  #Main_ExecuteButton
  
  #Config_PLinkText
  #Config_PLinkString
  #Config_PLinkButton
  #Config_WiresharkText
  #Config_WiresharkString
  #Config_WiresharkButton
  #Config_OkButton
  #Config_CancelButton
EndEnumeration


Structure ProgInfoStructure
  ProgPath$
  ProgFilename$
  PLink$
  Wireshark$
  User$
  Password$
  Remote$
  Port$
  Filter$
  Device$
EndStructure



Define.i Exit, Event, PLink, Wireshark, AvailableData, StartTime, Pos
Define Parameter$, Error$, Help$
Define *Buffer
Define ProgInfo.ProgInfoStructure


ProgInfo\ProgPath$ = GetPathPart(ProgramFilename())
ProgInfo\ProgFilename$ = GetFilePart(ProgramFilename(), #PB_FileSystem_NoExtension)

OpenPreferences(ProgInfo\ProgPath$ + ProgInfo\ProgFilename$ + ".ini")
ProgInfo\PLink$ = ReadPreferenceString("PLink", "")
ProgInfo\Wireshark$ = ReadPreferenceString("Wireshark", "")
ProgInfo\Remote$ = ReadPreferenceString("LastRemote", "")
ProgInfo\User$ = ReadPreferenceString("LastUser", "root")
ProgInfo\Device$ = ReadPreferenceString("LastInterface", "eth0")
ProgInfo\Filter$ = ReadPreferenceString("LastFilter", "")
ClosePreferences()

OpenWindow(#Main_Window, 0, 0, 290, 300, "TCPDump to Wireshark V" + #Version$, #PB_Window_SystemMenu|#PB_Window_ScreenCentered)

If CreateMenu(0, WindowID(#Main_Window))
  MenuTitle("File")
  MenuItem(#MenuConfig, "Config")
  MenuBar()
  MenuItem(#MenuExit, "Exit")
EndIf

TextGadget(#Main_RemoteText, 10, 20, 80, 20, "Remote:", #PB_Text_Right)
StringGadget(#Main_RemoteString, 100, 20, 150, 20, ProgInfo\Remote$)

TextGadget(#Main_UserText, 10, 50, 80, 20, "User:", #PB_Text_Right)
StringGadget(#Main_UserString, 100, 50, 150, 20, ProgInfo\User$)

TextGadget(#Main_PasswordText, 10, 80, 80, 20, "Password:", #PB_Text_Right)
StringGadget(#Main_PasswordString, 100, 80, 150, 20, "", #PB_String_Password)

TextGadget(#Main_InterfaceText, 10, 110, 80, 20, "Interface:", #PB_Text_Right)
StringGadget(#Main_InterfaceString, 100, 110, 150, 20, ProgInfo\Device$)

TextGadget(#Main_FilterText, 10, 140, 80, 20, "Filter:", #PB_Text_Right)
StringGadget(#Main_FilterString, 100, 140, 150, 20, ProgInfo\Filter$)

ButtonGadget(#Main_ExecuteButton, 30, 200, 220, 40, "Start Wireshark")

PostEvent(#PB_Event_Gadget, #Main_Window, -1)

If FileSize(ProgInfo\PLink$) <= 0 Or FileSize(ProgInfo\Wireshark$) <= 0
  PostEvent(#PB_Event_Menu, #Main_Window, #MenuConfig)
EndIf


Repeat
  
  Event = WaitWindowEvent()
  
  Select EventWindow()
    Case #Main_Window
      Select Event
        Case #PB_Event_Menu
          Select EventMenu()
            Case #MenuConfig
              OpenWindow(#Config_Window, 0, 0, 400, 180, "Config", #PB_Window_SystemMenu|#PB_Window_WindowCentered, WindowID(#Main_Window))
              
              TextGadget(#Config_PLinkText, 10, 10, 60, 20, "PLink:", #PB_Text_Right)
              StringGadget(#Config_PLinkString, 80, 10, 270, 20, ProgInfo\PLink$)
              ButtonGadget(#Config_PLinkButton, 360, 10, 30, 20, "...")
              
              TextGadget(#Config_WiresharkText, 10, 40, 60, 20, "Wireshark:", #PB_Text_Right)
              StringGadget(#Config_WiresharkString, 80, 40, 270, 20, ProgInfo\Wireshark$)
              ButtonGadget(#Config_WiresharkButton, 360, 40, 30, 20, "...")
              
              ButtonGadget(#Config_OkButton, 110, 100, 80, 30, "Ok")
              ButtonGadget(#Config_CancelButton, 210, 100, 80, 30, "Cancel")
              
            Case #MenuExit
              Exit = #True
              
          EndSelect
          
        Case #PB_Event_Gadget
          Select EventGadget()
            Case #Main_ExecuteButton
              
              ProgInfo\User$ = GetGadgetText(#Main_UserString)
              ProgInfo\Password$ = GetGadgetText(#Main_PasswordString)
              ProgInfo\Port$ = "22"
              ProgInfo\Remote$ = GetGadgetText(#Main_RemoteString)
              Pos = FindString(ProgInfo\Remote$, ":")
              If Pos
                ProgInfo\Port$ = Mid(ProgInfo\Remote$, Pos + 1)
                ProgInfo\Remote$ = Left(ProgInfo\Remote$, Pos - 1)
              EndIf
              ProgInfo\Filter$ = GetGadgetText(#Main_FilterString)
              ProgInfo\Device$ = GetGadgetText(#Main_InterfaceString)
              
              HideWindow(#Main_Window, #True)
                            
              Parameter$ = "-ssh"
              If Len(ProgInfo\Password$)
                Parameter$ + " -pw " + ProgInfo\Password$
              EndIf
              Parameter$ + " " + ProgInfo\User$ + "@" + ProgInfo\Remote$ + " -P " + ProgInfo\Port$ + " "
              Parameter$ + #DQUOTE$
              Parameter$ + "tcpdump -ni "
              Parameter$ + ProgInfo\Device$
              Parameter$ + " -s 0 -U -w - not port " + ProgInfo\Port$
              If Len(ProgInfo\Filter$)
                Parameter$ + " and " + ProgInfo\Filter$
              EndIf
              Parameter$ + #DQUOTE$
              ;Debug Parameter$
              PLink = RunProgram(ProgInfo\PLink$, Parameter$, "", #PB_Program_Open|#PB_Program_Read|#PB_Program_Write|#PB_Program_Error|#PB_Program_Hide)
              
              If PLink
                StartTime = ElapsedMilliseconds()
                Repeat
                  Error$ = ReadProgramError(PLink)
                  If Len(Error$)
                    Debug "stderr: " + Error$
                  EndIf
                  Delay(10)
                Until Len(Error$) Or (StartTime + 5000) < ElapsedMilliseconds()
                
                If FindString(Error$, "listening on")
                  
                  Wireshark = RunProgram(ProgInfo\Wireshark$, "-k -i -", "", #PB_Program_Open|#PB_Program_Write)
                  If Wireshark
                    *Buffer = AllocateMemory(64*1024)
                    If *Buffer
                      While ProgramRunning(Wireshark)
                        AvailableData = AvailableProgramOutput(PLink)
                        If AvailableData
                          If AvailableData > MemorySize(*Buffer)
                            AvailableData = MemorySize(*Buffer)
                          EndIf
                          ReadProgramData(PLink, *Buffer, AvailableData)
                          WriteProgramData(Wireshark, *Buffer, AvailableData)
                        Else
                          Delay(10)
                        EndIf
                      Wend
                      FreeMemory(*Buffer)
                    EndIf
                    CloseProgram(Wireshark)
                  Else
                    MessageRequester("Error", "Was not able to start Wireshark!")
                  EndIf
                Else
                  
                  If Len(Error$) = 0
                    AvailableData = AvailableProgramOutput(PLink)
                    If AvailableData
                      *Buffer = AllocateMemory(AvailableData)
                      If *Buffer
                        If ReadProgramData(PLink, *Buffer, AvailableData) = AvailableData
                          Error$ = PeekS(*Buffer, AvailableData, #PB_UTF8)
                        EndIf
                        FreeMemory(*Buffer)
                      EndIf
                    EndIf
                  EndIf
                  
                  MessageRequester("Error", Error$)
                EndIf  
                
                KillProgram(PLink)
                CloseProgram(PLink)
                
              Else
                MessageRequester("Error", "Was not able to start PLink!")
              EndIf
              
              HideWindow(#Main_Window, #False)
              
            Default
              If Len(ProgInfo\PLink$) And
                 Len(ProgInfo\Wireshark$) And
                 Len(GetGadgetText(#Main_RemoteString)) And
                 Len(GetGadgetText(#Main_UserString)) And
                 Len(GetGadgetText(#Main_PasswordString)) And
                 Len(GetGadgetText(#Main_InterfaceString))
                DisableGadget(#Main_ExecuteButton, #False)
              Else
                DisableGadget(#Main_ExecuteButton, #True)
              EndIf
              
          EndSelect
          
        Case #PB_Event_CloseWindow
          Exit = #True
      EndSelect
      
    Case #Config_Window
      Select Event
        Case #PB_Event_Gadget
          Select EventGadget()
            Case #Config_PLinkButton
              Help$ = OpenFileRequester("Search PLink", "C:\", "PLink|plink.exe", 0)
              If Len(Help$)
                SetGadgetText(#Config_PLinkString, Help$)
              EndIf
              
            Case #Config_WiresharkButton
              Help$ = OpenFileRequester("Search Wireshark", "C:\", "Wireshark|Wireshark.exe", 0)
              If Len(Help$)
                SetGadgetText(#Config_WiresharkString, Help$)
              EndIf
              
            Case #Config_OkButton
              ProgInfo\PLink$ = GetGadgetText(#Config_PLinkString)
              ProgInfo\Wireshark$ = GetGadgetText(#Config_WiresharkString)
              PostEvent(#PB_Event_CloseWindow, #Config_Window, 0)
              
            Case #Config_CancelButton
              PostEvent(#PB_Event_CloseWindow, #Config_Window, 0)
              
          EndSelect
          
        Case #PB_Event_CloseWindow
          CloseWindow(#Config_Window)
          
      EndSelect
      
  EndSelect
  
Until Exit

If CreatePreferences(ProgInfo\ProgPath$ + ProgInfo\ProgFilename$ + ".ini")
  WritePreferenceString("PLink", ProgInfo\PLink$)
  WritePreferenceString("Wireshark", ProgInfo\Wireshark$)
  WritePreferenceString("LastRemote", ProgInfo\Remote$)
  WritePreferenceString("LastUser", ProgInfo\User$)
  WritePreferenceString("LastInterface", ProgInfo\Device$)
  WritePreferenceString("LastFilter", ProgInfo\Filter$)
  ClosePreferences()
EndIf
Happy sniffing :mrgreen:

Bernd

P.S.: You need first a connection with PuTTY (once) to accept the ssh key of the linux PC
And of course the user needs the rights to execute tcpdump.
Simply test it with 'root'.