⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ifconfig.c

📁 MIPS处理器的bootloader,龙芯就是用的修改过的PMON2
💻 C
字号:
/* $Id: ifconfig.c,v 1.7 2002/08/09 21:20:28 pefo Exp $ *//* * Copyright (c) 2001-2002 Opsycon AB  (www.opsycon.se / www.opsycon.com) *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by Opsycon AB, Sweden. * 4. The name of the author may not be used to endorse or promote products *    derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */#ifdef _KERNEL#undef _KERNEL#include <sys/param.h>#include <sys/socket.h>#include <sys/errno.h>#include <net/if.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>#include <sys/protosw.h>#include <sys/ioctl.h>#define _KERNEL#else#include <sys/socket.h>#include <sys/ioctl.h>#include <netinet/in.h>#endif#include <net/route.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <pmon.h>#include "bootparams.h"#include "bootp.h"#define SIN(x) ((struct sockaddr_in *)&(x))#define SAD(x) ((struct sockaddr *)&(x))static void boot_getenv (struct bootparams *bootp, char *ifname);static void boot_parsecfg (struct bootparams *bootp, char *cfg);static void boot_setenv (struct bootparams *bootp, char *ifname, int level);int ifconfig __P((char *, char *));static voidsetsin (struct sockaddr_in *sa, int family, u_long addr){    bzero (sa, sizeof (*sa));    sa->sin_len = sizeof (*sa);    sa->sin_family = family;    sa->sin_addr.s_addr = addr;}/* *  Configure an interface. 'ifname' is the interface to configure. *  'ipaddr' is a colon spearated string with parameters. Thus: *  <ipaddr>[:<netmask>[:<broadcast>[:<gateway>]]] | bootp */intifconfig (ifname, ipaddr)	char *ifname;	char *ipaddr;{	struct sockaddr local, loop;	struct sockaddr zmask;	struct bootparams bootp;	struct ifaliasreq addreq;	char *gw;	int s, bootplev;	if (ifname == NULL) {		printf("ifconfig: no ifc name\n");		return (0);	}	bzero (&bootp, sizeof (bootp));	bootp.need = BOOT_ADDR;	s = socket (AF_INET, SOCK_DGRAM, 0);	if (s < 0) {		perror("ifconfig: socket");		return(0);	}	/*	 * Get the parameters for the ethernet interface 	 */	bootplev = matchenv ("bootp");	if (strncmp(ipaddr, "bootp", 5) == 0) {		bootplev = 2;	} else {		boot_parsecfg(&bootp, ipaddr);	}	if (bootplev <= 1 && ipaddr != NULL) {		if (inet_aton (ipaddr, &bootp.addr)) {			bootp.have |= BOOT_ADDR;		}		boot_getenv (&bootp, ifname);	/* Get any others from env */	}	if (bootplev >= 1) {		/* Enable interface with an initial dummy net address.		   Note ipintr() has been kludged to route all input packets		   to an interface on the loopback net. */		bzero (&addreq, sizeof(addreq));		strncpy(addreq.ifra_name, ifname, IFNAMSIZ);		setsin (SIN(addreq.ifra_addr), AF_INET, htonl (0x7f000002));		setsin (SIN(addreq.ifra_broadaddr), AF_INET, INADDR_ANY);		if (ioctl(s, SIOCAIFADDR, &addreq) < 0) {			perror("ioctl (SIOCAIFADDR) dummy");			close (s);			return(0);		}		/* get network parameters from network */		boot_bootp (&bootp, ifname);		/* delete dummy address */		(void) ioctl(s, SIOCDIFADDR, &addreq);		/* get any remaining unknown parameters from environment */		boot_getenv (&bootp, ifname);	}	if (!(bootp.have & BOOT_ADDR)) {		if (bootplev >= 1)			fprintf(stderr, "\nERROR: bootp setup of %s failed\n", ifname);		else			fprintf(stderr, "\nNOTICE: set $ifconfig to enable network\n");		close (s);		return (0);	}	/* save parameters in volatile or non-volatile environment */	boot_setenv (&bootp, ifname, bootplev);	/* got everyting we can, put them into the ifaddreq structure */	bzero (&addreq, sizeof(addreq));	strncpy(addreq.ifra_name, ifname, IFNAMSIZ);	setsin (SIN(addreq.ifra_addr), AF_INET, bootp.addr.s_addr);	if (bootp.have & BOOT_MASK) {		setsin (SIN(addreq.ifra_mask), 0, bootp.mask.s_addr);	}	if (bootp.have & BOOT_BROADADDR) {		setsin (SIN(addreq.ifra_broadaddr), AF_INET, bootp.broadaddr.s_addr);	}	/* remember our local address for later */	local = *SAD(addreq.ifra_addr);	/* now set our actual address */	if (ioctl(s, SIOCAIFADDR, &addreq) < 0) {		/* Assume this means no network interface to attach to */		fprintf (stderr, "\nNOTICE: No network interface available\n");		/*perror("ioctl (SIOCAIFADDR)"); */		close (s);		return(0);	}	/*	 * Configure the loopback i/f (lo0).	 */	bzero (&addreq, sizeof(addreq));	strncpy(addreq.ifra_name, "lo0", IFNAMSIZ);	setsin (SIN(addreq.ifra_addr), AF_INET, htonl (0x7f000001));	setsin (SIN(addreq.ifra_mask), 0, htonl (0xff000000));	/* remember loopback address for later */	loop = *SAD(addreq.ifra_addr);	if (ioctl(s, SIOCAIFADDR, &addreq) < 0) {		perror("ioctl (SIOCAIFADDR) loopback");		close (s);		return(0);	}	/*	 * Now setup the routing tables, equivalent to:	 * route add default $gateway 0	 * route add $ipaddr 127.0.0.1 0	 */	/* set a default routing mask */	bzero (&zmask, sizeof(zmask));	if ((bootp.have & BOOT_GATEIP) || (gw = getenv ("gateway"))) {		/* install default route via the gateway */		struct sockaddr dst;		struct sockaddr gate;		setsin (SIN(dst), AF_INET, INADDR_ANY);		if (bootp.have & BOOT_GATEIP) {			setsin (SIN(gate), AF_INET, bootp.gateip.s_addr);		} else {			/* try for a DNS lookup */			struct hostent *hp;			u_long addr = -1;			if ((hp = gethostbyname (gw)) && hp->h_addrtype == AF_INET) {				bcopy (hp->h_addr, (void *)&addr, sizeof(u_long));			}			setsin (SIN(gate), AF_INET, addr);		}		if (SIN(gate)->sin_addr.s_addr != (u_long)-1) {			errno = rtrequest (RTM_ADD, &dst, &gate, &zmask,			       RTF_UP | RTF_GATEWAY, (struct rtentry **)0);			if (errno) {				perror ("route add gateway");			}		} else {			fprintf (stderr, "gateway %s: unknown host\n", gw);		}	}	/*	 * Route packets with local address via loopback i/f.	 */	errno = rtrequest (RTM_ADD, &local, &loop, &zmask, RTF_UP | RTF_HOST,		       (struct rtentry **)0);	if (errno && errno != EEXIST) {		perror ("route add loopback");	}	close (s);	return (1);}static intia_getenv (const char *name, struct in_addr *ia){	char *s;	if ((s = getenv (name)) != 0)		return inet_aton (s, ia);	return 0;}static voidboot_getenv (struct bootparams *bootp, char *ifname){	/* these are the only ones that we have to know in this module */	if (!(bootp->have & BOOT_ADDR) && ia_getenv("ipaddr", &bootp->addr))		bootp->have |= BOOT_ADDR;	if (!(bootp->have & BOOT_MASK) && ia_getenv("netmask", &bootp->mask))		bootp->have |= BOOT_MASK;	if (!(bootp->have & BOOT_BROADADDR) && ia_getenv("broadcast", &bootp->broadaddr))		bootp->have |= BOOT_BROADADDR;	if (!(bootp->have & BOOT_GATEIP) && ia_getenv("gateway", &bootp->gateip))		bootp->have |= BOOT_GATEIP;}static intia_getcfg (char *cfg, char **ncfg, struct in_addr *ia){	char *s;	s = strchr(cfg, ':');	if (s == NULL)		s = cfg + strlen(cfg);	else		*s++ = '\0';	*ncfg = s;	if ((s - cfg) <= 1)		return(0);	return(inet_aton(cfg, ia));}static voidboot_parsecfg (struct bootparams *bootp, char *cfg){	char *ncfg;	if (ia_getcfg(cfg, &ncfg, &bootp->addr))		bootp->have |= BOOT_ADDR;	cfg = ncfg;	if (ia_getcfg (cfg, &ncfg, &bootp->mask))		bootp->have |= BOOT_MASK;	cfg = ncfg;	if (ia_getcfg(cfg, &ncfg, &bootp->broadaddr))		bootp->have |= BOOT_BROADADDR;	cfg = ncfg;	if (ia_getcfg (cfg, &ncfg, &bootp->gateip))		bootp->have |= BOOT_GATEIP;}static void__setenv (char *name, char *val, int level){	if (level <= 1 && getenv(name))		return;	if (level >= 3)		/* write to non-volatile environment */		do_setenv (name, val, 0);	else		/* write to local environment only */		do_setenv (name, val, 1);}static voidia_setenv (char *name, char *ifname, struct in_addr addr, int level){	char sn[30];	char *s = inet_ntoa (addr);	if (ifname)		sprintf(sn, "%s.%s", ifname, name);	else		sprintf(sn, "%s", name);	__setenv (sn, s, level);}static voidboot_setenv (struct bootparams *bootp, char *ifname, int level){	if (bootp->have & BOOT_ADDR)		ia_setenv ("ipaddr", ifname, bootp->addr, level);	if (bootp->have & BOOT_MASK)		ia_setenv ("netmask", ifname, bootp->mask, level);	if (bootp->have & BOOT_BROADADDR)		ia_setenv ("broadcast", ifname, bootp->broadaddr, level);	if (bootp->have & BOOT_GATEIP)		ia_setenv ("gateway", ifname, bootp->gateip, level);	if (bootp->have & BOOT_DNSIP)		ia_setenv ("nameserver", NULL, bootp->dnsip, level);	if (bootp->have & BOOT_BOOTIP)		ia_setenv ("bootaddr", NULL, bootp->bootip, level);	if (bootp->have & BOOT_HOSTNAME)		__setenv ("hostname", bootp->hostname, level);	if (bootp->have & BOOT_DOMAINNAME)		__setenv ("localdomain", bootp->domainname, level);	if (bootp->have & BOOT_BOOTFILE)		__setenv ("bootfile", bootp->bootfile, level);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -