модуль lapbether
От: Pavel515  
Дата: 06.03.19 15:00
Оценка:
Здравствуйте


Есть такая штука

/*
* "LAPB via ethernet" driver release 001
*
* This code REQUIRES 2.1.15 or higher/ NET3.038
*
* This module:
* This module is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* This is a "pseudo" network driver to allow LAPB over Ethernet.
*
* This driver can use any ethernet destination address, and can be
* limited to accept frames from one dedicated ethernet card only.


Скажите, пожалуйста, как её использовать?
Делаю
insmod lapb
insmod lapbether
insmod x25
ifconfig lapb0 up
x25route add 33 lapb0

x25client 44 33 (<- программа создает x25 сокет и пытается установить соединение на X25 адрес 33. Маршрутизатор направляет пакет на устройство lapb0. Tcpdump показывает пакет 01 — запрос соединения)

с какими параметрами создавать socket
У меня получилость ТОЛЬКО принять этот байт программой (это просто sniffer. Ну уж если Tcpdump ловит...) (далее)
при попытке отправить — ошибка (понятно, что sniffer работает только по приему...)

# ./lapb3
len = 1
(01)
write error: 22(Invalid argument)

int main(int argc,char** argv)
{
    int fd,rc,nr,i;
    unsigned char packet[40];

    if((fd = socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ALL))) == -1){
    printf("Socket error (%d)(%s)\n",errno,strerror(errno));
    return -1;
    }

    struct sockaddr_ll sll;
    struct ifreq ifr;

    memset( &sll, 0, sizeof( sll));
    memset( &ifr, 0, sizeof( ifr));

    strcpy( ifr.ifr_name, "lapb0");

    if(( ioctl( fd, SIOCGIFINDEX, &ifr))==-1)
    {
    printf( "error\n");
        return(-1);
    }
    sll.sll_family = AF_PACKET;
    sll.sll_ifindex = ifr.ifr_ifindex;
    sll.sll_protocol = htons(ETH_P_ALL);
      
    rc =  bind( fd, (struct sockaddr*)&sll, sizeof( sll));


    if(rc == -1){
    printf("Bind socket error (%d)(%s)\n",errno,strerror(errno));
    return -1;
    }

        
    nr = read(fd,packet,40);
    if(nr < 0){
        printf("Read socket error (%d)(%s)\n",errno,strerror(errno));
    return -1;
    }
    printf("len = %d\n",nr);
    for(i=0;i<nr;i++)printf("(%02X)",packet[i]);
    printf("\n");

    nr = write(fd,packet,1);
    if(nr != 1){
    printf("write error: %d(%s)\n",errno,strerror(errno));
    }

    close(fd);

    return 0;
}


пробовал добавлять ip адрес и работать через AF_INET — вообще ничего не принимает
таким образом какой-то караул
Вопросы

socket(????? family, ???????? typ, ??????? protocol <- ну тут исходя из исходников lapcether.c вроде как ETH_P_DEC (?)
с bind-ом понятнее (пристыковываем к устройству)

Если кто встречался — помогите, пожалуйста.

С уважением, Павел
Если хочешь выиграть в лотерею, то купи, хотя-бы лотерейный билет. (В.Мэгре)
Re: модуль lapbether
От: reversecode google
Дата: 06.03.19 17:01
Оценка:
Почему в исходник модуля не смотрите ?
https://github.com/spotify/linux/blob/master/drivers/net/wan/lapbether.c#L413
Только прием данных


Что то я написал и засомневался, но уточнять лень
Покопайте ядро
Отредактировано 06.03.2019 20:10 reversecode . Предыдущая версия .
Re[2]: модуль lapbether
От: Pavel515  
Дата: 07.03.19 05:34
Оценка:
Здравствуйте, reversecode, Вы писали:


R>Почему в исходник модуля не смотрите ?

R>https://github.com/spotify/linux/blob/master/drivers/net/wan/lapbether.c#L413
R>Только прием данных


R>Что то я написал и засомневался, но уточнять лень

R>Покопайте ядро

Шутка( если все, что перекопал в ядре обратить в земельные дела — получится пруд сотки в три и глубиной метров 5-7)

функция lapbeth_rcv действительно только принимает. Об этом говорят строки

dev->stats.rx_packets++;

dev->stats.rx_bytes += len;

но есть и функция

lapbeth_data_transmit, в которой мы видим как раз наоборот

ndev->stats.tx_packets++

ndev->stats.tx_bytes += size;

обмен двухсторонний

Наверное мой вопрос относится к категории загадки Полишинеля, т.е. настолько простой, что все про это знают и, поэтому, не говорят

в заголовке говорится, что это pseudo network driver

как с ним работать из программы? какой socket создавать? socket(PF_PSEUDO ???? , SOCK_PSEUDU ???

может что-то еще надо сделать в командной строке, кроме ifconfig up ....
может открывать его просто как файл /dev/lapb0 или ???

С уважением, Павел
Если хочешь выиграть в лотерею, то купи, хотя-бы лотерейный билет. (В.Мэгре)
Re[2]: модуль lapbether
От: Pavel515  
Дата: 07.03.19 07:12
Оценка:
Здравствуйте, reversecode, Вы писали:


R>Почему в исходник модуля не смотрите ?

R>https://github.com/spotify/linux/blob/master/drivers/net/wan/lapbether.c#L413
R>Только прием данных


R>Что то я написал и засомневался, но уточнять лень

R>Покопайте ядро

Спасибо. С ошибкой write error разобрался благодаря Вам

в функции lapbeth_rcv прямое указание какие пакеты посылать:

len = skb->data[0] + skb->data[1] * 256;

стал посылать пакеты

0x03,0x00,0x01 — длина 3 ошибка ушла, но такое ощущение, что до этого не доходит, так как RX по нулям !!!!!!

lapb0: flags=193<UP,RUNNING,NOARP> mtu 1031
x25 txqueuelen 1000 (generic X.25)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 138 bytes 276 (276.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

TX пакетов вон сколько пришло, а до RX процесс не дошел!!!
возвращаемся к вопросу как lapb# связывать с ethdev lapbether.c (строки 56...60)
struct lapbethdev {
...
struct net_device *ethdev; /* link to ethernet device */
...
};

С уважением, Павел.
Если хочешь выиграть в лотерею, то купи, хотя-бы лотерейный билет. (В.Мэгре)
Отредактировано 07.03.2019 7:13 Pavel515 . Предыдущая версия .
Re: модуль lapbether
От: Pavel515  
Дата: 13.03.19 11:19
Оценка: 4 (1)
Здравствуйте

Достиг результатов в понимании lapbether
Это такая штука, которая создает пару lapb и eth, причем однозначную, скажем в системе две карты eth0 и eth1. После
modprobe x25
modprobe lapb
modprobe lapbether

получается два устройства lapb, которые однозначно связываются с устройствами Ethernet
lapb0 <-> eth0
lapb1 <-> eth1
В общем случае, если в системе N eternet карт (кроме dummy, loop ...?) то будет N lapb однозначно связанных пар
lapbN <-> ethN

Провел эксперимент
две машины eth1 обоих связал в отдельном valn
ifconfig lapb1 up

на стороне клиента
route add -A x25 44 lapb1
x25client 33 44 <- программа устанавливает соединение с сервером по адресу 44 с использованием x25 socket
socket(PF_X25...
bind -> 33
connect -> 44

на стороне сервера
x25server 44
socket(PF_X25...
bind -> 44
listen
accept

в отдельном vlan, там где eth1, виден трафик (tcpdump) пакеты lapb, x25
устройства lapb общаются друг с другом

./x25server 44
X25: socket created
X25: get socket option qbit = 0
X25: set socket facility OK
X25: socket bind to 44
X25: start listen ...
X25: socket listening
X25: socket accept from 33
X25: from client: Hello server !!! (17)
X25: to client: Hi client !!! (14)
X25: client closed
X25: socket closed

./x25client 33 44
X25: socket created
X25: get socket option qbit = 0
X25: set socket facility OK
X25: socket bind to 33
X25: socket connecting to 44 ...
X25: socket connect to 44
X25: to server: 'Hello server !!!' (17)
X25: from server: Hi client !!! (14)
X25: socket closed


http://files.rsdn.org/45405/x25client.c
http://files.rsdn.org/45405/x25server.c

С уважением, Павел
Если хочешь выиграть в лотерею, то купи, хотя-бы лотерейный билет. (В.Мэгре)
Отредактировано 13.03.2019 11:20 Pavel515 . Предыдущая версия .
Re: модуль lapbether
От: Pavel515  
Дата: 08.04.19 06:33
Оценка:
Здравствуйте

Вот настал момент поделиться результатом
Не сразу и не быстро получилось адаптировать код x25tap для ядра 3.10

Основываясь на результатах https://switch-case.ru/51655676, только автор шел от broadcat к unicast, а я наоборот, изменения в коде x25tap:

(основные моменты)

в функции static void x25tap_rx_skb(struct sk_buff *skb)
при вызове функции kfree_skb(принятого skb) зависает с перегрузкой.
При передаче skb в пространство x25 в принимающей функции (x25_dev.c)
(int x25_lapb_receive_frame(struct sk_buff *skb, struct net_device *dev,
struct packet_type *ptype, struct net_device *orig_dev)

при выполнении skb_copy копия выполняется, но адрес skb и data внутри skb не меняется!!!!!, а размер данных обнуляется, поэтому pskb_may_pull возвращаяе FALSE), возвращаясь к x25tap_rx_skb(struct sk_buff *skb)
создаю новый буфер skb и копирую в него данные из буфера net_link
    if((__skb = dev_alloc_skb(skb->len)) == NULL)
    {
        printk(KERN_INFO "%s : dev_alloc_skb(%d) == NULL\n", dev->name,skb->len);
        return;
    }

    if (skb->data[0] == 0) {
        x25tap->stats.rx_packets++;
        x25tap->stats.rx_bytes += len;
    }

    dptr = skb_put(__skb,skb->len);
    memcpy(dptr,skb->data,skb->len);



Изменения в xotd — две функции
int writenls(struct xot_device* dev, unsigned char *packet, int len);
int readnls(struct xot_device* dev, unsigned char *packet, int len);
с изменением структуры struct xot_device* dev
...
    struct iovec iov;
    struct msghdr msg;
    int nls;        /* The x25tap device it talks to. */ вместо tap (для удобства)
...


добавлением заголовка
struct nl_header {
    struct nlmsghdr nlh;
    u_int16_t length;
};


и изменением буферов в функциях void *outbound(void *arg)
...
    unsigned char nls_packet[sizeof(struct nl_header) + MAX_PKT_LEN + 4];
    unsigned char *full_packet = nls_packet + (sizeof(struct nl_header) - sizeof(struct xot_header)) + 1;
//    unsigned char full_packet[sizeof(struct xot_header) + MAX_PKT_LEN];
    struct xot_header *header = (struct xot_header *)full_packet;
    unsigned char *packet = full_packet + sizeof(*header);
    unsigned char *tap_packet = packet - 1;


и void *inbound(void *arg)
...
    unsigned char nls_packet[sizeof(struct nl_header) + MAX_PKT_LEN + 1 + 4];
    unsigned char *tap_packet = nls_packet + sizeof(struct nl_header);
//    unsigned char tap_packet[MAX_PKT_LEN + 1];
    unsigned char *packet = tap_packet + 1;



паралельно при переходе к 64 битной версии в функции void *outbound(void *arg)
...
unsigned char *packet = full_packet + sizeof(*header);
...
nread += sizeof(*header);

не было * (разыменования) в 32 — битной версии размер указателя равен размеру заголовка, а 64 битной указатель становится размером 8, а заголовок остается 4

Ну вот, кажется и всё!
http://files.rsdn.org/45405/x25tap.c
http://files.rsdn.org/45405/xotd.c

С уважением, Павел
Если хочешь выиграть в лотерею, то купи, хотя-бы лотерейный билет. (В.Мэгре)
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.