我尝试使用AX.25封装创建TUN网络设备。 有效的是: - 创建设备 - 将其封装设置为ax25
无法正常工作的是设置硬件地址。这在ax.25通信中至关重要,因为它用于唯一地寻址节点。
首先我创建了TUN设备:
struct ifreq ifr = { 0 };
const char *clone_dev = "/dev/net/tun";
if ((fd = open(clone_dev, O_RDWR)) == -1)
error_exit(true, "Failed opening %s for tun device %s", clone_dev, dev_name);
ifr.ifr_flags = IFF_TUN;
strncpy(ifr.ifr_name, dev_name, IFNAMSIZ);
if (ioctl(fd, TUNSETIFF, (void *)&ifr) == -1)
error_exit(true, "Failed creating tun device %s", dev_name);
这导致:
root@travelmate:/home/folkert# ifconfig bla
bla Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
POINTOPOINT NOARP MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:500
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
然后我将接口设置为AX.25封装:
if (ioctl(fd, TUNSETLINK, ARPHRD_AX25) == -1)
error_exit(true, "Failed setting tun device %s to ARPHRD_AX25", dev_name);
这导致:
root@travelmate:/home/folkert# ifconfig bla
bla Link encap:AMPR AX.25 HWaddr
POINTOPOINT NOARP MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:500
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
然后是设置硬件地址的问题。 硬件地址是一个字符串,如: FH1GOU-1 首先,您需要将此地址的每个字节向右移一位。然后,ioctl-magic。 这总是失败。我还尝试过只创建一个tun-device,然后在其上调用ifconfig,这会导致一个"不支持"错误。 它当然可能是因为根本不可能在tun设备上设置ax.25硬件地址,但为什么可以设置ax.25封装?
struct sockaddr *sa = &ifr.ifr_ifru.ifru_addr;
struct sockaddr_ax25 *sap25 = (struct sockaddr_ax25 *)sa;
memset(sap25, 0x00, sizeof(struct sockaddr_ax25));
// tried AF_AX25 as well
sa->sa_family = ARPHRD_AX25;
char *min = strchr(hwaddr, '-');
*min = 0x00;
unsigned int hwaddr_len = strlen(hwaddr);
char *call_str = sap25->sax25_call.ax25_call;
unsigned int main_addr_size = sizeof(ax25_address) - 1;
for(unsigned int idx=0; idx<main_addr_size; idx++)
{
int c = idx < hwaddr_len ? toupper(hwaddr[idx]) : ' ';
call_str[idx] = (c << 1) & 0xfe;
}
if (min)
call_str[main_addr_size] = (atoi(min + 1) << 1) & 0xfe;
else
call_str[main_addr_size] = 0x00;
free(hwaddr);
printf("%d\n", ioctl(fd, SIOCSIFHWADDR, &ifr));
最后一行,即ioctl,始终打印-1(=错误)。
我还尝试使用TUNSETIFF ioctl直接设置hw-address,但这似乎被忽略了。
有什么想法吗?
答案 0 :(得分:1)
我认为问题出在&#34; ifr.ifr_flags = IFF_TUN&#34; 如果您计划使用ifr.ifr_flags = IFF_TAP |来创建TAP设备IFF_NO_PI;
不确定这是否对您有帮助。
答案 1 :(得分:1)
从那时起我就听说过tun设备根本就不支持ax25。
答案 2 :(得分:1)
btw我试过的其他东西:只需打开一个以太网封装的分接设备并将其启动,强制bpq将其视为以太网端口,为其提供bpq ax.25&#39;辅助接口&#39;不起作用。 bpq别名接口上的数据包永远不会进入tap设备的文件描述符。
但只是更改点击设备上的封装似乎工作正常。
ax.25处理更大的设置&#39;无论如何,在linux中都被打破了。进程无法连接到不同呼号上同一台机器内的其他进程,当有三脚架免费站点的人员死亡时,一半文档丢失或进入hudini等等。所以确实最好只是&#39;在用户空间中解决这个问题&#39;目前。我们稍后会修复内核堆栈:P整个事情似乎是由同一桌面上只有1个tranceiver和1个终端程序的人做出的:P
答案 3 :(得分:0)
只需使用点击设备(如果你不想要它就剥离数据包的最终硬件层)并且它工作正常。 (编辑:使它 - 随机 - 工作正常,只设置呼号位,然后由于上一个答案中描述的一些错误,甚至停止工作;)
root@user-X551MA:/home/user# ifconfig cb3rob0
cb3rob0 Link encap:AMPR AX.25 HWaddr CB3ROB
无论是为tun工作而不是点击
请注意,TAP设备本身作为文件句柄打开。 (open()
)
为了设置硬件地址(=callsign
),您需要创建一个临时的NETWORK SOCKET HANDLE(socket()
)
你还需要一个套接字句柄调出接口(IFF_UP | IFF_RUNNING)禁用广播和arp并将mtu设置为更多'AX.25ish',例如256而不是1500默认值。
打开一个包含任何所谓支持的协议族的套接字(PF_PACKET工作正常,至少对于root并在ifoc名称字段设置为已创建的tap(tun?)设备名称的情况下执行ioctls
之后再次关闭套接字。除了配置之外,在点击设备上操作时不需要它。
答案 4 :(得分:0)
现在似乎不可能让这个工作起来。 虽然tun / tap属于'通用',但它似乎有2个错误:(对于TAP。使用TUN,完全不可能设置硬件地址,因为没有)。
1:在硬件地址结构中似乎有一些随机覆盖ssid的东西(以太网mac是6个字节,AX.25地址是7个字节(6个呼号,1个ssid +标志)尽管看起来工作正常但它现在不断将SSID设置为8;)
2:即使忽略第一个bug,read()也不会在将封装设置为AMPR AX.25并使用axcall或linpac发送一些数据后返回任何数据 (由于第一个bug,axcall'随机'抱怨无法将端口链接到某些/ etc / ax25 / axports条目。)
就我们而言, / etc / ax25 / axports已经过时了,但是其他程序仍在使用它,而不是扫描所有接口,可能是因为过去没有获得ipv4的接口接口列表的问题,并期待它匹配callign + ssid,它随机找不到......下面的代码 - 应该根据tun / tap声称的'通用'以及它确实在BPQ和KISS接口上正确设置呼号这一事实,而不是TAP接口上的最后一个字节。
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<sys/ioctl.h>
#include<sys/socket.h>
#include<linux/if_tun.h>
#include<net/if_arp.h>
#include<net/if.h>
#include<string.h>
#include<unistd.h>
#define AXALEN 7
int ax25tapcreate(char *tempdev,void *tempcall,int tempflags){
struct ifreq tempifr;
int tempfile;
int tempsock;
char *tempclonedev="/dev/net/tun";
if((tempfile=open(tempclonedev,O_RDWR|O_SYNC))<0)return(-1);
bzero(&tempifr,sizeof(tempifr));
tempifr.ifr_flags=tempflags;
if(*tempdev)strncpy(tempifr.ifr_name,tempdev,IFNAMSIZ-1);
if(ioctl(tempfile,TUNSETIFF,&tempifr)<0){close(tempfile);return(-1);};
if(ioctl(tempfile,TUNSETLINK,ARPHRD_AX25)==-1){close(tempfile);return(-1);};
if(ioctl(tempfile,TUNSETPERSIST,0)<0){close(tempfile);return(-1);};
tempsock=socket(PF_PACKET,SOCK_DGRAM,0);
bzero(&tempifr,sizeof(tempifr));
strncpy(tempifr.ifr_name,tempdev,IFNAMSIZ-1);
bcopy(tempcall,&tempifr.ifr_hwaddr.sa_data,AXALEN);
tempifr.ifr_hwaddr.sa_family=ARPHRD_AX25;
if(ioctl(tempsock,SIOCSIFHWADDR,&tempifr)!=0){close(tempsock)close(tempfile);return(-1);};
bzero(&tempifr,sizeof(tempifr));
strncpy(tempifr.ifr_name,tempdev,IFNAMSIZ-1);
tempifr.ifr_mtu=256;
if(ioctl(tempsock,SIOCSIFMTU,&tempifr<0){close(tempsock);close(tempfile);return(-1);};
bzero(&tempifr,sizeof(tempifr));
strncpy(tempifr.ifr_name,tempdev,IFNAMSIZ-1);
tempifr.ifr_flags=IFF_UP|IFF_RUNNING;
if(ioctl(tempsock,SIOCSIFFLAGS,&tempifr<0){close(tempsock);close(tempfile);return(-1);};
close(tempsock);
return(tempfile);
};
//###EXAMPLECODE
#include<stdio.h>
#include<stdlib.h>
#include<stdint.h>
int main(){
int fd;
int n;
int size;
uint8_t call[AXALEN];
call[0]=('C'<<1)&0xFE;
call[1]=('B'<<1)&0xFE;
call[2]=('3'<<1)&0xFE;
call[3]=('R'<<1)&0xFE;
call[4]=('O'<<1)&0xFE;
call[5]=('B'<<1)&0xFE;
call[6]=(4<<1)&0xFE;
fd=ax25tapcreate("cb3rob0",&call,IFF_TAP);
if(fd>0){printf("SUCCEEDED: %d\n",fd);system("ifconfig cb3rob0");};
if(fd<0)exit(1);
unsigned char buffer[10];
while(1){
size=read(fd,&buffer,sizeof(buffer));
if(size>1)for(n=0;n<size;n++)printf("%02X ",buffer[n]);printf("\n---\n");
if(size<0)exit(1);
};//while1
};
但是...无论如何都不会起作用......现在......
root@user-TW100-E5:/home/user# ./tapcreate
SUCCEEDED: 3
cb3rob0 Link encap:AMPR AX.25 HWaddr CB3ROB-8
UP BROADCAST RUNNING MTU:256 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
注意callign中未保留的-8 SSID。 显然TAP不是用于其他框架而不是以太网。
还注意到TUN / TAP中的实际但不太严重的错误#3 ... IFF_BROADCAST标志在ifconfig中可见...在AX.25接口上无法将其关闭...所有的事情;)(现在为什么AX.25界面甚至有可能将某些内容改为ipv4-ish作为'广播';)