openwrt中设置mac地址

在对物联网产品开发测试的过程中,需要对无线射频芯片配置mac地址, 

以高通 ATHEROS  AR93XX为例, 硬件mac地址存放于uboot的一个固定地址中.

在openwrt中可以开发setmac程序来配置.

/**
* create by iversondeng168
*/
#include <sys/time.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <errno.h>
#include <syslog.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <fcntl.h>

#include <memory.h>
#include <signal.h>


#define  UI8      unsigned char
#define  I8       char
#define  U32      unsigned int 
#define  I32      int


#define UBOOT_MACADDR    (0x1fc00)



I32 hex_char_to_int(I8 in)
{
    if(in >= '0' && in <= '9')
        return in - '0';

    if(in >= 'a' && in <= 'f')
        return (in - 'a') + 10;

    if(in >= 'A' && in <= 'F')
        return (in - 'A') + 10;

    return 0;
}





I8* cmd_system(const I8* command)
{    
     I8* result = "";    
     FILE *fpRead;    
	 fpRead = popen(command, "r");    
	 I8 buf[1024];    
	 memset(buf,'\0',sizeof(buf));    
	 while(fgets(buf,1024-1,fpRead)!=NULL)
	 {        
	    result = buf;    
	 }
	 
	 if(fpRead!=NULL)        
	 	pclose(fpRead);  
	 
	 return result;
}




void set_wifissid(UI8*suffix)
{
	I8*retpt;
    I8 cmds[128]={0};

    //wifi ap模式才需要设置ssid
    retpt = cmd_system("uci get wireless.@wifi-iface[0].mode");
	if(strncmp("ap",retpt,2)) return;

    sprintf(cmds,"uci set wireless.@wifi-iface[0].ssid=OpenWrt-%02X%02X%02X",suffix[0],suffix[1],suffix[2]);
    cmd_system(cmds);

    cmd_system("uci commit wireless");;
}





void set_macaddr(UI8*data,I32 datalen)
{
   if(datalen != 6) return;
   
   UI8 macaddr[6];
   memset(macaddr,0,6);
   memcpy(macaddr,data,6);
   
   //macaddr 第一个字节的第二位必须是偶数(0、2、4、6、8、A、C、E)
   //经过测试mac不能全为0
   if(macaddr[0] % 2 != 0) return;

   if(macaddr[0] == 0 && macaddr[1] == 0 && macaddr[2] == 0 &&
   	  macaddr[3] == 0 && macaddr[4] == 0 && macaddr[5] == 0)
   	  return;

   
   //拷贝一份uboot
   cmd_system("dd if=/dev/mtd0 of=/tmp/new_uboot.bin");
   sleep(1);
   
   I8*newubootpath = "/tmp/new_uboot.bin";
   //检测副本存在并且可读可写
   while(access(newubootpath,F_OK | R_OK | W_OK) == -1);

   //将mac地址写入副本固件中
   I32 new_fd = open(newubootpath,O_RDWR);
   if(new_fd < 0) return;

   //0x1fc00即为mac起始地址
   lseek(new_fd,UBOOT_MACADDR,SEEK_SET);

   write(new_fd,macaddr,6);

   close(new_fd);

   //附带设置wifi名称
   set_wifissid(&macaddr[3]);

   sleep(1);
   //将副本写入分区会自动重启,openwrt重启后会自动清理掉/tmp下的文件
   cmd_system("mtd -r write /tmp/new_uboot.bin u-boot");
   
}





//setmac auto / setmac AUTO
//setmac 001234567890
I32  main(I32 argc,I8*argv[])
{
	UI8 i;
	UI8 j;
	UI8 macaddr[6];
	memset(macaddr,0,sizeof(macaddr));

	srand(time(NULL));

	if(argc != 2){
		printf("argc != 2\n");
		return -1;
	}


	if(!strcmp("auto",argv[1]) ||
		!strcmp("AUTO",argv[1]))
	{
       sleep(1);

       macaddr[0] = 0x00;
       for(i=1;i < sizeof(macaddr);i++)
	   {
          macaddr[i] = rand() & 0xFF;
	   }
	}
	else{

       if(strlen(argv[1]) != 12)
	   {
           printf("macadddr format error!\n");
		   return -1;
	   }

	   for(i=0,j=0;i < sizeof(macaddr);i++,j+=2)
	   {
           macaddr[i] = hex_char_to_int(argv[1][j]) * 16 + hex_char_to_int(argv[1][j + 1]);
           if(macaddr[0] % 2 != 0){
			   printf("the macaddr head must be even number\n");
			   return -1;
		   }
	   }
	}


    printf("set macaddr=%02X:%02X:%02X:%02X:%02X:%02X\n",macaddr[0],macaddr[1],macaddr[2],macaddr[3],macaddr[4],macaddr[5]);

    set_macaddr(macaddr,sizeof(macaddr));

	return 0;
}

执行交叉编译

GCC=/home/openwrt-master/staging_dir/toolchain-mips_74kc_gcc-5.3.0_musl-1.1.16/bin/mips-openwrt-linux-gcc
$GCC setmac.c -o setmac -O2 -w

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值