net_user.c revision da00d9a5466558ccd9e7b7d04b13d7cb9160c876
11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Licensed under the GPL
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <stddef.h>
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <stdarg.h>
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <unistd.h>
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <stdio.h>
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <errno.h>
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <stdlib.h>
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <string.h>
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <sys/socket.h>
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <sys/wait.h>
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "user.h"
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "user_util.h"
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "kern_util.h"
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "net_user.h"
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "helper.h"
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "os.h"
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint tap_open_common(void *dev, char *gate_addr)
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int tap_addr[4];
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if(gate_addr == NULL) return(0);
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if(sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0],
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		  &tap_addr[1], &tap_addr[2], &tap_addr[3]) != 4){
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printk("Invalid tap IP address - '%s'\n", gate_addr);
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return(-EINVAL);
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return(0);
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
35da00d9a5466558ccd9e7b7d04b13d7cb9160c876Jeff Dikevoid tap_check_ips(char *gate_addr, unsigned char *eth_addr)
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int tap_addr[4];
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if((gate_addr != NULL) &&
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	   (sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0],
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		   &tap_addr[1], &tap_addr[2], &tap_addr[3]) == 4) &&
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	   (eth_addr[0] == tap_addr[0]) &&
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	   (eth_addr[1] == tap_addr[1]) &&
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	   (eth_addr[2] == tap_addr[2]) &&
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	   (eth_addr[3] == tap_addr[3])){
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printk("The tap IP address and the UML eth IP address"
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		       " must be different\n");
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid read_output(int fd, char *output, int len)
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int remain, n, actual;
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char c;
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if(output == NULL){
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		output = &c;
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		len = sizeof(c);
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*output = '\0';
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	n = os_read_file(fd, &remain, sizeof(remain));
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if(n != sizeof(remain)){
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printk("read_output - read of length failed, err = %d\n", -n);
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	while(remain != 0){
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		n = (remain < len) ? remain : len;
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		actual = os_read_file(fd, output, n);
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if(actual != n){
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			printk("read_output - read of data failed, "
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			       "err = %d\n", -actual);
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return;
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		remain -= actual;
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return;
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint net_read(int fd, void *buf, int len)
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int n;
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	n = os_read_file(fd,  buf,  len);
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if(n == -EAGAIN)
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return(0);
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	else if(n == 0)
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return(-ENOTCONN);
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return(n);
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint net_recvfrom(int fd, void *buf, int len)
951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int n;
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	while(((n = recvfrom(fd,  buf,  len, 0, NULL, NULL)) < 0) &&
991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	      (errno == EINTR)) ;
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if(n < 0){
1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if(errno == EAGAIN) return(0);
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return(-errno);
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	else if(n == 0) return(-ENOTCONN);
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return(n);
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint net_write(int fd, void *buf, int len)
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int n;
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	n = os_write_file(fd, buf, len);
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if(n == -EAGAIN)
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return(0);
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	else if(n == 0)
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return(-ENOTCONN);
1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return(n);
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint net_send(int fd, void *buf, int len)
1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int n;
1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	while(((n = send(fd, buf, len, 0)) < 0) && (errno == EINTR)) ;
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if(n < 0){
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if(errno == EAGAIN) return(0);
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return(-errno);
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	else if(n == 0) return(-ENOTCONN);
1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return(n);
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint net_sendto(int fd, void *buf, int len, void *to, int sock_len)
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int n;
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	while(((n = sendto(fd, buf, len, 0, (struct sockaddr *) to,
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   sock_len)) < 0) && (errno == EINTR)) ;
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if(n < 0){
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if(errno == EAGAIN) return(0);
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return(-errno);
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	else if(n == 0) return(-ENOTCONN);
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return(n);
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct change_pre_exec_data {
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int close_me;
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int stdout;
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void change_pre_exec(void *arg)
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct change_pre_exec_data *data = arg;
1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	os_close_file(data->close_me);
1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dup2(data->stdout, 1);
1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int change_tramp(char **argv, char *output, int output_len)
1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int pid, fds[2], err;
1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct change_pre_exec_data pe_data;
1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	err = os_pipe(fds, 1, 0);
1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if(err < 0){
1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printk("change_tramp - pipe failed, err = %d\n", -err);
1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return(err);
1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pe_data.close_me = fds[0];
1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pe_data.stdout = fds[1];
1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pid = run_helper(change_pre_exec, &pe_data, argv, NULL);
1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	read_output(fds[0], output, output_len);
1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	os_close_file(fds[0]);
1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	os_close_file(fds[1]);
1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (pid > 0)
1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		CATCH_EINTR(err = waitpid(pid, NULL, 0));
1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return(pid);
1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void change(char *dev, char *what, unsigned char *addr,
1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		   unsigned char *netmask)
1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char addr_buf[sizeof("255.255.255.255\0")];
1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char netmask_buf[sizeof("255.255.255.255\0")];
1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char version[sizeof("nnnnn\0")];
1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char *argv[] = { "uml_net", version, what, dev, addr_buf,
1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 netmask_buf, NULL };
1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char *output;
1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int output_len, pid;
1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sprintf(version, "%d", UML_NET_VERSION);
1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sprintf(addr_buf, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sprintf(netmask_buf, "%d.%d.%d.%d", netmask[0], netmask[1],
1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		netmask[2], netmask[3]);
2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	output_len = page_size();
2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	output = um_kmalloc(output_len);
2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if(output == NULL)
2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printk("change : failed to allocate output buffer\n");
2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pid = change_tramp(argv, output, output_len);
2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if(pid < 0) return;
2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if(output != NULL){
2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printk("%s", output);
2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		kfree(output);
2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid open_addr(unsigned char *addr, unsigned char *netmask, void *arg)
2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	change(arg, "add", addr, netmask);
2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid close_addr(unsigned char *addr, unsigned char *netmask, void *arg)
2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	change(arg, "del", addr, netmask);
2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldschar *split_if_spec(char *str, ...)
2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char **arg, *end;
2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	va_list ap;
2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	va_start(ap, str);
2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	while((arg = va_arg(ap, char **)) != NULL){
2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if(*str == '\0')
2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return(NULL);
2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		end = strchr(str, ',');
2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if(end != str)
2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			*arg = str;
2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if(end == NULL)
2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return(NULL);
2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		*end++ = '\0';
2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		str = end;
2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	va_end(ap);
2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return(str);
2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Overrides for Emacs so that we follow Linus's tabbing style.
2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Emacs will notice this stuff at the end of the file and automatically
2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * adjust the settings for this buffer only.  This must remain at the end
2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * of the file.
2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ---------------------------------------------------------------------------
2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Local variables:
2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * c-file-style: "linux"
2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * End:
2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
256