📄 sys-ecos.c
字号:
ret = 0;
}
}
return ret;
}
#endif
//==========================================================================
/*
* sifvjcomp - config tcp header compression
*/
int
sifvjcomp(u, vjcomp, cidcomp, maxcid)
int u, vjcomp, cidcomp, maxcid;
{
u_int x;
int err;
if ((err = cyg_ppp_ppptioctl(&ppp_tty, PPPIOCGFLAGS, (caddr_t) &x, 0)) != 0) {
syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %d",err);
return 0;
}
x = vjcomp ? x | SC_COMP_TCP: x &~ SC_COMP_TCP;
x = cidcomp? x & ~SC_NO_TCP_CCID: x | SC_NO_TCP_CCID;
if ((err = cyg_ppp_ppptioctl(&ppp_tty, PPPIOCSFLAGS, (caddr_t) &x, 0)) != 0) {
syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %d",err);
return 0;
}
if (vjcomp && ((err=cyg_ppp_ppptioctl(&ppp_tty, PPPIOCSMAXCID, (caddr_t) &maxcid, 0)) != 0)) {
syslog(LOG_ERR, "ioctl(PPPIOCSMAXCID): %d",err);
return 0;
}
return 1;
}
//==========================================================================
/*
* sifup - Config the interface up and enable IP packets to pass.
*/
int
sifup(u)
int u;
{
struct ifreq ifr;
//db_printf("%s called\n", __PRETTY_FUNCTION__);
strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
if (ioctl(sockfd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
syslog(LOG_ERR, "ioctl (SIOCGIFFLAGS): %m");
return 0;
}
ifr.ifr_flags |= IFF_UP;
if (ioctl(sockfd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
syslog(LOG_ERR, "ioctl(SIOCSIFFLAGS): %m");
return 0;
}
if_is_up = 1;
return 1;
}
//==========================================================================
/*
* sifnpmode - Set the mode for handling packets for a given NP.
*/
int
sifnpmode(u, proto, mode)
int u;
int proto;
enum NPmode mode;
{
struct npioctl npi;
//db_printf("%s called\n", __PRETTY_FUNCTION__);
npi.protocol = proto;
npi.mode = mode;
{
int err;
if ((err = cyg_ppp_ppptioctl(&ppp_tty, PPPIOCSNPMODE, (caddr_t)&npi, 0)) < 0) {
syslog(LOG_ERR, "ioctl(set NP %d mode to %d): %d", proto, mode,err);
return 0;
}
}
return 1;
}
//==========================================================================
/*
* sifdown - Config the interface down and disable IP.
*/
int
sifdown(u)
int u;
{
struct ifreq ifr;
int rv;
struct npioctl npi;
db_printf("%s called\n", __PRETTY_FUNCTION__);
rv = 1;
npi.protocol = PPP_IP;
npi.mode = NPMODE_ERROR;
{
int err = cyg_ppp_ppptioctl(&ppp_tty, PPPIOCSNPMODE, (caddr_t) &npi, 0);
if( err < 0 )
syslog(LOG_WARNING, "ioctl(PPPIOCSNPMODE): %d",err);
}
strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
if (ioctl(sockfd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
syslog(LOG_ERR, "ioctl (SIOCGIFFLAGS): %m");
rv = 0;
} else {
ifr.ifr_flags &= ~IFF_UP;
if (ioctl(sockfd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
syslog(LOG_ERR, "ioctl(SIOCSIFFLAGS): %m");
rv = 0;
} else
if_is_up = 0;
}
return rv;
return 0;
}
//==========================================================================
/*
* SET_SA_FAMILY - set the sa_family field of a struct sockaddr,
* if it exists.
*/
#define SET_SA_FAMILY(addr, family) \ BZERO((char *) &(addr), sizeof(addr)); \ addr.sa_family = (family); \ addr.sa_len = sizeof(addr);
//==========================================================================
/*
* sifaddr - Config the interface IP addresses and netmask.
*/
int
sifaddr(u, o, h, m)
int u;
u_int32_t o, h, m;
{
struct ifaliasreq ifra;
struct ifreq ifr;
//db_printf("%s called\n", __PRETTY_FUNCTION__);
strncpy(ifra.ifra_name, ifname, sizeof(ifra.ifra_name));
SET_SA_FAMILY(ifra.ifra_addr, AF_INET);
((struct sockaddr_in *) &ifra.ifra_addr)->sin_addr.s_addr = o;
SET_SA_FAMILY(ifra.ifra_broadaddr, AF_INET);
((struct sockaddr_in *) &ifra.ifra_broadaddr)->sin_addr.s_addr = h;
if (m != 0) {
SET_SA_FAMILY(ifra.ifra_mask, AF_INET);
((struct sockaddr_in *) &ifra.ifra_mask)->sin_addr.s_addr = m;
} else
BZERO(&ifra.ifra_mask, sizeof(ifra.ifra_mask));
BZERO(&ifr, sizeof(ifr));
strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
if (ioctl(sockfd, SIOCDIFADDR, (caddr_t) &ifr) < 0) {
if (errno != EADDRNOTAVAIL)
syslog(LOG_WARNING, "Couldn't remove interface address: %d",errno);
}
if (ioctl(sockfd, SIOCAIFADDR, (caddr_t) &ifra) < 0) {
if (errno != EEXIST) {
syslog(LOG_ERR, "Couldn't set interface address: %d",errno);
return 0;
}
syslog(LOG_WARNING,
"Couldn't set interface address: Address %s already exists",
ip_ntoa(o));
}
ifaddrs[0] = o;
ifaddrs[1] = h;
return 1;
}
//==========================================================================
/*
* cifaddr - Clear the interface IP addresses, and delete routes
* through the interface if possible.
*/
int
cifaddr(u, o, h)
int u;
u_int32_t o, h;
{
struct ifaliasreq ifra;
db_printf("%s called\n", __PRETTY_FUNCTION__);
ifaddrs[0] = 0;
strncpy(ifra.ifra_name, ifname, sizeof(ifra.ifra_name));
SET_SA_FAMILY(ifra.ifra_addr, AF_INET);
((struct sockaddr_in *) &ifra.ifra_addr)->sin_addr.s_addr = o;
SET_SA_FAMILY(ifra.ifra_broadaddr, AF_INET);
((struct sockaddr_in *) &ifra.ifra_broadaddr)->sin_addr.s_addr = h;
BZERO(&ifra.ifra_mask, sizeof(ifra.ifra_mask));
if (ioctl(sockfd, SIOCDIFADDR, (caddr_t) &ifra) < 0) {
if (errno != EADDRNOTAVAIL)
syslog(LOG_WARNING, "Couldn't delete interface address: %m");
return 0;
}
return 1;
}
//==========================================================================
/*
* sifdefaultroute - assign a default route through the address given.
*/
int
sifdefaultroute(u, l, g)
int u;
u_int32_t l, g;
{
db_printf("%s called\n", __PRETTY_FUNCTION__);
return dodefaultroute(g, 's');
}
//==========================================================================
/*
* cifdefaultroute - delete a default route through the address given.
*/
int
cifdefaultroute(u, l, g)
int u;
u_int32_t l, g;
{
db_printf("%s called\n", __PRETTY_FUNCTION__);
return dodefaultroute(g, 'c');
}
//==========================================================================
/*
* dodefaultroute - talk to a routing socket to add/delete a default route.
*/
static int
dodefaultroute(g, cmd)
u_int32_t g;
int cmd;
{
int routes;
struct {
struct rt_msghdr hdr;
struct sockaddr_in dst;
struct sockaddr_in gway;
struct sockaddr_in mask;
} rtmsg;
db_printf("%s %08x %c\n", __PRETTY_FUNCTION__,g,cmd);
if ((routes = socket(PF_ROUTE, SOCK_RAW, AF_INET)) < 0) {
syslog(LOG_ERR, "Couldn't %s default route: socket: %d",
cmd=='s'? "add": "delete",errno);
return 0;
}
memset(&rtmsg, 0, sizeof(rtmsg));
rtmsg.hdr.rtm_type = cmd == 's'? RTM_ADD: RTM_DELETE;
rtmsg.hdr.rtm_flags = RTF_UP | RTF_GATEWAY | RTF_STATIC;
rtmsg.hdr.rtm_version = RTM_VERSION;
rtmsg.hdr.rtm_seq = ++rtm_seq;
rtmsg.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK;
rtmsg.dst.sin_len = sizeof(rtmsg.dst);
rtmsg.dst.sin_family = AF_INET;
rtmsg.gway.sin_len = sizeof(rtmsg.gway);
rtmsg.gway.sin_family = AF_INET;
rtmsg.gway.sin_addr.s_addr = g;
rtmsg.mask.sin_len = sizeof(rtmsg.dst);
rtmsg.mask.sin_family = AF_INET;
rtmsg.hdr.rtm_msglen = sizeof(rtmsg);
if (write(routes, &rtmsg, sizeof(rtmsg)) < 0) {
syslog(LOG_ERR, "Couldn't %s default route: %d",
cmd=='s'? "add": "delete",errno);
close(routes);
return 0;
}
close(routes);
default_route_gateway = (cmd == 's')? g: 0;
return 1;
}
//==========================================================================
#if RTM_VERSION >= 3
/*
* sifproxyarp - Make a proxy ARP entry for the peer.
*/
static struct {
struct rt_msghdr hdr;
struct sockaddr_inarp dst;
struct sockaddr_dl hwa;
char extra[128];
} arpmsg;
static int arpmsg_valid;
int
sifproxyarp(unit, hisaddr)
int unit;
u_int32_t hisaddr;
{
int routes;
db_printf("%s called\n", __PRETTY_FUNCTION__);
/*
* Get the hardware address of an interface on the same subnet
* as our local address.
*/
memset(&arpmsg, 0, sizeof(arpmsg));
if (!get_ether_addr(hisaddr, &arpmsg.hwa)) {
syslog(LOG_ERR, "Cannot determine ethernet address for proxy ARP");
return 0;
}
if ((routes = socket(PF_ROUTE, SOCK_RAW, AF_INET)) < 0) {
syslog(LOG_ERR, "Couldn't add proxy arp entry: socket: %m");
return 0;
}
arpmsg.hdr.rtm_type = RTM_ADD;
arpmsg.hdr.rtm_flags = RTF_ANNOUNCE | RTF_HOST | RTF_STATIC;
arpmsg.hdr.rtm_version = RTM_VERSION;
arpmsg.hdr.rtm_seq = ++rtm_seq;
arpmsg.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY;
arpmsg.hdr.rtm_inits = RTV_EXPIRE;
arpmsg.dst.sin_len = sizeof(struct sockaddr_inarp);
arpmsg.dst.sin_family = AF_INET;
arpmsg.dst.sin_addr.s_addr = hisaddr;
arpmsg.dst.sin_other = SIN_PROXY;
arpmsg.hdr.rtm_msglen = (char *) &arpmsg.hwa - (char *) &arpmsg
+ arpmsg.hwa.sdl_len;
if (write(routes, &arpmsg, arpmsg.hdr.rtm_msglen) < 0) {
syslog(LOG_ERR, "Couldn't add proxy arp entry: %m");
close(routes);
return 0;
}
close(routes);
arpmsg_valid = 1;
proxy_arp_addr = hisaddr;
return 1;
}
/*
* cifproxyarp - Delete the proxy ARP entry for the peer.
*/
int
cifproxyarp(unit, hisaddr)
int unit;
u_int32_t hisaddr;
{
int routes;
db_printf("%s called\n", __PRETTY_FUNCTION__);
if (!arpmsg_valid)
return 0;
arpmsg_valid = 0;
arpmsg.hdr.rtm_type = RTM_DELETE;
arpmsg.hdr.rtm_seq = ++rtm_seq;
if ((routes = socket(PF_ROUTE, SOCK_RAW, AF_INET)) < 0) {
syslog(LOG_ERR, "Couldn't delete proxy arp entry: socket: %m");
return 0;
}
if (write(routes, &arpmsg, arpmsg.hdr.rtm_msglen) < 0) {
syslog(LOG_ERR, "Couldn't delete proxy arp entry: %m");
close(routes);
return 0;
}
close(routes);
proxy_arp_addr = 0;
return 1;
}
//==========================================================================
#else /* RTM_VERSION */
/*
* sifproxyarp - Make a proxy ARP entry for the peer.
*/
int
sifproxyarp(unit, hisaddr)
int unit;
u_int32_t hisaddr;
{
struct arpreq arpreq;
struct {
struct sockaddr_dl sdl;
char space[128];
} dls;
db_printf("%s called\n", __PRETTY_FUNCTION__);
BZERO(&arpreq, sizeof(arpreq));
/*
* Get the hardware address of an interface on the same subnet
* as our local address.
*/
if (!get_ether_addr(hisaddr, &dls.sdl)) {
syslog(LOG_ERR, "Cannot determine ethernet address for proxy ARP");
return 0;
}
arpreq.arp_ha.sa_len = sizeof(struct sockaddr);
arpreq.arp_ha.sa_family = AF_UNSPEC;
BCOPY(LLADDR(&dls.sdl), arpreq.arp_ha.sa_data, dls.sdl.sdl_alen);
SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr;
arpreq.arp_flags = ATF_PERM | ATF_PUBL;
if (ioctl(sockfd, SIOCSARP, (caddr_t)&arpreq) < 0) {
syslog(LOG_ERR, "Couldn't add proxy arp entry: %m");
return 0;
}
proxy_arp_addr = hisaddr;
return 1;
}
/*
* cifproxyarp - Delete the proxy ARP entry for the peer.
*/
int
cifproxyarp(unit, hisaddr)
int unit;
u_int32_t hisaddr;
{
struct arpreq arpreq;
db_printf("%s called\n", __PRETTY_FUNCTION__);
BZERO(&arpreq, sizeof(arpreq));
SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr;
if (ioctl(sockfd, SIOCDARP, (caddr_t)&arpreq) < 0) {
syslog(LOG_WARNING, "Couldn't delete proxy arp entry: %m");
return 0;
}
proxy_arp_addr = 0;
return 1;
}
#endif /* RTM_VERSION */
//==========================================================================
/*
* get_ether_addr - get the hardware address of an interface on the
* the same subnet as ipaddr.
*/
#define MAX_IFS 32
static int
get_ether_addr(ipaddr, hwaddr)
u_int32_t ipaddr;
struct sockaddr_dl *hwaddr;
{
struct ifreq *ifr, *ifend, *ifp;
u_int32_t ina, mask;
struct sockaddr_dl *dla;
struct ifreq ifreq;
struct ifconf ifc;
struct ifreq ifs[MAX_IFS];
db_printf("%s called\n", __PRETTY_FUNCTION__);
ifc.ifc_len = sizeof(ifs);
ifc.ifc_req = ifs;
if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) {
syslog(LOG_ERR, "ioctl(SIOCGIFCONF): %m");
return 0;
}
/*
* Scan through looking for an interface with an Internet
* address on the same subnet as `ipaddr'.
*/
ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -