2013-09-26 2 views
0

Я хотел бы создать туннель IP. Для этого я создаю сокеты в C# на стороне клиента и привязать его к порту 4999:Получение пакетов из любого протокола в сыром linux-сокете

Socket mysock = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP); 
mysock.Bind(new IPEndPoint(IPAddress.Loopback, 4999)); 
mysock.Connect(new IPEndPoint(IPAddress.Loopback, 4999)); 

Теперь я могу просто позвонить mysock.Receive(byte[]), и я получаю все IP-пакеты, включая заголовок IP. Например, если я пытаюсь открыть TCP-соединение с 127.0.0.1:4999, приложение C# захватывает 3 пакета. Я также могу отправить пакеты через этот сокет, и он будет работать нормально.

Приложение C# затем передает эти пакеты в приложение C++, работающее на Linux-машине. Там я меняю порт отправителя (это легкая часть, просто записывайте его в заголовок TCP), а затем я хотел бы просто отправить его и сделать все для меня, как это работает на C#. И, очевидно, я также хотел бы получать пакеты из сырого linux-сокета, поэтому я могу перенести их обратно в приложение C# и получить сообщение.

Я уже внедрил все, кроме исходного разъема Linux. Это мой вопрос: Как я могу написать выше код C# в C/C++ для Linux? Согласно raw(7), я не получу пакеты TCP или UDP, если я просто сделаю socket(AF_INET, SOCK_RAW, IPPROTO_RAW), правильно?

Редактировать: Кстати, я запускаю код C# на окнах, но это не моя проблема.

+0

Berkeley Sockets будет предпочтительным вариантом для C IMHO http://gnosis.cx/publish/programming/sockets.html, если вы используете C++, библиотеки, такие как Boost, имеют обертки вокруг Беркли, которые ближе к коду C# вы отправили. –

+0

@AllanElder См. Мое редактирование. –

ответ

0

No.

Номер порта не должен быть TCP или UDP номер порта в этом случае.

Должен быть (я не уверен) идентификатор протокола более высокого уровня (например, «номер порта» из 6 означает: TCP-пакеты, а 17 означает: UDP-пакеты). В текущей версии Linux говорится, что номер порта должен быть 0 для сырых сокетов. Для приложения требуются права «root».

Различия в для Windows (по сравнению с Linux):

Документация для Windows говорит, что сырые сокеты разрешены для ICMP и IGMP-пакетов (только).

Использование библиотеки winpcap должно позволить программе получать необработанный доступ к карте Ethernet. Однако в этом случае вы также увидите 14-байтовый заголовок Ethernet (до заголовка IP), и вы получите все виды Ethernet-пакетов (в обычной сети TCP/IP это должны быть ARP, IPv4, IPv6 и STP) и не только пакеты IPv4.

Существует обертка .NET для winpcap, поэтому вы также сможете использовать winpcap с C#.

+0

Вы говорите об идентификаторах протокола. Но я хотел бы иметь возможность передавать IP-пакеты, не заботясь о транспортном уровне. –

+0

@ main--: Я отредактировал свой ответ. –

+0

Спасибо, но ты неправильно понял мой вопрос. Часть Windows работает отлично, мне просто нужна помощь с частью Linux. –

Смежные вопросы