The Pedigree Project  0.1
CdiNet.cc
1 /*
2  * Copyright (c) 2008-2014, Pedigree Developers
3  *
4  * Please see the CONTRIB file in the root of the source tree for a full
5  * list of contributors.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include "CdiNet.h"
21 #include "modules/system/network-stack/NetworkStack.h"
22 #include "pedigree/kernel/Log.h"
23 #include "pedigree/kernel/compiler.h"
24 #include "pedigree/kernel/machine/Device.h"
25 #include "pedigree/kernel/machine/Network.h"
26 #include "pedigree/kernel/network/IpAddress.h"
27 #include "pedigree/kernel/network/MacAddress.h"
28 #include "pedigree/kernel/utilities/utility.h"
29 
30 // Prototypes in the extern "C" block to ensure that they are not mangled
31 extern "C" {
32  void cdi_cpp_net_register(void* void_pdev, struct cdi_net_device* device);
33  void cdi_net_receive(struct cdi_net_device* device, void* buffer, size_t size);
34  struct cdi_net_device* cdi_net_get_device(int num);
35 };
36 
37 CdiNet::CdiNet(Network* pDev, struct cdi_net_device* device) :
38  Network(pDev), m_Device(device)
39 {
40  setSpecificType(String("CDI NIC"));
41 
43  uint64_t mac = m_Device->mac;
44  m_StationInfo.mac.setMac(reinterpret_cast<uint16_t*>(&mac), false);
45 
47 }
48 
49 CdiNet::CdiNet(struct cdi_net_device* device) :
50  Network(), m_Device(device)
51 {
52  setSpecificType(String("CDI NIC"));
53 
55  uint64_t mac = m_Device->mac;
56  m_StationInfo.mac.setMac(reinterpret_cast<uint16_t*>(&mac), false);
57 
59 }
60 
61 CdiNet::~CdiNet()
62 {
63 }
64 
65 bool CdiNet::send(size_t nBytes, uintptr_t buffer)
66 {
67  struct cdi_net_driver *driver = reinterpret_cast<struct cdi_net_driver *>(m_Device->dev.driver);
68  if(driver)
69  {
70  driver->send_packet(m_Device, reinterpret_cast<void*>(buffer), nBytes);
71  return true;
72  }
73  return false;
74 }
75 
77 {
78  return m_StationInfo;
79 }
80 
82 {
83  // free the old DNS servers list, if there is one
84  if (m_StationInfo.dnsServers)
85  delete [] m_StationInfo.dnsServers;
86 
87  // MAC isn't changeable, so set it all manually
88  m_StationInfo.ipv4 = info.ipv4;
89  NOTICE("cdi-net: Setting ipv4, " << info.ipv4.toString() << ", " << m_StationInfo.ipv4.toString() << "...");
90 
91  m_StationInfo.ipv6 = info.ipv6;
92  m_StationInfo.nIpv6Addresses = info.nIpv6Addresses;
93  NOTICE("cdi-net: Assigning " << Dec << info.nIpv6Addresses << Hex << " IPv6 addresses.");
94 
95  m_StationInfo.subnetMask = info.subnetMask;
96  NOTICE("cdi-net: Setting subnet mask, " << info.subnetMask.toString() << ", " << m_StationInfo.subnetMask.toString() << "...");
97  m_StationInfo.gateway = info.gateway;
98  NOTICE("cdi-net: Setting gateway, " << info.gateway.toString() << ", " << m_StationInfo.gateway.toString() << "...");
99 
100  // Callers do not free their dnsServers memory
101  m_StationInfo.dnsServers = info.dnsServers;
102  m_StationInfo.nDnsServers = info.nDnsServers;
103  NOTICE("cdi-net: Setting DNS servers [" << Dec << m_StationInfo.nDnsServers << Hex << " servers being set]...");
104 
105  return true;
106 }
107 
108 EXPORTED_PUBLIC void cdi_cpp_net_register(void* void_pdev, struct cdi_net_device* device)
109 {
110  // Create a new CdiNet node
111  CdiNet *pCdiNet = new CdiNet(device);
112 
113  // Replace pDev with pCdiNet
114  Device::addToRoot(pCdiNet);
115 }
116 
121 EXPORTED_PUBLIC void cdi_net_receive(struct cdi_net_device* device, void* buffer, size_t size)
122 {
123  auto f = [&] (Device *p) {
124  if (p->getType() == Device::Network)
125  {
126  if (p->getSpecificType() == "CDI NIC")
127  {
128  CdiNet *pNet = static_cast<CdiNet *>(p);
129  if (pNet->getCdiDevice() == device)
130  {
131  // Submit the packet.
132  NetworkStack::instance().receive(size, reinterpret_cast<uintptr_t>(buffer), pNet, 0);
133  }
134  }
135  }
136  return p;
137  };
138 
139  auto c = pedigree_std::make_callable(f);
140 
141  Device::foreach(c, 0);
142 }
virtual const StationInfo & getStationInfo()
Definition: CdiNet.cc:76
virtual bool setStationInfo(const StationInfo &info)
Definition: CdiNet.cc:81
A communication device.
Definition: Device.h:59
static void addToRoot(Device *device)
Definition: Device.cc:102
Definition: String.h:49
IpAddress gateway
Automatically calculated?
void receive(size_t nBytes, uintptr_t packet, Network *pCard, uint32_t offset)
Definition: Device.h:43
size_t nDnsServers
Can contain IPv6 addresses.
virtual void setSpecificType(String str)
Definition: Device.h:174
#define NOTICE(text)
Definition: Log.h:74
Definition: CdiNet.h:31
Definition: Log.h:136
virtual bool send(size_t nBytes, uintptr_t buffer)
Definition: CdiNet.cc:65
CdiNet(struct cdi_net_device *device)
Definition: CdiNet.cc:49
static void foreach(Callback callback, Device *root=0)
Definition: Device.cc:94
static NetworkStack & instance()
Definition: NetworkStack.h:47
void registerDevice(Network *pDevice)
Definition: Log.h:138